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