 Hello everyone. Good morning. I'm Akash. I work with the web performance team at Flipkart. Today we'll talk about how we use perceived performance to make Flipkart faster. Before that, how many of you feel Flipkart.com loads faster? One, two, three. Okay, thank you. This is my team. These are the guys you should blame. Flipkart.com loads slower. That's me on top. We have Abilash and Arya. All of us work on separate departments. I work on the desktop. Abilash works on mobile and Arya on server side. You should also have a performance team at your organization if you haven't. That's our team and you should also have a performance team in your organization that you have not done until now. It helps build a performance culture at the company. I really hate slow websites. I hate it when people just test on the connection they are working with their office connections and then get away with it. That's miserable. We in India are seeing people getting on boarded to internet with all sorts of connections you have with these data cards. We have our ISPs which startle the connection once we cross the FUP. We have horrible internet connections in India and it really bothers me when people do not test their websites across all different types of connections. They just leave things as is. It's a responsibility that we fix. Cool, thanks. You should make sure that your website works on all or not all but at least the least connection available with us. You will realize this only when you face it yourself. You will realize this only when the websites you build, you only feel that they are slow. You come across a slow connection and you feel the website is slow. I really hate these white pages. I see the title of the website up there but there is nothing rendered. All I see is a white page. I feel the web is slow because of these white pages. It feels slow because of these and the white page is actually the fastest thing the browser could render. I mean it doesn't need anything to render this. Anything you add on top of it, browsers will have to download to compute your JavaScript and render it on the screen. Now, today we will just see the download part. We will not talk about JavaScript performance, we will not talk about rendering performance, jank bursting or anything else. We will just see how you could download the content to the user in the best possible way. Let's see this. You start from this. You put your CSS on top, you put your JS at bottom, you use a CDN. You basically use all the rules on why slow. They have listed and users still say that the website is slow. What do you do then? I mean you have followed all the rules, you have done almost everything but still users say that the website is slow. That's when proceed performance would help. It's not their internet connection, it's because the way you have written your code, it's because of that it makes them feel slower. This to me is proceed performance and you don't always need the fastest bike to win the race. You need to have a good strategy to load the content to the users. It's all about how users perceive your page load, whether it's in a flash or it takes ages to load. That's how they will feel. They will not say it loads in 2 seconds, 3 seconds or whatever. You have to make users believe that it's actually loading faster, even when it is not. Now let's see how we do this, how we can embrace progressive enhancement techniques to make sure our pages load faster on all sorts of connections. We'll see things which we had done. This is the home page, this is actually the below the full of the home page. We push out home page very soon because it's where all our visit starts actually. We push out above the full of the home page very soon and below the full looks somewhat like this if you quickly scroll down. All you see is skeleton screens waiting for the content to be loaded. You buy more time from the user while the content loads. When the content is ready it goes in and sits in this. People also know that this is where my best sellers would come, this is where my mobiles would come. If I put it in those I can move ahead and keep scrolling actually without the full thing being loaded. This is that very recent MotoG page we developed. How many of you bought MotoG from Flipkart recently? It was really badness that day. This is that page. The left one is how it renders on a slow connection and the right one is how it renders on a fast connection. How we do this? It's actually really simple. The left one if you see, the images have not loaded but all we have done is we have put a background color of blue so that the text is visible. People can read the text while the images are loading. I mean our designers wanted all sorts of funky full screen images, full vector images and we were like this all will not load on slow connections. What will people see? Then we took a step back and we said okay let's give them at least something while all this loads. This is how we do it. Everything is clickable on slow connection while the images load. The images are not blocking the content here. They're just enhancement. Other techniques with people user show them exactly how much time it is going to take. How much of it is already loaded like Gmail. Optimistic actions. When you like a photo on Instagram immediately such that even when the network call is happening because it believes that 99% of the time the call will succeed. This makes the user experience really better for the user. This talk will see the third point. We'll see how we can get users to see what they're seeing right now very quickly. Next is measuring perceived performance because it's really hard. I mean how do you know that the user is perceiving your website slow or fast and it's very difficult to fix something which you cannot measure. Let's see the techniques for it. First thing you find on internet is synthetic monitoring which tools like webpitch test. I hope people have used it here. How many of you have used webpitches at least once? I'll go over these. Webpitch test shows you load times it shows you what defaults of request, how your request happened, it shows you CPU utilization while your page is rendering, it shows you network utilization it even shows you film strips that how your page is loading at what point. One really interesting feature of webpitch test is the film strips. This is the screenshot of our page on webpitch test. It has this frames on top and network photo fall on the bottom. As you move your mouse through the frames you could see what request is happening. So you could accurately drill down that this is the request which is making my webpitch slower and this is how if this request is slow, this is how the user will perceive it. This is one of the codes from one of our emails. Why is it taking 750 or download a 5kb image? This is just after developer ran webpitch test on one of our pages and he says to me this and that's the problem with webpitch test and tools like this in India that they give and consider load times on every one. Every time we will run it we will always see a new load time or we will see some random request taking too long and we don't know how is it happening. Probably because of the conditions over there but we don't know how often it is happening for our users. The bigger question is that how often are our users seeing the page the way webpitch test is seeing them. Are they also seeing it that way? How many percentage of users see the page this way and how we could go about fixing things there. So here comes real user monitoring. Actually real user monitoring or RUM as we call it. It requires a lot of infrastructure because you need to get the data from browsers export it, run your Hadoop jobs over it or whatever processing over it to get the metrics. There are third party websites that do it log normal and so on and you should be using one of those actually and window on load. So this is the basic real user monitoring you could do. It's really webpooked 1.0. It doesn't tell you how your page loaded. The above the forward might have completed very early actually. And this is the bare minimum you should track if you're not tracking anything you should be actually just tracking this. And browsers fire window on load when all the request started before on load end. So any request that starts before window on load it will count towards your window on load. It will count towards your images, your Ajax request or whatever are started before on load. So they told let's give some detailed info about how the page loaded. So W3C gave us navigation timing API. It tells us that this is how much time it took for the DNS this is how much time it took for the TCP, this is how much time it took for the server and how much time it took for finally the client to process it. And for big sites like us, the server time is very less. It's like 200 milliseconds or something just that and we won't get much optimizing it. This is where most of the time is going like it's in seconds. It's not a millisecond. It's in seconds. The time spent there and we would want more details about this processing part. I mean we just cannot leave like this. We want that okay if it's taking 3 seconds on client side what exactly is taking 3 seconds and what if you could export request from real users and reconstruct the picture that okay this is how the request loaded for the guy. And this is where resource timing API would help you. Resource timing API gives you all the requests that happened in the browser, the load time, the start times and you could even get the DNS and the TCP times if cross origin headers and this is really under documented actually. This is very recent and Chrome and latest Chrome and I even I tend supports it actually. So navigation timing API plus the resource timing API they give the complete end to end picture of performance that how the page is loading for the guy. It gives you complete picture of how the network was that for that guy and you could choose to see that where exactly time is being spent and so this is what we did. So we exported data from browsers and we ran a few jobs over it to process data and see that what exactly is happening with the users. Why are they saying it's slow? And this is what we saw. This was exactly the scene at the browser when the page was loading. It was complete chaos. I mean we have so many requests starting. They are all competing with for bandwidth. They are all interfering with each other and they are blocking each other. Actually we are consuming the number of HTTP connections we could make in browser and everything. To sort it out we visualize this in a form of a waterfall like we see in webpiste or your Chrome DevTools. This is from real users actually. And it has the start time and duration of all the requests and the moment we saw this we found out that there are a lot of optimizations possible. But how do we pick that one which would give us the maximum amount of benefit? So we set on to identify the critical request and in this case the critical request for us were the CSS, the logo your sprite which has our cart icons and all majority of the icons and this banner on home page which occupies almost 50% of the area. We said that if we are able to download this for the user he would feel that it's almost loaded and he would start interacting with the page and this was the time that above the fold load was happening and we should aim for getting this as low as possible. Now some of the findings, some more findings from the resource timing APIs. CSS and JavaScript are heavily cached over requests and the median for CSS and JavaScript was under 100 milliseconds actually. And cleaning up JavaScript CSS would hardly move metrics. It would hardly make things better for the user. But CSS load times are critical. CSS is blocking resource and we need to make sure that we keep a tap on what size it is and because it affects the start time of other requests we need to make sure, still make sure that it's as small as possible. JavaScript you should load it in bottom. Just do not clean up JavaScript just because your performance is slow and yeah, what was slow? So Google Analytics, Omnichord calls, they were all taking like 500 milliseconds for us on every page. I mean we could hardly help anything about it but yeah, after this we know that okay where is the time going and redirects. We were doing a lot of redirects again. We'll see how we fixed this later and HTML document itself was taking long to load and images. Images as they are known, they are still slow for the web. So to clear up things, we divided our requests into types of requests and when to load these type of requests. We had this critical request. We said that let the browser handle this. Browser network managers these days are really complex and really smart. Let them do heavy lifting and make them make the critical request discoverable to browser as soon as possible. Do not put something which in JavaScript which your browser parser will not be able to snatch and preload it. Now the non-critical below the full request. You should lazy load images, you should lazy load the modules which the user is not seeing at that moment and you should probably do this at DOM ready. And third party code. So third party code is again evil for us. I mean you don't know what these guys will do. They will inject an iFrame into your website or another JavaScript or another JavaScript or another image. You don't know. You don't trust them. So make sure that these not consume the resources which could be used to download resources which your users would see. You should make request for this after onload. You don't have control over these. All in all the data from resource timing appears a gold mine actually. Every time you would look at it you would always discover something new or the other. Let's see that how we went about fixing things which we identified with it. Fixing images. So this is the talk we have. We were having almost every day. A developer would say that this image is huge. Give me a smaller one to the designer. Designers will say okay how small you need. Developer at that moment will be really confused and he would make a random guess that give me this size image. But we should not make guesses. We should use data. We should use the data from the resource timing API. An example that was at the banner on homepage it was 300px. It took 50kb file. If it were a 50kb file it would take 380ms to load. This was from real users and actually happening for our users. This is the data we use to win all these battles with the design team. Fixing carousels. So again carousels are really terrible. This is a carousel on our site. This is on homepage and all other pages. It is very easy to wrongly implement it. This could affect the overall page performance very adversely if it is wrongly implemented. We will see how we implemented it. What was the wrong way and then we will see the right way. The wrong way is that all the images on all the slides loading in parallel and the situation we had was we had 350kb images which were loading in parallel and each one of them would take 30ms to load because they all compete for bandwidth. They all compete for network connections available at any moment. This is and actually we were just showing one image. We were not showing the other three. Why were we loading the other ones? So that's what we did. So we were just loading the first image. The other slides of the carousel were loaded after the page loads or when the connection was idle. We loaded these images via markup directly like image src equal to as a critical resource. So that browser can snatch this and load it as soon as possible. This is another technique we use on mobile website. We have this browse page and product page. People navigate very frequently between the two. They click a product on browse page and they go to product page and this is what we did. So we used the same cached image from browse page on product page and we upscaled it as a placeholder image. So that people at least see something on the screen while the big image is loading. This is how we made it feel that it's actually loading faster but it's not. I mean all developers hate teams I believe. So this is how Flipkart looked on Diwali and you could see that the header is brown. We have all these small decorative items on the left and right and it just then went on from there. Then we had this on Christmas this on Valentine's Day and while we were doing this we said to ourselves that the Christmas tree or the Diwali doodles they should load after the main content loads. They should not interfere with the main content. Your banners, your product images should load before these start. And this is how we came up with progressive festival deeming. While we did all these themes, the designer and developer were sitting next to each other and they did these themes actually. The theme is non-critical resource. It should complete after all critical requests complete. All functionality should work with the base skin and theme is just an enhancement. Limited to colors and background images but you could see that we achieved a lot even with this limitations. Another was that we will not use any other new DOM elements for the theme. We'll just use before after pseudo elements to make things work and all this would be packed in a single theme.css file which would be then loaded asynchronously after the DOM ready. Next is about fixing STMS size. I mean STMS size is very important because it affects the discovery of critical requests for us. For us the STMS size was big because of this menu. We had this huge menu on all pages of the website and this actually evolved heavily over the time. As we were adding categories every category would go in these menus and they were all controlled by business people and in few days this menu was huge. They abused this. Almost all the links are there. Initially there was just a menu and a sub menu. Then there were even tabs within the sub menus and multiply it across the six main categories. This is how actually the menu is actually this is how the menu would load on a slow connection on a data card like connection. You would see that there is small pause as it loads and this was happening for all pages. Menu was there on all pages actually and this was the markup that looked like we had our header on top. The search bar would appear but then this menu would come and it would look and we had this big menu STML and then we had our critical images here and this is how we identified that if we could cache this part of menu in browser it would be good. That's what we did. About 40% of our 40% of our markup was actually menu and it was persistent on client side in local storage for 10 minutes because it doesn't change. It changes very less frequently and it drastically reduced the payload we were sending for every request overall it gave us around 200 milliseconds of improvement and this was both for mobile website as well as your desktop website. This improved a lot. We could see in actually with the resource timing APIs is that the start time of the request dropped after we did this. Coming to redirects, redirects are really costly. It's really easy to get them wrong. I visit a website. I go to the website on phone. I type in website.com then the website decides to redirect me to the website. It has to be an STDP connection actually. This is bad for mobile. It will kill your mobile site if you redirect randomly. It starts with a shortcut actually. Developers write this condition. If some condition redirect and then all other developers would do is they would just put their conditions with some condition and take that shortcut. It's really bad practice in the code. We found that at one point all our search pages were redirects basically. Some even had two redirects actually. You could see between mobile and desktop very early on because if you don't get it right initially you will be left redirecting people from here to there. You should prefer a single URL between mobile and desktop. Flipkart.com for mobile for desktop. Good flipkart.com is bad. You would have to maintain two sets of URL every time new page request have to come to you. You will have to decide what will be the mobile site for this, what will be the desktop URL for this and how do we redirect from here to there. It makes things easier in the long run if you use this early on. Mobile site performance highlights. Most of the things we discussed were actually applied to both desktop site and the mobile site. We will see some mobile specific things now. Much of the users actually come from 2G connections in India. It's like 50% for us. We were using click initially but then we moved to touch start and that gave us a 300ms advantage. Touch start fires almost immediately but click would fire after like 300ms. That's bad. And maybe it is heavily to find out what's the right mix of content for the screen size and the bandwidth. You should also do this for your content. What is the right mix? How many results per page people want to see? You can't get it just by designing yourself actually. You need to push out, you need to experiment and see how much results people are expecting for this. Next to sustain, performance is a moving target. You cannot say that today you would do performance and get away with it and you won't have to do this later on. You cannot do once and forget. To sustain, you should have a performance team in your organization like we have. It's very important actually and the performance team actually evangelizes to all other developers about what could go wrong if you do not do this and you should always measure key performance metrics like your first byte, about the full load, DOM ready, window on load. You should be measuring this and keeping an eye on this very regularly. When each of these is breached, you should get an alert. You should use web test test in your content integration to make sure that someone checks in a new file or a new request. You know it and you know what impact it could have on your load times and how will it interfere with other requests. This is about it. Now little about the future. I mean the future of performance is prefetching actually and prefetching will give near instant loads to your web pages like your apps. Native apps are cheating prefetching actually. When you open a Flipkart mobile app, let's see what happens. The Flipkart mobile app is 8.5 MB for iOS. Tell a web developer that you could download 8.5 MB of data how happy he would be. With this 8.5 MB of data, the app could show splash screens, it could show initial place order content, it could show stale data, it could do a lot of things and the moment you open a web view, hit across a web view inside the app, all you see is this, a white page. I mean and the web view doesn't have any other info. All it could have at the most is that the DNS could be prefetched. That's it. It's zero bytes actually. I mean and this is where prefetching would help. Some foot foot thought for prefetching prefetch autosugist. Autosugist is something browsers heavily prefetched. The moment you type your address bar, type something in Chrome address bar, it goes in there and it prefetches the web page first result and you could even prefetch your next pages. If you know that the users are actually most likely to visit the next page of the results. Service workers, again it's very interesting API. It's very interesting W3C proposal. It's expected to replace your app cache and the way it would be is that the FBC itself would be offline. The JavaScript FBC that we write today will itself be on the browser cached. So the browser would know that how do I handle this URL? Do I have the resources to deliver it or not? Or if I do not have the resources, I could cache some resources and make sure I show something to the user and this was very recent again if you have been following hacker news, prefetching on hover and touch start because this starts very early on and people see near instant pages because of this. This is something we should all experiment with and that's it. I'm done with my talk. Time for questions now. In the first few slides you mentioned that Omniture and Google Analytics were beyond your control. What will happen if you load them after document load? After the content is loaded? We would lose some tracking calls. Our number of visits will be less or number of pages that will record will be less. That's why we have to make them early on. Is there any service that right now you're seeing that uses the performance API to give you an entire picture and so you guys wrote your own? Yeah, we wrote our own and because we didn't find anything like that and I mean this resource timing API is very new but I could see that a lot of these sites log normal and keynote they would enable this very soon. They should be enabling this very soon. Thank you. Anything else? Hello? Yeah. So you told about CSS JavaScript and all after the main critical thing loads right? Yes. So won't this affect the render cycles of the browser like you are injecting different HTML after the load. So each time it reflow the page it re-renders the page. Yes, it affects it sort of affects but again that you'll have to see that what is the benefit I'm getting out of it. You have two things that it could affect rendering performance but it could but if you're doing this you could flush out your above the full content very fast. So this is a trade off we have to take and what we do is that these elements that we load after page load we make sure we put them out of the flow by translate Z-hacks and sort of. So you were telling about the main menu right? Yes. So you told it's some kind of a template or something right? It's loaded after the HTML loads. No, it's not loaded after the server doesn't send the menu. The server sends the menu if the client doesn't have it once the client has the menu it sets the cookie that I have the menu don't send me back. Okay, so set in the server side. Yeah. Because menu is on the top of the screen it doesn't make sense to load it from bottom. Yeah, anything else? Hi, it's a continuation of the same question. I mean like this related to the sub menus which is you're storing it in the local storage. You mentioned the time frame is 10 minutes. I mean like is there any specific reason only for 10 minutes? When you could change, I mean our category is they keep updating the menus very often and we would not want 404s in there and generally the amount of like you would view you would view a lot of pages in 10 minutes and you would come back to the website and then again you would start your browsing. So it's like that just when once you're starting the browsing we would load a little slower but again after that for like few minutes your experience would be better. So you mean I mean like after 10 minutes I mean basically you keep on updating the menus in your website. Yes, it changes very frequently that's why we have to we cannot leave it for like half a day or a day. Anything else? So I'm available at this URL for any questions if you have after the talk. Thank you.