 Good afternoon, everyone. We're excited to be in this conference. In fact, this is one of the best conferences we've ever been to, not many times your work gets showcased in the keynote. And on top, and to add to it, incredible audience. I mean, everybody we ran into yesterday and today had so much stuff to tell us about Flipkart Lite, all the positive feedback we got. Thank you. Thank you so much. We're really honored to be here. In fact, there was so much stuff on Twitter. We were actually spending all night to go through all the stuff. There's so much stuff going on. And especially the feedback, right? I mean, this is just the beginning. There's a long way for us to go. And a lot of feedback we were getting. It's incredible. But truth be told, it wasn't an easy journey for us till here. As many of you know, beginning of this year, we shut down our mobile site. And we kind of actually committed to one thing and one thing only. And that was like we wanted to give the best experience on mobile to our users. The challenge is to actually make this happen in a country like India. Tal from her talk yesterday was giving out some astonishing numbers about emerging markets in India in particular. A typical device in India is at least six times inferior to a normal device you would find here in terms of memory, CPU, storage. On top of it, you have 87% of your internet users on 2G network. If you actually kind of put this together, it's almost impossible to give a compelling experience on a mobile device. And we have one more challenge on top of it. We are an e-commerce application. Users don't come to e-commerce application every day. So when they come to you, you better be getting their attention. You cannot afford to throw dinosaurs at them. This really got us started on a completely different journey, a journey that we have never taken before. In fact, it was such a soul-searching journey for us. We ended up with an awesome product that we are very, very proud of. In fact, we are so proud of it, I would not miss an opportunity to show it every time. In fact, I was showing it to a lot of you guys yesterday when I ran into you guys. And I'm going to do it one more time. I'm going to show a video of how Flipkart Lite actually works. So OK. There you go. So you fire it off from the home page. Just like an A2 page. There's a splash screen. You slide up the categories. Look at how fluid the animations are, everything that expands. This is actually a live app. I mean, you're looking at a live e-commerce app. Look at how fast the products are loading in the search page. And this is actually coming from our 30 million product catalog. The product page almost loaded instantaneously. I mean, all of this actually happened in a matter of two to three seconds. This is incredible. In fact, what I'm going to show you next is the most useful feature that we've built in Flipkart Lite. We just switched to offline mode and see what happened to the app. It is visually different to the user. It's no longer showing the dinosaurs. The user is still able to do whatever he did in the last session. In fact, if you look at all of these products, everything is grayed out except the product he was actually browsing last time. So this is the offline experience on Flipkart Lite. There you go, online. And it's back up. So how do you get this? You go to flipkart.com on the latest Chrome or Opera browsers on your Android device, add to your home screen, and boom. You don't have to install it or anything. That's it. I actually have a funny story to share here. When we were actually working on this internally, not many people in Flipkart actually knew about it. So when I was actually showing this demo to our leaders and all of the other flipsters, I was actually showing them, hey, so yeah, we call ourselves flipsters. I was actually telling them, hey, here's a light app that we are working on. What do you think? Oh, it's cool. It's fast. It's light. Yeah. How do I get it? I don't see it on the Play Store. You won't get it on Play Store. You just have to go to Browser and type in the euro. And this is after we shut down our mobile site. So everybody's just dropped. Oh, this is incredible. So yeah, I mean, we've had an exciting, exciting, journey in coming up to where we are today. But we sincerely believe behind every product, there is an incredible team to make this happen. And this product was no different. It was five engineers, 42 days, and we got it. In fact, I'm going to ask a couple of those engineers to come up on stage today to talk about what really happened in those 42 days. I mean, I know I was getting requests for too many Red Bulls, but a lot more happened than Red Bulls. So I'm going to actually ask Jair to come up first, take us through what really happened. And thank you. Good afternoon, everyone. I'm Jair Santosh. I'm part of the Flipkart team. I work as a UI engineer there. So we are incredibly excited to take you through what our journey was, what our experiences were when we were building this Flipkart Lite app. So before we shut down our old mobile website, this is how the rough flow of the application was. So the browser fires a request to the web server, which in turn calls other API services, gets the data. I mean, it sends back a very fat HTML. And then from the CDN, we load further assets. This approach actually worked for no JS browsers that we had. If you see back in India, we had about 60% that was coming from no JS browsers. Supporting all of that was difficult and all that. But we wanted to ensure that we wanted to give a very good experience. But the page load times in this approach really suffered a lot. So we had to trash this approach out. So what we changed now, so we thought probably once the application is loaded, we can actually do a nice client-side application whenever on the client side. So for the first page load, you actually contact the web server, get the HTML bootstrap shell, which loads up your single-page application. Then we went ahead and added something called service workers. So this acted as a proxy for further requests to API or push API or CDN. So we cached whatever we could. And yeah, boom, this gave us a lot of advantage. So a little more on the client side, what we did. We used React to build a single-page application, navigating through the various pages with React router. We also built a lightweight flux implementation for fetching data for our application. So we built something called frontend.js. So the GitHub link for the library is available in flipkart slash frontend. But still, the first-page time still suffered because we had to load up fully the single-page application so that it's intractable for the user. It still took a lot of time. So what we wanted to do was enter HTML page shells. How many of you, I mean, I think through the Dev Summit, you've heard a lot about what page shells are, what you can do. So we just go into a little more detail about what we did for rendering our HTML page shells. So we divided our application into two states. One is the loading state, which is, before you even fetch the data, you know what your state can be. So that is what we call as the loading state. Then the rest of the application moves on to the loaded state, which is after you fetch all the data that you need. So a typical loading state would look something like this. So this actually, like, you can actually give the user visual cues into how the application will look like once the data is fetched. So you can actually render whatever you need upfront and before, I mean, much easily than only rendering after you fetch all the data. So if we move on. So how did we achieve these HTML page shells? One thing that we wanted to do was minimize the server processing time as much as possible. So that meant we wanted to generate these HTML page shells upfront during build time itself. So whatever JS CSS images that you write for your application, we run it through Webpack. We generated bundles. So once these bundles are generated, we process them through another render cycle, which allowed you to generate the final HTML page shells that you wanted in the loading state. Because you can predict what the loading state can be for each of your pages. And you can generate them at build time. To give a little more idea into what we call as pages in a single page application is, I mean, you have a lot of logical pages in your application. And each of these can be generated as a static page shell for you to load them really fast. So this is now the new state of the application that changed. So during the first page load, you actually, I mean, when you load up your single page app, to load it, you first make server requests, get the HTML page shell back. And this is something with very less processing time on your web server. I mean, this is not generated at runtime. So we were able to optimize a lot on that front. So once you get the page shell back on the document, it's ready for rendering. Because you have all the HTML that you need to put the loading state on the browser. And you also have to fetch the data now to fully render the application. So we utilized service workers. We also utilized service worker to, once it's installed, we were able to fetch the rest of the page shells that are there in that single page application. Because what you loaded upfront was only the first page of your single page application. We also used service workers extensively to fetch all our data endpoints. I mean, data from our endpoints. So if you see the code a little, you have the API endpoints that we call. We kind of went with cache-first strategy. So you can see, for most of them, we have what is the fast SW.fastest in our configuration for toolbox to fetch the data. But yeah, for fetching all the static assets, et cetera, we used cache-first. Just to reiterate what cacheable HTML page shells are, like your page components are rendered in the loading state upfront when you load the HTML immediately with all the critical CSS in line so that it will allow us, we thought it will allow us to get to the first paint time really fast. So once you load this loading state, now you have to fetch the data, or you can also utilize whatever data you had prefetched using service workers and re-render your application. This is one thing that I want to bring to your notice that in this kind of an execution, you can actually have partial re-renders compared to native world. You can, so whenever you need to change something on the screen, you need to re-render every pixel of it. So I mean, everything on your page on the native app. But here you can actually have partial re-renders possible. Since we were using React, it allowed us to do so. Another thing is we get too excited about page shells. We could go ahead and generate lots and lots of page shells. If your application is really complex, I mean, you could end up with a lot of page shells, which when you're prefetching after your service worker is installed, it might consume a lot of bandwidth for the user. So what we thought of was maybe this is not the right approach. So what we did was, you know, if we analyzed our product, we went back. We analyzed, like, what are the product flows? So there are, if you look at our e-commerce product, there is a phase where the user, you know, broses from the home page, searches for a product, goes on to the product page, and then goes on to the checkout phase and then completes the payment flow. There is another flow called the order management flow where he can manage his order, like, returns and cancellations of his products. We also have, like, an account management flow for the user. If you analyze these flows, they are not really, like, very interconnected. They are, like, you can kind of say they are mutually exclusive. So there is not a lot of back and forth between these flows. So what we did was we broke our application down into these product flows, which are mutually exclusive. And, I mean, instead of going with a one big monolith single-page app, what we did was, I mean, we broke it down into smaller single-page apps. So that way, what it allowed us to do is we were able to build and deploy this separately. We separated out the servers, set of servers that these are deployed on. And this gave us much more freedom into pushing whatever affects to only one set of servers and not all of them at the same time. Since we bundled them separately, we also decided that, since all of the single-page applications behave in the same way, there is a possibility to share whatever common libraries and utilities that you have. Like, for example, our front-end JS implementation, the React library, we were able to make it all common for all the applications. And what was needed to make it work as a... And it almost made the whole application work as kind of a big single-page app. So what was... SW Toolbox has this another wonderful thing, which is like it supports express JS-style routers. So, yeah, so you can actually model your application and you can put in logic in your service worker code to manage your routes of your product flows in such a way that you can actually, whenever you needed an app-to-app navigation of all your single-page apps, it meant you only need to download app-specific files because you had all... I mean, you can actually... Because we had already prefaced and pre-cached the common libraries that were needed for loading the single-page application. So the results of what we did here is like we actually tested on a 3G connection first. And after the page load, these were this... I mean, this was a timeline that we could achieve. So we could actually get to the first paint in, like, 30 milliseconds time. And that's... And that was something phenomenal. And this way, like... I mean, we then went ahead and tested it on 2G. And voila, the results didn't change. We were able to achieve the same first paint times as that was possible in a faster connection in 3G or Wi-Fi. So this was really... Like, made us really happy. And this is where, like, the power of service workers comes in for you, where even in flaky networks, you can actually load an application state for the users upfront with really faster times. So I'll go ahead and hand over to Abhinav. He's my fellow teammate. He'll walk you across the rest of the journey that we had. Thank you. Thank you. Hello, everyone. They introduced me. My name is Abhinav Rastogi. I'm a UI engineer at Flipkart in the same team. So, yeah, I think we established yesterday that you guys are pretty comfortable with British accents. Let's see how it goes with Indian accents. We'll find out. All right. So the first thing I want to talk about is the app-to-home screen feature and how we utilize it. So it is a very important feature, you know, when you are a progressive app and especially for any commerce channel like Flipkart, it becomes very important to re-engage the user very easily with very less friction. So when we went native only, when we were only apps, the app installs were a very important metric for us at all times, how many people are installing it, what's the current active user base. The same thing happened when we went as a progressive app. The app-to-home screen tends to be, at least it seems, it is an important metric because people who come from the home screen tend to be, you know, it's easier to convert those users. So, at-to-home screen, as we discussed, as it was being discussed yesterday, has a certain heuristic that the browser implements before it allows the website to show a pop-up to the native browser pop-up to add-to-home screen, which for a very good reason doesn't happen on the first time. Now, when a user lands on our website, add-to-home screen is something that is a very new feature and especially for an audience like the Indian audience, we realize we may need to train the users of what this feature is and what are the benefits. So, for that, what we did was we created a first-time user experience which trains the user what add-to-home screen brings to the table for him. So, let me show you a quick demo of what kind of experience we built. So, this is our learning state and this is the experience that we built. We give a brief explanation of what Flipkart brings to the web and this we tell the user that it's just a tap away and this is what you get when you add to the home screen. So, it's accessible and you continue using the website like you would and it's only for the first time, first visit. Any way the add-to-home screen native pop-up will not show up in any case. But going further, we again need to prompt the user, not prompt, but we need to give some way to the user to add-to-home screen whenever he wishes to do so. For that, this is what we did. We added a small add-to-home screen button at the corner, which again guides the user of how we can add-to-home screen manually. So, if you look at it carefully to get his attention to the icon and again, this happens only once or twice in the first few visits. We shake the icon a little bit and we also tap into the hardware access that we have and we trigger and navigate a vibration, which immediately brings attention to something that is shaking on the screen. So, the next thing I want to talk about is the splash screen. Now, again, this is a very cool new feature which makes it very difficult for a layman to distinguish between a web app and a native app. So, what happens is when you add your manifest, you add your theme colors, and you add your icons and text, your splash screen shows up well and good. Another thing, what we saw after this is that the splash screen shows up, which prevents the user from seeing a blank page. You immediately see a splash screen and you go to the application. What happens after this is some of our data is still loading, at least on our home page, right? So, we added another layer, we added another splash screen, you could say, or a loading state for our home page, which triggers for both when you launch from the home screen or when you directly open from the browser. And as you will notice, I will just play this. This is the native apps load this and this is what we added over that. So, we tried to reuse the same experience but add a loader over that and when it fades out, the experience is ready to use. This gives a very seamless experience to the user. There's no jang, there's no jumping of content as it loads or things like that. Another thing we talked about yesterday was the custom navigation UI. So, Alex pointed out yesterday that you need to provide the user with some way of navigating, right? So, when you go to full screen, use the browser traits that are there and the browser brings some very useful features to the table. It brings the ability to go back for a user, to refresh, to go to the home, to go to your home page and things like that. So, when we go full screen, we need to build this and this is exactly what we added. So, as you navigate across the app, we have a dynamic header which adds the back buttons and home and search and things like that, right? And it's dynamic, now we can customize it. So, across different pages, it behaves differently. So, if you load a model, the same header can show a close button and things like that. Now, as we've been talking about service workers quite a lot, right, so let me also add a little more to it. So, the next thing we built was a rich offline experience. Some examples that we saw so far are that if you go offline, instead of showing a dinosaur, one thing we can do is show a custom error page which at least tells the user that, you know, we know what happened, that, you know, something went wrong, we are not able to access the Internet. We went a step ahead and as we showed you in the demo earlier also, we built an experience that is delightful to experience. So, as you will see here, when you go offline, now we are just going to append mode to demo that. We changed the color scheme of the application which guides the user without any annoying pop-ups or models or, you know, popovers and things like that or consistent banners that you are offline, like, you know, like in your face error messages. We avoid that and instead we give a delightful experience no matter what the situation is. The next thing I would like to talk about is what we did with some hardware APIs. Now that we have good access to really good hardware APIs, the first thing we decided to do was try out geolocation, which gives us a very easy win. We just pick up, we just, we are just one tap away for the user's permission to access his location and we are able to accurately and easily predict how much and how much time can we get a product to his doorstep. Just makes it very easy and delightful for the customer. Another thing we did was added an Easter egg. So, the API that we used here, just to give you a hint, is the accelerometer API. I won't tell you what the Easter egg is, but I will tell you how to trigger it. On the home page, you can simply tap the logo twice and you should see something happening based on the accelerometer data. You can try it out at flipkart.com. Now, while we are doing all this, we needed to make sure that we always made sure that a performance was always the first benchmark, the most important feature of our application. Yes, we treated performance as a feature and not a side effect. So, we have been talking since morning about rail, right? And it really does help. If you follow these principles, it really does work. The one that I won't go into the detail of all four, but one that I want to talk about is the animations. And yes, since I'm talking about animation, I had to animate that. So, the animation part of rail says that you have to render each frame in under 16 milliseconds. Right? So, as some of you might know, there is a project called Project Ganesh, which also is the name of an Indian god. But this is something that allows rasterization to happen on the GPU. What this brings to the table is a lot of performance benefits plus a lot of benefits in terms of power consumption. Right? So, we enabled it using some hacks like a metatag which enables GPU rasterization for us. And it gave us huge amounts of performance benefits. But there are a lot of gotchas there, right? It's not just easy sailing all the way. One thing that we figured, I will give you one example. One thing that we figured was that animating SVGs is costly. Right? So, we figured that SVGs are actually vectors, right? And rasterizing them on GPU gets quite costly sometimes. And it goes into a specific rendering mode, which currently with the current technology is didn't give us equal performance in all the phones. So, what we did right now is that we can either remove those or we can replace them with PNGs. And one, of course, the obvious thing is that use opacity and transforms instead of height width and those kind of things so that you avoid unnecessary layouts and paints. Just prefer compositing. So, here you will see an example that this is a website, this is a web app which is able to give a consistent 60 FPS performance on these kind of animations across devices because of these kind of optimizations. And here is some proof. All right. One last thing, one more thing that I want to touch upon is security that we talked, that Emily talked about yesterday. HTTPS is really a baseline now. We achieved the shiny green lock, as she said, and we have to tell you that it brings perceived security, which is very important in a country like India, and it also brings a very real security benefit. We implemented end-to-end HTTPS and made sure that there is no mixed content in any of our pages. This also gave us the benefit that it is future-friendly. What I mean by that is that I can think of at least two use cases. For example, we heard yesterday that hardware APIs, because of privacy reasons, might become... Some hardware APIs might become restricted to HTTPS access only. For example, your camera or your location. We are ready for that. And the second is HTTP2. It can give us great performance benefits, and that is on the cards for us very soon. And HTTPS allows us to proceed on that without hindrance. We also heard yesterday about content security policy, which allows us to set a specific response header, which tells the browser to very specifically allow only certain types of assets to be loaded from certain types of domains. So the simplest form of a CSP is that you just give a default SRC, and that's it. It works. But for a complex website, it might be that you have a variety of different domain origins for your different kinds of content, so you can configure all of them separately. All right. So this covers a lot of the basic stuff, a lot of the modern web technologies that we are using in Flipkart Lite. But this is not the end of the story. This is just the very beginning. We are just getting started. We are deeply committed to the open web, and we would like to see this on all modern browsers, and definitely giving the same experience across all modern browsers. Currently, what you see is the minimal experience. It's just the quick buy flow that the user is able to open the website, search for a product, and buy it, and the rest of the pages like your accounts and your orders and things like that, which are, of course, necessary. We want to add a lot more things. We want to enable things like push notifications, and we can attempt them with great offers as and when needed. With this, I will hand it back to Amar. I don't know what was harder. Doing all of this in 42 days or talking about it in 30 minutes. Well, yes, like Abhinav said, we are excited about what's yet to happen in this space, and we are deeply committed to this. I would actually like to take a moment to call upon the awesome Flipkart Lite team. Guys, please. So those are the five engineers. He's our engineering manager and product manager. So thank you, guys.