 A slightly provocative topic, single page apps and you know why we want to kill them and build things on micro front ends but let's see how this goes. The intent of the talk is about trying to let you guys know that there are other possibilities than building single page apps and see if you guys want to try and explore that. And before we start any further, I mean I just want to kind of recognize and applause the team that built the very first micro frontend app for us in Sapient. This is a fantastic awesome job, building the frontend framework and also taking it production with a couple of our clients. And a big shout out to Anand, Imran and Saurab who also helped me with the demos that we'll get to see today. So we all love SPAs, right? We love single page apps. People building single page apps here, yeah? Most of us, pretty much the entire room built single page apps, awesome, great. So we love single page apps. I mean businesses want single page apps, clients ask for it, product owners ask for it. And the reason we do that is because they're supposed to be faster. They give us a good user experience because once a bundle is downloaded, it works on the desktop. It's supposed to be faster, right? And as technologists, I think we just love trying to solve all the complexity and the challenges that single page apps throw at us. You know, how do you do dynamic imports? How do you do route level code splitting? How do you do lazy loading of routes and stuff like that? So a lot of complexity and we love solving those challenges. And I used to be a huge fan of SPAs. In fact, way back in 2012, my very first talk actually was on SPAs, was building an Angular front end single page app on top of Magento. And I kept advocating that for a really long time until about a year back when I started going back and questioning, you know, does it make sense building a single page app and what are really the values of building a single page app? And also a lot of my stuff that I'm talking about is based on things that I see in the internet nowadays. So a lot of sites are being built on React and Angular of the world and they're all single page apps. But the experience that you get to see is something like this. You have half the site loaded in. You have the header, the app shell loaded in. But the actual content that you want to interact with is still taking time to load because your app sitting in the browser is making a network call to an API gateway, somewhere sitting in Europe or US and waiting for the JSON data to be sending back and parsing the JSON data, which is a very great experience, right? And sometime back, Jake Archibald, who's one of the Google advocates, actually posted a video saying GitHub's SPA is slower than its server-ended page. And he did a video saying on... So this is he's sitting on a Heathrow airport trying to close a couple of tickets on GitHub. So what he did was, the one on the left-hand side is an SPA. He clicks on a link, copies and pays the same link in a new window. And he actually shows that the new window loads faster. He clicks on a link, opens up a new tab. And you can see on the left it's actually loading and the page on the right is already loaded in by the time. So while we go with the notion that single-page apps are supposed to be faster, they need not be. They can be faster. I think companies like Flipkart and a lot of other people do a fantastic job making SPAs really fast. But it's not easy. It's very, very difficult. And the biggest problem with single-page apps is the amount of data that it sends down the wire. So this is, again, another very popular e-commerce site where I hit the home page, I get about eight MB of data downloading in. It's about nine actually. A 9.4 MB of data just hitting the home page. 9.4 MB of JavaScript loading in. Out of which, close to six MB is unused data. It's not being used at all on the app. It says down there below. But 5.9 MB is unused of all the 9.4 that's loaded in. So that's a huge amount of data being sent down the wire, just waste of bandwidth in for your users. SPAs also bring in a lot of other complexity. If you have tried integrating an analytical tool, A-B testing tools, they don't work very well because most of those tools require DOM events. And in a single-page app, you don't get those DOM events and you try and fake them by using different means. That's one of the bigger problems. Trying to deploy apps, trying to have a continuous deployment is a challenge because every small change that you try and make requires to deploy the entire bundle. You deploy the entire app for a small change which also means you need to regression test the entire application. So that's a lot of effort going waste. And for me, the biggest problem is trying to upgrade. So you built it on a framework, the framework is great. Now some new libraries have come in or you want to try out a new helper function that's there. You can't try it out within your module because you don't know if it's gonna go and break something somewhere. So upgrading a single-page app is like a mini project in itself and it takes a lot of time and effort. So there are a lot of challenges that come with single-page apps. And if you think about it, your single-page app is nothing but a monolith sitting on a microservice architecture. So your backend teams are building microservices, they're building your pricing APIs, they're building your product APIs, but you have this one big monolith sitting on top and you can't upgrade anything small because you have to deploy the whole thing. So it sort of breaks the microservices paradigm. And isn't this what is happening to the world today? The backend teams predominantly building monoliths in the past. They have figured out the drawbacks and the problems of that and they're actually moving to a microservices architecture. Whereas the front-end teams who sort of were on a target, actually just sort of microservices, right? You could create an HTML deployed, create a CSS deployed, work, are you moving back into a world of monoliths? So what's happening around here? And most importantly, their customers care that you're building a single-page app. Your customers don't even care, don't even know that you're building a single-page app from a technicality standpoint. They may like the single-page experience of it, but they don't care whether it's a single-page app or not. So what's the big deal about it? So if there's an alternative where you can try and give your customers a single-page experience, I think you should explore that. And if that helps you reduce some of the complexity that single-page apps gives, definitely go for it. And that's where microfrontends come in. So microfrontends for me is an alternative approach to building front-end applications, right? It came in, the term came in 2014 for the first time. It showed up on ThoughtWorks TechRadar. And since then a lot of people have been working around that, talking about it, building applications around it. It's also called front-end microservices. And what that basically means is the whole notion of microfrontends is based on a concept of microservices. So hopefully, if you have attended the talk by Arun, which is a previously, you got the concepts of what a microservice architecture is. And to understand microfrontends, I think it's important for us to know what microservices are. So for me and for a lot of front-end developers like us, microservices are a stand-point that gives me data back, right? If you ask a lot of other people, they'll say microservices is breaking down a monolith into by domain boundaries. So different people have different thoughts and different ideas of what a microservice architecture is. But I think for me, the one that resonated the most was the one, the definition by Morton Flower, where he says the term microservice architecture has sprung up in the last few years to describe a particular way of designing software applications as suites of independently deployable services. And for me that word, independently deployable services means a lot. Because I think that's where I've been struggling with building single-page apps. And if there's an option where I can independently deploy modules, that's fantastic, right? Some of the other core principles of a microservice architecture are the ability to abstract complexity away from developers. So most of the complexities move somewhere else and developers are just working on their respective modules and building and deploying them. And things just work. The ability to move quickly, obviously. I think that is one of the main reasons why we want to do that. And it's also about breaking down teams by a domain context and not necessarily by your skill sets. And finally, it's also about giving teams an opportunity to decide what tech stacks they want to use. So these are some of the broad principles of a microservice architecture and we try and inherit that to the micro front end world. Another important thing I want to try and touch upon is the notion of building software. You know, when you build software, a lot of us think it's like constructing a building. And as architects, our roles are to define that blueprint which has every minute detail of how the building is going to be laid out, the foundation, right from the material that's going to be used to the final look and feel, right? So as an architect, you're required to design that entire building to the final look and feel. And the problem with that is buildings don't change. When you build a building, it's fixed. You can't change a building, but the software that you build is expected to change very often. It's expected to evolve, it's expected to grow, and it's expected to be future ready for the next five to 10 years, that's what the clients ask. And in this book called Building Microservices, Sam Newman brings a very nice notion. He says, as architects, you should be thinking yourself as town planners and not an architect who builds a building. And what he says is, as a town planner, your role is to identify that, okay, this is my town, and these are the various resources that are there. And my job is to make sure that I identify the zones in that particular town saying, hey, this is an industrial zone based on the resources that are there. This is a residential zone, or this is a market city zone, commercial zone. And I define the roads and the infrastructure and the plumbing and the electricity and the wiring required to connect all those zones together. And I let those zones evolve independently. And if you have that kind of a notion when you're building a software, I think you'll be able to build applications that are scalable and resistant, resilient for years to come. So if you are interested in microservices or want to learn microfrontends, please, please do read that book on building microservices by Sam Newman. It changed the way I thought about microservices completely. Okay, so that's all about microfrontends. Now, how do we take our single page app and convert it to a microfrontend? So for that, let's understand the anatomy of a single page app, right? Any SPA has got these three broad components, actually, all the time. So you've got components, which is a collection of status components, stateful components, styling, layouts, right? And then you have got some sort of a state management library out there. So you'll have an action reducer and you'll have some sort of a middleware to handle async operations and some sort of side effects that are there. And you have routing. And what you do is, so these are all basically JavaScript files. You take all these JavaScript, put them through a webpack and bundle it. And you make one big bundle. And then you realize the bundle is very big, so you break it down into different chunks and then you do the chunking. So that's essentially how we are building single page apps. Now, to convert it to a microfrontend, you basically decouple these out. You break them out into different modules and have ownership for each of them. So this is something how a microfrontend appears here to look like. So you have different teams that are basically just creating those microapps. They're picking up those apps and they are building them in React or Angular or Vue or whatnot. Create those bundles, put them into a cloud bucket or a public leaders folder. And then you have templates which are nothing but HTML shells. So that HTML file is nothing but slots within which each of those microfrontend apps will load in. And you have an assembly layer which is usually on node where every time a route comes in, it picks up a template, picks up these microapps, puts them into the page, switches the page and serves the page out. So that's how the whole architecture would look like when you're trying to build a microfrontend. And one important thought when you're trying to break down your app is at what level do you want to break? So when I had conversations with a lot of people, people had the thought that microfrontend, microservices, so every microservice should have an equivalent microfrontend app, which is not right. So for example, I'm building a pricing microservice. That does not mean I have a pricing microfrontend app. The notion of breaking down your frontend app is more from the visual side and not from the domain side. So if you follow the atomic design pattern, you have atoms, molecules, and organisms. So your atoms and molecules would be the components that you use. The organism is where you want to break it at a microapp. And for me, the definition of an organism is a module that is self-contained is independently visible and has enough meaning to it. And two modules do not have to communicate with each other for their existence. So for me, that is a microapp. And if you try and break it at that level, I think that's where I've seen it work best. So you have organisms, and then you basically stitch them up into templates, and then ultimately your pages are served up. So if I had to put that in from a visual context, this is how it would look, a very simple page. So you have the header as one microapp. You have the product details as one microapp. If you've got a categories on the right-hand side, that's the third microapp. And fourth could be a recommendation that something else. Now, if microapp three was actually my faceted search where I click on the filters and that's updating content on the left, which means those two components are going to be talking quite often, then I'll actually club them together as one microapp in itself. So you need to kind of weigh up pros and cons and decide at what level you want to break. But this is one of the ways that you can try and break a app. And a couple of tech stacks that would work. So a microfrontend framework would inherently be polyglot in a certain way. You know, there are different tools or libraries that you want to use. So most of the microapps would be built on a JavaScript framework. You would use React, Angular, Vue, whatnot to build those out. Your assembly layer, most of the time, is usually node. So there are two popular, so TaylorJS is a very popular library that is used to stitch those pages out. And we are working on our own internal framework called Malcolm Pazza. This will be on the works. You have HTML that work as a template and layout. Most of the time these are driven by CMSs. So you could either have Drupal or Adobe Experience Manager or anything where content authors go create these templates and they publish out those HTML slots for you. Routing, most of the time it's linked to the CMS that you use, so you'll end up creating a custom route. Otherwise, you can also use Skipper, which comes as a part of Mosaic 9, part of Zoolando's framework for microfrontends. And in the past, we've also used Zool as a routing engine. So Zool is a routing library for APIs and microservices. But end of the day, it simply receives a request and points it to an origin. And I could also use it to point it to a frontend app and that worked perfectly fine for us. So you can use Zool over there. For a package manager, the recommendation is to try and go with a mono repo. So every micro app sort of resides within its own repo or within its own package. You could have it in a multi-repo architecture also, but then that tends to get a little difficult to maintain. So we have seen mono repos work best. So every micro app lives within the package and we use something like Lerna, which a very nice tool to run command, in-prem commands across all your applications together. Probably show you a couple of these and styles. So because every micro app has to kind of live independently, we prefer encapsulated styles. Intent being that styles from one micro do not bleed into the other and do not pollute or mess up the design. So we prefer encapsulated styles. CSS and JS frameworks are great nowadays. So anything like CSS modules, Emotion.js or style components work best in this kind of a pattern. And building great software is not just about technology. I think it's a combination of getting the right architecture, getting the right processes and the right teams. So architecture is most of the time we do a pretty good job with it. Processors, everybody follows agile or they claim that they follow agile, so that's great. Teams is where the challenges usually start. So because traditionally most of the teams are broken down like this, they're broken by our skill sets. So you say these are the front end teams, these are the back end teams, these are the API teams and this is how they work. But to really get the benefit of speed and agility of a microservice architecture, you need to be slicing them vertically. And you have your teams grouped out as, hey, this is the homepage team, this is the search team and this is the cart team or the products team. And every team I call them as full stack teams rather than a full stack developer. Full stack developers are overrated here. So I'll say it's a full stack team. It may be a combination of one person for each of the skill sets. Could be even two people who kind of are fungible enough and you know, hey, I do a little bit of react, I can do microservices also or I can do a bit of API also. So fungible teams or polyglot teams, but vertically sliced. So every team can go create the backend API, get the front end ready, deploy it and you're up and ready. So this gives a huge change in the speed at which you're able to deploy things. Okay, enough of dian. Let's look at some demo. So what I'll do is big enough for everybody to see. Still bigger. I mean, I'm just gonna run an NPM start command over here. So we have a project called NPM Nitro. Let's start. Little runner server here. And then they go to localhost. So a very simple app. It's got a homepage. It's got an about us page, static content and a product grid. Now, if you look at a page like this, each of them is a micro app. So header one micro app, product grid is a micro app. And even the footer is another micro app. And you can't see that just for the sake of creating micro apps. If I go and see my inspect element, refresh that. So you'll see that each of my apps load in as a separate JS bundle, right? So a lot of people think that, hey, in this may not be right. Why don't we just club all of them as one single bundle and deploy it? But if your bundle size is very large, that's not great. So with Webpack, you would do code splitting and chunking, which essentially would be like, you create one big bundle and then you create, you let it mix up everything and then you break them down into different, different places. But here the advantage is every app gets bundled in its own package, which means now I can just look at one particular app and say, hey, my header bundle looks looking very large. I can go back and tell the header team, hey, your bundle size looks bigger and you can optimize that. I get to see it very clearly right up on my network tab. Don't have to go into a Webpack analyzer and do source maps and all those kind of things. Stayed on my network, I can see that. And the other advantage to this is on this particular page, there are only three components. So only the three component files loaded in, which meant if I had a really large application with say 100, 200 components, it doesn't matter. I will get only three bundles on this page because those bundles will load only when that page gets hit. So those are some of the benefits that you can start to see with an architecture like this. And another point is with regard to state management. So the usual practice and the recommendation is that you build the apps at a level where they do not communicate with each other. But at some point of time, you know, you'd have to. Like for example, when you click on an add to cart, the mini cart count has to increase. So in a scenario like this, what we do is every micro app has its own state. So we're using Bobex over here. Fairly great. I mean, we love Bobex much better, not much better, but much less a boilerplate than Redux. So, and each app has its own Redux store, sorry, Bobex store. And we're using a simple pub sub to communicate between each of them. So when I click on any of this, it's basically going and updating the mini cart count on the top. So a fairly simple mechanism. And I think it just works fine. So this is the demo that we had. And maybe we can just walk you through the folder structure and some of the code that is there. Try to make it big again. So fairly simple, right? Really simple, trying to keep it as simple as possible. So we've got a package.json. We've got a learner file. Learn as one that runs most of the tasks. We've got a server which is running my node server. And packages is where all my micro apps are residing. And templates is where my templates are. So if you can look at the package or script very quickly. So I basically have these scripts. So NPM start will simply run node server for me. And when I run install apps, it's learning, learn a bootstrap. So when you do a learner bootstrap, what it does is it goes into every package, reads the package.json and does an NPM install in the respective packages. So instead of having to do it in every single package, learner will do all the packages in that particular folder for me. Similarly, and learner build, run build, will run the build script in every package. So what you need to do is in every package, you need to make sure that you have the same script and learner will run it for you. So that way it makes it easier for you to run all the builds in one single command. And when you restart, you also have an ability to run them in parallel. So that's learner. On the server side, it's, again, a reasonably simple express app. You import in Taylor, define what are the fetch templates, find the static folder, find the routes and the port that you want to run it in. And in Taylor, you have, you're just setting up some headers, defining where to pick up the templates from, and so on and so forth. And templates is sort of the routing API for us in this place. So this works very similar to the way Next.js works. Now in Next.js, you go and create a pages folder and create a .js file that becomes a route. The same logic over here. So when I create an aboutus.html, that is my about route. Or this is my home route. Or this is my new arrivals route. And I can also have the ability of creating an app shell, which is essentially like my base template. So most of the common code goes into my app shell and I can go in and create a slot. Ignore the comments out there. I'll come to that later. But you have something called a slot. And within the slot, you can actually load any page that you want. So as you notice, I have my server running. And these are plain simple HTMLs. Now, say for example, I want to go back and add a new component to my aboutus page. Aboutus page looks really bland for now right now. So I want to add a component to my aboutus page. All I do is I'm going to add a fragment. So this is again a term that Taylor uses. So I have one of the micro apps called feature, which is supposed to show me a list of feature products and all the index.html. So I save my template and when I refresh it, hopefully it should load in. That comes in. So I didn't have to redeploy my app. Just make a change in HTML via CMS or anything. And I can compose my components on the page there itself. So that's one of the good features or possibilities because you know most of the e-commerce site, for example, you're constantly changing it. Home page is changing very often and you don't want to keep deploying it every single time. So you create a template file, just update the temperature. I can drop in the components that you want, publish it, the page is up. So that's how templates work. Let's look at packages. So packages is where all our React apps are sitting. I mean, we chose to use React over here, flavor of the season right now. So we've got different components called featured, footer, header, products, and my vendor bundle. I can probably go into the featured component and just quickly show you. Very regular React component. You've got a cart component. We are using Emotion.js for styling here encapsulated styles, gives us a pattern of a single function component, CSS and JavaScript all in the same file. Go to cart list. And if I want to make some changes over here, so for example, let's say, just add some text for now. So I built up my component. Now, so as an individual team, I'm going to be working only on my featured component. So what I do is I will, I'm already seated into featured. So that is my featured folder. I can do an NPM start, you'll run webpack.dev server for me and it should hopefully load it, fully my featured component. So that's my featured component with the changes that I just made, right? Very simple. And I'm happy with this component. I think this is good. I want to, I'm ready to push it into my main application. So what I would do is I'd stop it and I'll simply run NPM run build. I'll show you the build schedule. What this does is simply creates the bundle and puts it into my disk folder under the micro app thing. That's it. And once it's done, my changes should automatically reflect on the main site. So you see here? And my server is still running. I'm not using Nodemon or anything to do a watch and restart. It's a proper server that's running. I just, first I changed the template, updated it, it updated. Now I go and change a component, deploy only that component and it's already reflected onto my site. So that's there. And just a quick insight into the webpack config file. A couple of things to see here. A regular stuff that you pick up and you have your module exports which is pickups of my index file and it creates a path and puts it into my disk. So this is where I'm taking that particular bundle, putting into my disk slash package folder name. So if my app is called homepage or featured app, it puts it into disk slash feature name slash, so on and so forth. That's there. Now, one thought on this. So when you're building all these micro apps, each of them is independently built, independently deployable. So which also means that those library bundles like React, React, DOM or any other libraries are getting bundled with every single app. And if I've got five of those bundles on the homepage, I'm going to have that getting loaded five times, which is not really great. So the answer to that is externals. So webpack allows you to define an object called externals and say, hey, these options do not include my bundle. So what we do is every micro app will pick up these common library bundles and in the externals, it will define that we do not want to include this as a part of my micro app bundle. And these are separately deployed as a part of my vendor bundle. And that also ensures that you get those really small bundle sizes on the front end. So this is one of the ways. So the external is an important feature that you should try and keep in mind when you're working with, when you're trying to build a micro front end app so that you don't have the same library getting loaded via multiple apps. So do have a look at that. I'm saying, okay. Oh, that was fast. Can I just, one small demo? Okay. So, well. So I just want to mention that, when you want to do server-side rendering with these particular apps, you can deploy these into Firebase Cloud Functions. And that is a demo with Firebase Cloud Functions. I'll share the GitHub repo with you guys. Have a look at it. When you do server-side rendering, you want to put them in Docker containers. Docker containers work great, but it's also an overkill. And this was a tweet by Sarah. She says that deploying React into Docker means that there's a small trailer truck. I mean, probably a truck city got a big trailer. So you can try and deploy them using Cloud Functions. Makes life really very easy with that. Yeah. You guys can, so yeah. Okay, that's fine. These are the reports that you can look at. And look at that. Thank you.