 All right. Hi everybody. My name is Nidhi Siddhanand and I work as an architect at Wal-Mart Labs Bangalore. I hope you've had great talk so far and you're back from tea. So just want to talk about microfrontend architecture and before I do that I want to set some context. So my team works on the discovery experience in walmart.com, which are the landing pages that customers see when they come to Wal-Mart either directly or via SEO or SEM. Typically these are homepage, search and browse, product page and so on and so forth. This talk microfrontend architecture is basically talking about the fitment widget on the product page as an example. And the goal of this talk is to give you a sense of why and how we adopted this architecture and hopefully you can relate this back to your own use cases or think about it in your future projects. Right. And before I sort of delve into the talk, I just want to give you some context. So walmart.com sells products across multiple categories which include home, fashion, everyday living, things like diapers, shampoos and also auto parts and products that are specifically for the enthusiast and professional. So we have a diverse set of customers who come into Wal-Mart and the way you would serve a customer who is trying to shop for clothes is different from whoever is trying to buy diapers because in the case of diapers and shampoos you know exactly which brand you're going to buy and you're not really looking for a whole lot of other things whereas in fashion and other areas like electronics you want to get more information about the product, what are the alternatives. So the experience kind of changes for these various pages depending on the category. So it's dynamic for a category. So we are a large team. We are distributed between US and India. We're roughly around 70 engineers and at any one point in time we're working on 10 parallel initiatives which include both business and engineering requirements. We are broadly divided into a core and a specialized experience. So the specialized experience is as I just mentioned that fashion product page will look slightly different from something like a core product page and we largely work off the same core base. We share across all these web apps we share around 10 third party libraries and 10 in-house libraries across the board and we do have automation but we're not 100% automation covered so that's the other challenge. Because we are the landing pages we are also very sensitive to performance. Metrics like TTFP first meaningful paint are things that we really care about and our page views are roughly around 5000 page views per minute. And adding experience like the fitment widget on the product page can be upward of 120 files for that experience only and if you count the number of react components, the reducers, the API integration, your configuration files and if you look at unit tests, automation tests, analytics code, all of these things really add up to a lot of code that you're adding and we are roughly around 6000 lines of additional code just for putting a fitment widget on a product page. So we do have a process now you might be thinking large scale web development you must be having the processes and all and this probably looks very similar to what you've got in your current companies is that we do have guidelines on coding conventions how to raise PRs. We have Git pre-commit hooks that run your lint, your unit test as well as sometimes it runs automation as well and we have Slack channels for review where you post your PR and there's a pool of reviewers for a particular day who will pick up your PR and review it. Now the thing about that is that reviewers need not necessarily be working on the same initiative or be from the same team they focus more on the technical aspects and less on the functional aspects. So typically your PR can go up to two to three days for a review depending on which part of the code you're touching and depending on how much context the reviewer has how much bandwidth they have etc. So coming to this we wanted to be more efficient in the way we were developing things and this is not across the board this is I'm going to be talking about a specific example. So in the light of that what is a micro front-end and this is not a textbook definition either this is more how we kind of define it is it's a fragment or a component that can be reused and embedded into any page. It can be rendered on the client and server and this is important because across all these web apps we have some pages that are client-side rendered some pages which are really rendered on the server side and hydrated on the client side and then there's a combination of both. So we want to make sure that it supports both formats. It has 80% of independent life cycle and the reason we need that is that we can automate this independently we can ship this independently so it should have an independent life cycle and it has medium to heavy functionality so if you are adding code roughly which is around 20 components and you know reduces or 20 modules that's fairly heavy functionality that you are adding to an app. So while your micro fragment or component can act independently and it can be executed independently it really decides its behavior and UX from the host page. So the host page provides some context so that the fragment's behavior is determined by the host context and it has to adhere to the SLAs specified by the host context which is typically your TTFB, FMP and in our case we track the CATF which is the customer ATF whatever the customer sees when they land and this we track week on week in terms of how it's progressing whether it degrades so adding more and more fragments can sometimes you know those metrics can get compromised if you're not very careful with it. So we also say that fragments should be maintained as a library or as a service so essentially you can embed a fragment using just a script tag with a particular version of that script or you can actually make a service call to a remote service and that will give you the HTML that the fragment has to display. So it can be maintained independently as a service or a library. So in the light of this when you are like developing a fragment and there is a host web app there are some constraints that the host web app kind of places on fragment and the team that's developing the fragment is one that should not add a lot of code bloat so when you're developing a fragment and you should not have like you know 10-12 different files coming in it should align to the performance budget and most web apps actually know what performance budget they're tracking should reuse common versions of the same framework so this is also very important because if you are developing a fragment and the host web app let's say is on React 15 and you're on React 16 if this is going to be on the client side you'll download additional versions of React which is not needed. Integration should be limited to a few lines of code so we want to make sure that we encapsulate it in a way that the host web app is only dealing with some interfaces. So at this point you're probably wondering why do I have to do all of this stuff? I mean I can handle all of this using code splitting or bundle splitting and I'm sure that most of you have used bundle splitting. A lot of you know libraries support this out of the box so if you've used bundle splitting using routes using webpack entries or even module based bundle splitting using webpack dynamic imports React loadables is similar to that. What it does is that it also has support for server-side render and it also has a progress loader for when your bundle is loading. So React loadables is great to kind of chunk out your JavaScript code and to load them at a later point in time but it doesn't really solve for independent life cycle management so it doesn't tell you how to version it it doesn't tell you how to automate it it doesn't sort of allow you to separately execute it as an independent entity. So coming back what are some of the goals for component developers? So one is your fragment should be configurable because if you're not building a reusable fragment there's really a lot of heavy lifting you're doing to achieve this kind of architecture which doesn't make sense. So you want to ensure that the fragment is configurable that if you change the page in which it's getting embedded into it can accordingly its UX and behavior should change as I mentioned before can be CSR SSR and it doesn't assume anything about it's sorry my this thing is falling off of it. So it doesn't assume anything about the host context so it doesn't try to access DOM elements of your host it just uses event-based communication and I'll get to what libraries we use for this but there are many. You can analyze all the clicks user interaction of this fragment independently so all the beacons all the user clicks all the API calls or API errors performance metrics can be collected independently analyzed independently and as I mentioned it has an independent lifecycle you can release new fragments and the host web app either just gets the latest version or it sticks to a version that it already has. So coming to the specific instance of micro frontend that we have implemented is this is a screenshot of the product page and this is an auto parts product page where you're basically checking whether this windshield wiper needs to fit my car or not. So earlier before we did not have this check fit widget you would buy this and you might have to return it if it doesn't fit. So the reason that this widget is there is to help reduce the number of returns that we are seeing. So essentially what so the widget is basically configurable in that the year make model all of those texts is configured the number of drop-downs is configured and the data that it populates is coming from an API call and there is state management in this widget because you have to click on your then you have to click on make and there is some validation between the two and then finally model and the call to action here is the check fit button over there. So essentially what check fit does is it makes an API call to the back end and tells you whether this fits or not and when you click on a variant like let's say the 22 inch wiper blade this widget then re-renders and make sure that it checks for the right product part. So it talks to the host page to get context of the part saying this is the part that I'm rendering and hence my APIs are specific to this particular product and it listens for changes on the host page in this case when you're clicking on your variant it goes and re-renders. So on the product page what this gives is a binary evaluation of whether yes it fit or no it did not fit but if I put the same widget on the search page what it does is it issues a new search query to narrow it down to items that do fit. So there is so all of that is also configurable so behavior changed but it's configured right. So what are some of the design elements that we incorporated while doing this was one all the scaffolding all the boilerplate code was encapsulated into a node module and we just expose that for the host web apps then we expose an API to determine whether this widget has to be included or not and this we need because whenever we roll out anything we A-B tested extensively so we show the feature to a certain set of customers before it goes to everybody so everything is behind a toggle flag and we support lazy loading of the JS and the CSS. So this is essentially just adding a script tag and a style tag dynamically. So this widget has its own API integration so it doesn't depend on the host context for APIs it does its own API integration. It has its own automation test so it can be automated completely independently and everything is configuration driven as I mentioned before and it communicates with the host only asynchronously using this library called postal JS that is used for publishing messages and subscribing to messages. So coming to the code snippet I don't know if everybody can see it but I'll try to walk you through this. Essentially this is the widget container and this is the bootstrapping part of what the host container is using and this is a react component and the render method here is essentially just assigning a placeholder for this widget and this widget is actually rendered only on the client side but it gets its place where it has to render from the server and before we actually render it we check whether it is enabled or not. Great so there's some I think there's a typo somewhere okay. So essentially after it gets on to the client when the component did and it renders and the component did mount a lifecycle method is called next. It injects the CSS and the JS at that point in time and once the JS has loaded this method executes in which we pass in all the context information to the widget which says hey this is the product page this is the mount point and this is the part and the product that we're looking at. Right so I had mentioned at the start of the talk that we roughly like quite a lot of web apps and we share roughly around 20 libraries between all these web apps. So if you look go through walmart.com we are basically doing route based mini apps so product is one app search and browser is another app home is another app etc. So how do we share libraries between this and how do we do that efficiently I mean if you have to manage 20 libraries across so many teams it can get really hard to do. So what we use is a web pack feature called web pack DLL plugin. What this does is it allows you to consolidate all your dependencies into a manifest file and instead of each web app trying to resolve their own react and load and all of those dependencies they just reference this manifest file and using a complementary plugin and that's the version that they all get so that way it gets easier to maintain. You just have to maintain the versions in this one in this one configuration saying these are the versions of react and redux and common libraries that I'm using. Yeah so this is what the web pack DLL reference plugin is what the web apps are going to use and as you can see I've got like the kernel 1P which is the manifest file that was generated from the previous build. So I have two of them and it just references these so that those versions get maintained otherwise you have a problem of multiple people using different versions of the same library and if it is client side rendered then you're downloading those on the client. Right so communication we use postal JS this has the same semantics as any kind of server side communication you have a channel topics etc. And you use you basically publish a message to your topic and subscribers get the message from that topic and the widget is essentially a JSON configuration so we have dependencies between the nodes that are mentioned in the JSON file. So JSON is a good format for us to define a configuration in which there are dependencies from the from the leaf nodes to the topmost nodes. So this was just a reinforcement of what I'm saying but since I'm kind of going out of time I'll just really run through this really quick and I think I hope you kind of got the idea of when I talked is that first page load request goes to the web app. It just sends a placeholder for the for the widget and the widget then loads off the CSS from the CDN the JS and the CSS from the CDN then it talks to its own services for getting the UI configuration from which it makes API calls. Okay I'll quickly walk through benefits and all so one thing is we are a large team so our PR turnaround came down to one hour from one to two days because we're a small team of engineers. Person knew about the context as well as the technical aspects. AB testing was a whole lot easier because we're just managing all the toggle flags within the fragment at the fragment level and the most important aspect was that a bug fix at the fragment did not require a full page regression on the host app. It just required the fragment to be fully regressed. Yeah so takeaways independent development of page fragments configuration based UX and behavior fragments can be released independently off the main app so that's a huge win. And the thing you need to take care of is also should be orthogonal functionality should not be specific to a particular use case. Hence you have to make sure that there is an independent lifecycle for this that is reusable and reduce risk of failures because you can regress at a fragment level. And some of the downsides are when you've created fragments it can get orphaned because now everything works as as you expect. But there is no one size fits all so there are always use cases that you can get into where your component does not satisfy that requirement. And if you're hosting this separately and having its own API services etc there is the additional cost of infrastructure. Okay so that's all you can reach me over LinkedIn I'll be here if you have any questions and I have the additional reading material here on the slide. Micro front ends by Martin Fowler and the GitHub links for react loadable DLLs as well as the gist to the code that I just showed you. So thank you thanks for being here catch me later. Thanks Nidhi for the wonderful talk.