Improving React Native Performance in Facebook Marketplace - Konstantin Raev | JSConf Hawaii 2019

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
so my name is Constantine and I'll learn how to use this remote just another second so there are just three buttons I'll use my finger and I just press spacebar here so I work for Facebook on Marketplace team and I mostly focus on performance recently before joining marketplace in Seattle I worked in Facebook UK and I worked on yarn package manager anyone loves packages and before that I worked on react native so I'm a little bit biased towards what framework to choose when you build a mobile app so today I'm going to talk what I have been working on for the last year actually making Marketplace load faster just before we start anyone is familiar with react nice how about react native much less so this talk is I made it so that you could actually take it home some ideas how to make your application faster specifically react native but it also applies to react and actually if you think about it it applies to any other application so first of all what is marketplace anyone used marketplace before so it's a platform it's actually a tab inside Facebook application anyone knows about Facebook so it's a social network and there are tabs in it and marketplace is one of the tabs it's a place where you can buy and sell things to people in your community so marketplace started in 2016 and it took us to build to build the first version for iOS just six months and actually we tested it in Hawaii so it means that this stock sort of brings it back home then it took us just two months to build the Android version and this is actually quite rare for applications of this size in company of this this size because it's usually like six months iOS then another six months Android but because we reused JavaScript and 90% of the code was reused we were able to do it just in two months so what officially launched in October 2016 to mainland US and some other countries and now it's global and there are more than 800 million people using this application every month and marketplace is more than just buying and selling items to people around you it's also both buying a car finding a place to live some daily deals some business opportunities quite a lot the team is quite large it's more than 100 engineers working on the same react native code base so market will plays grew from 0 to 800 million in just about two years and the Tube team grew as well so we need to hire more people and we need to make the application nice to work with and react native played a big role in how to make a good developer experience so anyone is familiar with hot reloading anyone knows the difference between live reloading and hot reloading all right not everyone so live reloading is when you develop a website you change your code type something save it and then your browser or application refreshes with the latest code and you see the changes hot reloading is when you make your changes on your laptop like here make some code some code changes to my react component I press save and then it goes to the device and only the components that actually changed get re-rendered as usual react tree renders components at at its pleasure and this iteration is quite fast because I'm just changing code a little bit and here we go and another thing that you probably don't know at Facebook we don't like building the Facebook application will love the application but building it is not fun because it takes 30 minutes to have a new binary on your device because we have millions of files something good about react native as I mentioned 90% of the code or even more is written in JavaScript and we don't need to change the native code that often so what we can do is we can grab the latest binary from a build server install it on the device and then build the JavaScript file from the source code as a matter of fact we have integration with our IDE that just grabs this binary and does everything with just one single click another big deal is hiring people as I told you marketplace team has grown a lot to build a lot of features and at Facebook we have a joke that it's really hard to find Android developers because we already hired every Android developer who wanted to work for us so we we need a high incidentally there are more JavaScript developers around still hard to hire them but possible less than 5% of people working on marketplace are actually specializing in native platforms it doesn't mean that we don't use their skills we just leverage their ability to work on something complex platform specific all the other people are quite quick to adapt to their javascript code base and become quite proficient building features Repton react native are also very popular if you count github stars which I do periodically there it probably in top 10 frameworks on github by star count of course it doesn't matter but if you look at the number of contributors individual people who contribute to the codebase react native is one of the top projects and also it built a community around it what I'm saying is that when we hire people from outside to work on marketplace those people are very likely already familiar with our technology technology and it means that they can be productive straightaway so I just described react native a JavaScript framework that allowed us to grow the team fast but what about javascript and been building an application that works fast javascript has a lot of things that people people say that it's not good for performance it's garbage collected anyone else has ideas yes dynamic typing I'm just kidding I actually have it written here it has module system that's not really mature enough we have not different module system it's single threaded how do you build a UI when single threaded but thankfully we actually have a synchronous code and co-routines but anyway a lot of people are biased about javascript and there are reasons so Facebook occasionally surveys people who are using their applications and there is a direct correlation between how fast the application loads and how satisfied are people with the application and performance work that we did on marketplace in the last year shows that people engage more with the application if it loads faster for every hundred milliseconds there is a certain percent of improvement of how people engage with marketplace and I'm not talking about just looking at the screen and I'm going away I'm actually good I'm I'm actually meaning that it sticks to people if something loads fast so Facebook application leadership spend some time researching how fast the application should be for people to feel comfortable with it and in the last 40 years there have been a lot of researches and the consensus is that if the application if a computer system refreshes a screen within one second then people perceive that it's fast so that was the goal for all the tabs at Facebook how do we make them fast as in load within one second and on a slow device like this Samsung j5 prime which is not a nicest device that around but surprisingly it's one of the most popular devices in the world so we started with three and a half seconds for 75% of people load in marketplace and when we heard about the goal we thought well it's a bit humorous 70 % improvement are you serious a year passed and turns out they believed in us and they were serious so we are getting closer so what I'm going to talk next about is how we achieved that and I tried to focus on things that you people working on react and react native could actually bring it home and reuse it and even though many people hold JavaScript as a liability of react native I think it's on the contrary we have many years of experience optimizing websites and if you haven't seen this talk from ilya grigorik from six years ago pretty much everything applies to optimizing react native so similar to optimizing websites or any other application we start with measuring all different sub spans how things are loading then we find the slow things and we make a decision it is something that we really need at the startup that we call the critical path or is it something and if it is not let's just do it later and if it is let's do it in parallel with something else so what's another cool thing about JavaScript and ability to debug your applications is that JavaScript can run on many things and there is a feature called debug JavaScript remotely on react native and not a lot of people realize that it's actually sending the JavaScript application of react native to the browser it executes their full application builds the component tree and then sends signal to the device telling what needs to be rendered in the native code so full JavaScript is for real running in the browser and it means that we have access to the development tools that are coming with the browsers for example in Chrome I can click performance tab I can click record and get some samples and then it has a very good integration with react and react native is running react.js inside it so we actually have a very nice flame chart of all the components that are loading and we can see which components are slow or which component are unnecessary and we can make some assumptions like let's let's not have this component or let's let's optimize that first now you have to take this with a grain of salt because we're running this on a desktop browser on your powerful MacBook probably and it's a v8 JavaScript engine on a real device it will be a JavaScript core that runs on Android and iOS and it's completely different picture but if you really want to have the same flame chart there is a tool called systrace that just collects the traces and it integrates with react native and you can see how your components work on a real device so measuring performance is actually an art we could be talking have a separate talk about how to measure performance on a group of people on a large group of people how about the distributions between different people what kind of category of devices exists but I think the first two tools that I showed you could be a good start how to start improving your performance so now let's actually look at what things helped us to improve react native so this one is an obvious one I'm pretty sure everyone who is running a mobile application should be running their network requests in parallel when things are loading because you're doing stuff on the server and stuff on the client they shouldn't be interconnected however there is a caveat I know some people are using graph girl here who likes graph you'll yeah so with mobile and graph QL and JavaScript there is a caveat because usually people using react native they use JavaScript implementation of graph queue for those who don't know what graph QL is it's a it's a concept that allows your components to define what they need and it means that the query for the data is based on the components so you need a graphical engine that would inspect your components build a query and then send this query and if it is in JavaScript you see the blue line we need to start up JavaScript VM we need to start up react native we need to start the bundle we need to find the graph QL JavaScript implementation and then send the request what we should be doing is running it in parallel so if you are using react native or a very similar framework and the graph QL you should the question how can I make the request in parallel at Facebook we have a very thin layer implemented in native code that is capable of sending the request from Java or from Objective C that's how we achieve that also I brought you some good news if you update to latest react native you will know that it has the latest JavaScript core engine for those who don't know JavaScript core is the JavaScript engine that react native is using the problem is that it hasn't been updated for two years and it has been 32 bits and now we have the latest one that's 64 bits it's not only good for library compatibility but also it comes with two years of optimizations and performance tweaks it's one of the easiest things that that you can actually do to improve your reg native performance oh this one is really cool but legal department didn't allow me to mention anything about it just imagine unicorns exploding with jelly beans moving on now let's talk about what we can do to the JavaScript bundle by default all react native surfaces in our application are compiled in one JavaScript file this is a very common technique anyone using webpack pretty much everyone so it compiles all the JavaScript in one javascript file it gets zipped and sent over the network to the device with react native it's a little bit different we want to optimize it differently the problem is that this JavaScript on react native is actually part of the application and if we want to load any react native screen we need to read this file and if it's large like sex may six megabytes or maybe 20 megabytes it's quite heavy for IO it will take time to load so ideally we want to split it into two like webpack can do you can have a very small javascript bundle for the your initial screen and then you can load other things later for example unclick or maybe it's a different surface now the trick is that actually for react native we don't need to do that there is a feature called Ram bundles it's a fancy name means random access memory but what it actually does it compels every JavaScript module is its own file and puts it in the application so we when you start up your application you only read the modules that are required in your initial startup path and it means that you only pay I owe only for the modules that you need now talking about requires and imports let's imagine we have a very heavy component like I even called it very expensive and let's say it does something nasty not just this console log that indicates that's something I still like it it mines a Bitcoin for you now you want to use this component but you know that it mines a bit going so it's very slow so what you do when you use it on line 20 you say hey don't load this very expensive component before I make a click there's a conditional for the state but you didn't know that import is actually eagerly loading and it means when we have on line 3 import very expensive component you actually get a bit Co in mind we don't want global code executed during our startup time so what we can do is change the import into the old common GS require that allows you to import files within the functions so we define a new variable called lead very expensive it's undefined by default and then on the key press we say require this module and then it becomes available as a as something to render now obviously you don't want to do it for everything in your application so thankfully react native packager that's called Metro bundler has this setting that automatically translates all your imports into these require statements so you can write idiomatic JavaScript but it's smart enough to find that components are not used during the startup it converts them into require statements and you don't pay the extra thing so we talked about what things you can do with your configurations and then other people built parts of your application build frameworks for you and you can just tweak some knobs and get it work faster now let's talk about what you can do to your production code so you can find a lot of information on the web about optimizing react components the gist of it is we don't want to call render function multiple times for your component and react is very generous about cold in render because it's supposed to be fast however if it's critical for you to don't call extra extra extra times the component then you you can do some tricks so here is a common way of how we can avoid it this component implemented should component update function the idea is if it returns true then the render function will be called and if it returns false react will trust you that this component shouldn't be rendered in this case we look at the property color and we say only update this component only rerender this component when color changes this this concept is very popular so there is a pure component in react what it does it matically implements should component update for you and only calls rerender when a prop changes and I'd like to finish my talk on a point that focusing on perception can give you more results than actually grinding the components here is what I mean by default react built a component tree depth first so we have some top component and it goes down down down to the most inner component in it then goes up up up by the stack then goes again and it kind of builds the whole tree now react fiber is coming to react native soon but for now we don't have this way to prioritize things how to load them so for example in marketplace we can decide that hey user content is more important than a fancy navigation at the top and we could save 50 milliseconds by just delaying the navigation the header and show the components the user content that people could engage with here is how you can do it with react native so you can define that alright this header is very expensive I don't want to have to render it from the first go but how do I know that it got rendered at all because components are built in JavaScript and code is rendered in the native that and there is some communication between those threads but they are completely independent you cannot just say wait 400 milliseconds and then render the header because a hundred milliseconds on a slow device may pass and you start rendering the header before anything rendered on the screen so you slow it down but we have a trick for example I created a little view component on line 23 and it has an own layout callback this view is actually invisible but react native still renders it when we have this view rendered we know that hey something this component already was rendered by the native code so we can do things that we wanted to delay so it has the only out callback that goes to line seven and that's when we change the state of the component and say hey I render other things now as a matter of fact in marketplace this was one of the most common things that we have been doing reg native application is just one large component that goes into more smaller components and in marketplace we were saying alright this looks like a heavy component let's delay it the problem is that we have a large team and a lot of features so these components started piling up and of course we started delaying them but there are a lot of layers a lot of things that javascript has still to go through and when we measure when we measure this this just didn't sit with me right right we spent 500 milliseconds on a slow device to render this screen because we have flat list we have many things we still delay them but we can delay everything because the code will be really hard to read but really I can implement this thing from scratch and it would run under 200 milliseconds because it's just four images I can just do a view and put images in there so we thought about it and we implemented this we decided to do a little trick so we implement the light one and then destroy it and render the full view with all the flag stars and craft and of course this is not shippable this is a terrible experience because it blinks but not everyone knows that react native has a very good animation library that allows you to run an animation when a component is destroyed so for a couple of weeks we tested a few ideas and this is what we settle to it we render the light view with the runs within 200 milliseconds in the background we build the full view with all the crafts that takes 500 millisecond then we destroy the light one and we animate in with a fade out into the thing that's already in the background this way we have quite indistinguishable change but at the same time the light view is already clickable and people can engage with the application much sooner so lets me summarize what I talked about today Market Place is on a great trajectory and keeps growing react native is one of the tools to satisfy the product growth needs and we can use our experience from the web from optimizing all those websites for many years and apply it to react native and in general mobile J's on mobile that's all you
Info
Channel: JSConf
Views: 6,158
Rating: undefined out of 5
Keywords: React, React Native, JavaScript, Facebook Marketplace, Software Engineering, JSConfHI
Id: g3jwd0kAIDU
Channel Id: undefined
Length: 26min 6sec (1566 seconds)
Published: Mon Jun 24 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.