[Applause]
hey everybody I'm Taylor thanks so much
for the introduction Paul and today
we're going to talk about JavaScript's
performance in extreme environments
through the lens of our production web
app for refugee aid groups so start off
with some background on the aid movement
look at those extreme environments
setting performance goals is always a
great place to start when diving into
this stuff and outlining a strategy and
then look at the tools and techniques we
use to improve performance in our own
app this is my first-ever Tech Talk both
as an attendee and a speaker so I really
and I just want to emphasize like I'm
nothing special I'm just like an average
web dev I needed to do this to make our
stuff work in the field but to take away
from that is that you can do this too
you don't have to be an expert it's not
using some really advanced API or
anything so hopefully on Monday you can
go in take a look at some performance in
your own apps maybe do some improvements
who knows cool so the refugee movement
is one of the largest grassroots you
know volunteer-driven things in the
world
it has had tens of thousands of
volunteers working with hundreds of
grassroots aid groups welcomed millions
of newcomers to Europe it's kind of this
interesting network of distributed
autonomous groups they each do their own
part independently which means they can
respond really quickly to changing
conditions or new needs that governments
or larger multinational NGOs can't but
there's lots of communication overhead
and lots of in efficiencies around these
administrative processes so it's a
diverse movement it's led by women you
can see our board there on the left is
Stephanie who's a admin at movement on
the ground we'll be talking about some
of their work on the island of Lesbos
later the middle is our own director
Sarah say hi if you see her around the
conference
and on the right is Regina who has
started an aid group that takes donated
laptops and equipment loads educational
content on them and sends them to
informal schools in camps so I think
it's really cool to see women at the
forefront of this movement and this is
something that's not going to be solved
within our lifetimes there's 70 million
displaced people in the world today 20
million of them are refugees in another
country and due to climate change we're
looking at up to 1 billion displaced
people in the world by 2050 so this is
something that we need to pay attention
to now we need to build the
infrastructure for now and I'm really
grateful to indigenous people all over
the world and our youth like Greta who
are fighting you know to reduce the
impact of climate change so a little
overview of our tech leave three main
areas of our platform there's kind of
discovery and networking
there's the aid supply chain so tools
around getting things from A to B and
there's the knowledge sharing section to
help you know share knowledge things
like that so our goal is to increase
collaboration save time and help groups
make smarter better decisions really by
just surfacing more information in a
centralized place and then easy to
consume and structured way but the
important thing is that our tech
empowers groups which means if they
can't use it if it doesn't work where
they're at then what are we doing right
so yeah it were free as in freedom and
beer best of both worlds right we're
using the a GPL and we're nonprofit so
it's free for aid groups and this is
going to be important when we talk about
testing strategies and stuff I'm the
only full-time dev on our team we have a
great team of remote volunteers so we
need to approach kind of performance
testing through the lens of a scrappy
you know the volunteer-driven nonprofit
not through like a million dollar lab or
something that you can just have a bunch
of boxes like automate all of this away
cool just a couple of slides here about
our tech that's the profile this is the
aid marketplace the the inventory
manager or you can see what's available
and what people need and then we have
the shipment coordinator helps you keep
track of decisions that you make where
things are going and this is great cuz
it it shows you hey the town next door
is sending the shipment I can just throw
some stuff on there and they can include
it rather than sending another one
myself
cool so the impact in the real world we
coordinated a shipment of a hundred and
eighty thousand bars of soap from
Glasgow to caring City in Scotland it
went to central warehouses in Athens and
Thessaloniki and they distributed it to
dozens of aid groups all over Greece
including the islands and most
importantly the end result we get this
to the people who need it most so that
was kind of the intro section I'm glad
I'm doing well on time and now we're
gonna take a look at some of the extreme
environments that our users operate in
okay maybe not that extreme so this is
Moria
it's the largest refugee camp in Europe
it's on the remote and Greek island of
Lesbos right next to the Turkish border
it's a former prison designed to hold
2,000 inmates and that's the kind of
prison section right there
there are currently 10,000 newcomers
living in the Moria refugee camp and you
can see the massive overflow area and
kind of an informal camp in the four
grounds there that's called the olive
grove so this is the kind of border
outside Moria surrounded by barbed wire
and this is what you see every day as an
aid worker you're going into camp you're
doing all sorts of things to help people
out 10 to 12 hours a day it's like an
all-day thing you don't get a lot of
time to rest relax you don't get a lot
of time to go back to the office and
jump on the Wi-Fi or charge your phone
up as you can see there's not really any
power infrastructure there the cell
signal is spotty
and so we have to take all of this into
account when we're trying to figure out
how to make our app work for for the aid
workers so we don't operate here but
there's a little bit of interesting like
other extreme environments you have
search and rescue ships at sea who are
on the ocean for months at a time and
you have human rights like observers who
are on borders this is a photo of the
Hungarian Serbian border which has 500
kilometers of razor wire and so the
human rights observers are going to be
out in remote parts of the country
remote villages I'm kind of monitoring
for things like border pushback stuff
like that and last but not least my
favorite place which is warehouses so
this is really cool that warehouse was
actually the old 2003 Olympic basketball
Stadium in Greece like just a ton of fun
to walk around and explore and aid
groups really like they just popped up
overnight they asked the government hey
can we have some space and they have to
work with what they're given so it's not
something where they can design a
connected infrastructure set up the
Wi-Fi through the whole thing you know
it's like here's a shed in my backyard
here's a converted basketball Stadium
you know make it work so the storage
space there is in the ring in kind of
that concession area you know outside of
the main stadium and that's what it
looks like inside there so they have
self-service don't have Wi-Fi they do
have power but again people are dealing
with inventory and stuff all day every
day
so let's actually take a look at what we
mean when we're talking about
performance high speed situations this
is Amsterdam this is the office in San
Francisco low speed might be my own
office in Serbia you know gets the job
done sometimes the video calls are a bit
flaky but it's okay no speed there are
lots of situations we talked about some
of them like at sea on the borders and
then we have this fun one I like to call
maybe speed so this is really where
house is this is camps you might have
some cell signal you might have
and Wi-Fi there will be dead zones and
that produces a lot of problems it's not
just online offline online its
ping-ponging you back and forth so you
have random latency spikes race
conditions are a huge issue and the from
a UI standpoint you have to deal with
this back and forth between the
different states you don't want to just
be showing up the pop-up your online
your offline your online very rapid
succession so when we're talking about
speed we're really talking about latency
bandwidth and throughput that's an
example of a warehouse so that's the
office with the Wi-Fi there this is
about the size of the football field as
you can see that Wi-Fi is not going to
extend throughout the whole place it's
kind of like a giant Faraday cage and
then this is a fun one so to get Wi-Fi
in the olive grove which is that
overflow area outside of Moria this is
the town of MIT's aleady it's the
largest town in the islands they send
they have a satellite dish or something
that sends it to a water tower another
satellite dish there bounces it off to
the camp that's about 4 kilometers right
there just beaming that off a water
tower
it goes into a satellite dish on the the
the office there and then they have a
series of Wi-Fi repeaters around the
camp
so clearly dealing with super high
latency they're intermittent
connectivity
you know storm or something like can
just knock out that infrastructure
there's the office right there
and that's an example of a telephone
pole with one of the Wi-Fi routers or
the repeaters on it so something else we
need to consider is data and power so
you have like unmetered Wi-Fi you have
mobile data or you just don't have data
same thing with power you plugged into
the wall you're on the go or your
devices debt and these are all resources
that our users have in our context
they're very limited you're out and
about using your phone using our app all
day long we can't kill that battery
right you know you have a certain amount
of time
then your phone's dead and then you're
back to pit the old pen-and-paper way
same thing with data you know it's it's
nice when you have an unlimited plan
most aid workers that I know they might
buy one or two gigabytes at a time so
they're constantly having like running
out of data having to wait a day go back
to the cell phone store plug some more
data in and if your stuff just stops
working
when they run out of data again back to
the pen and paper way it's a bug it's my
problem you know it's it's their size
they're not gonna make it their problem
and then we have hardware so lots of old
donated equipment I'm gonna speed up a
little bit to make sure I stay on time
but this is an example with my friends
computer it just doesn't have a battery
right like she just leaves it plugged
into the wall if there's a gentle breeze
that knocks the cable out then she
immediately you know loses all her state
of what she's been working on it's my
friend's phone different friends he
can't use about half his screen so I
think that's maybe a different tech talk
like how to make your app work with a
busted phone but that's the type of
equipment that we're dealing with here
this is all more relevant than you might
think
right so a slow connection is a slow
connection where houses have dead zones
offices have dead zones there's some
poor guy in the basement you know trying
to just get the printer to work and yes
run up and down the stairs every time he
wants to print something they connect to
the Wi-Fi if you don't have a connection
you don't have a connection it doesn't
matter if you're in the middle of a
refugee camp or if you're on a six-hour
plane to come talk you know at ge'ez con
free to past a dead battery is a dead
battery regardless of how fancy your
phone is and old hardware exists in many
real-world businesses hospitals are a
great example where due to budget or
regulations they're running sometimes
internet explorer in 2019 right so let's
take a look at some performance goals
and you want to start here really
important when you have these
conversations with your managers you
know everyone the marketing department
the DevOps people they want their stuff
included
in that page-load and so you need to be
realistic and set those goals which will
then help you prioritize what's
necessary what can you cut what can you
delay so in our case we're looking at a
mid-range Android device on we're gonna
say a bad 3G connection 400 kilobytes a
second bandwidth and 400 milliseconds
latency we want to minimize data and
power usage and we're gonna focus for
speed on two key indicators there's time
to first paint and time to interactive
so we want on an initial load less than
two seconds to first paint and
subsequent loads less than one second
and for interactivity we want less than
five seconds on an initial load and less
than two seconds after that and remember
that latency here is the killer so
that's going to take up you know easily
twenty to forty percent just ping the
server for a roundtrip we have product
goals
hopefully we're building stuff to do
useful things whether that's relax and
have fun or you know make something that
people want to use in our case we try to
support modern browsers on desktop and
mobile we're not supporting Internet
Explorer and we need it to work offline
so it's ok we can cut some content on
functionality like our Maps page we need
to get tiles from a server if you're
offline we're just gonna say you know
don't use the maps wait until you
connect but there's lots of other stuff
that that doesn't need to work and I
think that ok so business goals no
ultimatums I think that performance is
something you should take an incremental
approach to you know make one
performance change at a time something
is better than nothing
build an offline support one step at a
time starting with the most used or most
impactful workflows in our case we need
reasonable testing overhead like I said
it's a volunteer team so we have to kind
of keep that in mind we're not gonna
have you know if you budget for extra
or lab and we need to balance you know
this sort of performance testing with
new feature development adding on there
and I think that one of the best things
you can do is if you're talking to your
users talk to them about performance
right it's you know you have your
product and application bugs and stuff
like that but tell them listen if it
takes too long to load and that makes
you frustrated that's a bug like talk to
me tell me about that I want to know
what device you're using what the the
connection was like go to speedtest.net
and send me a copy of the results so
that I can have realistic benchmarks you
know when we're doing our internal
testing I think that we have lots of
great conversations with users we should
definitely extend that to performance so
I'm gonna dive in here and look at our
strategy to make these improvements look
at the tools that we're using and look
at the techniques and results that we
had in our production application so our
stack I can hear the groans already yes
we're using jQuery in production in 2019
I think 2009 called and they want their
developer back so it's pretty modern on
the back ends we have elixir and phonics
I'm sitting behind an engines proxy we
used web back of course to kind of
bundle up all of our front-end assets
the reason for jQuery is that I love the
data tables plug-in and when you're
prototyping none of this matters right
we're going to be cutting that out and
probably go with no framework on the
front ends but this is good in this case
raise your hand if you're building a
single page application view react it's
a lot of hands so we're not I'm gonna
have some stuff that touches on
performance considerations with single
page applications but just in terms of
the numbers I'm showing on screen jQuery
is kind of halfway between you and react
in terms of in terms of like library
size so some realistic numbers there
so let's look at how our usage what's
really going to drain that device
battery it's gonna be two things it's
gonna be the antenna and it's going to
be running that CPU or on the laptop the
GPU and stuff like that so how to
minimize antennas just minimizing
networking right batch requests if
you're sending telemetry or something
you know if you could if you could batch
those collect all the data every 50
milliseconds or whatever you want but
only send it up to the server once a
second or once every 10 seconds or on
the next load we don't want to use
polling because that's going to send a
heartbeat out so there's some great tech
out there like WebSockets which do a
much better job of keeping a TCP
connection open without that heartbeat
we want to limit animations as much as
possible every time that you have an
animation going it's going to be
repainting on the browser running that
CPU and I'll show you some performance
stats on that in just a minute
sinking timers is important as well if
you have like 10 different timers
going off that aren't synchronized
that's gonna wake the CPU up every time
if you have something that you know 50
millisecond interval and then every
third time it goes off you run some
other function and synchronize it that
way it's a much better strategy and for
common events like the scroll events or
you know whenever a user types on the
keyboard things that are gonna fire a
lot like that you want to use timeouts
and just kind of take samples of them
rather than responding to every single
one so we're using the chrome dev tools
this is the network panel this is
Google's homepage and every time you
type in a character it makes another
Network request so this is what I'm
talking about with those events with
that networking this is going to keep
the antenna on your phone on that whole
time it's okay I think when you're
looking at really optimizing performance
this is great on a desktop but it's fine
to just let the use our type in their
search query and hit the search button
and make it
single requests up or to do it once a
second or once every half second this is
I've loaded up some page with like a
spinning loading animation on there and
this is what it looks like using
Chrome's dev tools performance panel you
can see all of that activity all of that
repainting constantly which is going to
run that CPU and drain that battery so
another strategy is minimizing a data
usage this is just small bundles is
really the answer and aggressive caching
you want to compress your payloads you
need to cache everything you can load
content as needed which means if you
don't need it up front just grab it in
the background if it's not on that you
know above the fold then load it as the
user Scrolls down if they scroll down
there's oftentimes they're just gonna
click a link on the main menu and then
never need that second half of the page
and then I think for pre-caching with a
serviceworker or something like that you
want to get your app working offline ask
for consent just a simple button like
hey would you like to download the
offline experience I think it's
important when you're looking at people
with low data like they're on a limited
metered plan to just give them a heads
up it's the white thing to do and then
improving speed a lot of the same thing
you need to compress payloads cache a
guest of Lee server-side rendering is
super useful here that's really going to
reduce the amount of time it takes to
get to that first paint which means if
you're building a single page
application you do need to do a little
bit of extra work and actually send down
some HTML at least send down an
application shell send down the the
header and the footer and a sidebar and
you know maybe a little loading message
or something to just get something on
the screen and then once your JavaScript
loads and pulls in the rest of the
content and compiles the templates it'll
it'll fill out the rest of the
experience
so images are going to delay
interactivity it'll-it'll show useful
stuff on the the browser right away but
it's not going to run the JavaScript
until after the images are loading so we
try to delay that as much as possible
there's also in limited bandwidth
situations you can be pulling multiple
things from the network at the same time
but if your pipes are really small like
trying to send it to the refugee camp
then you don't want your JavaScript
download to be competing with a bunch of
user uploaded images and minimizing the
amount of stuff on the critical path is
definitely a good technique especially
for single page applications you don't
need all of your templates at once load
the current template load the
interactivity above the fold and then
asynchronously grab the rest of that
once the page is up and running so we're
gonna be taking a look now at our groups
list page this has static content
static sections of the site user
uploaded text and images and some
JavaScript functionality you can sort
the table by name you can do a search
and we're using really for tools like
keeping it simple for our team is chrome
dev tools Network and performance panels
there is some setup here so to simulate
a bad 3G connection we're slowing down
the CPU as much as dev tools will allow
and we're putting in a custom network
throttling profile so remember it's 400
milliseconds latency and a 400 kilobyte
a second connection and we're gonna take
a look at a baseline this was our app
two weeks ago we already do have some
goodies so because we're doing a
server-side rendering model with onyx
and elixir that's there what pack
already does some minimization for us
and Phonics has built-in cache busting
raise your hand if you know what cache
busting is okay 50/50 so basically what
you do you compile your ass
and generate a hash of the file and
you're actually gonna serve up a file
with like you know app - the hash j/s
what this means is that you can send
your your caching headers right just
tell the browser to hold on to that
forever they never need to load it again
from your server as long as they have a
local copy when you make a change in
your application it generates a new hash
and you actually just download a
different file which is I think a pretty
good way of dealing with caching and
just trying to hold on to that data as
long as it's needed so likes this is our
initial load time it took five seconds
on our simulated connection to to paint
the page it took 22 seconds to become
interactive and we downloaded basically
a megabyte of content this seems really
bad it is a bad 3G connection in 2017
this was the average load time for
mobile there's 22 seconds to to just
grab a page so I think we can do better
than that this is the performance pane
and dev tools you see really long load
times grabbing that javascript file to
get to interactivity even just grabbing
the images and the HTML took quite a
while so secondary loads are better we
can take advantage of browser caching
takes about a second to paint the page
and become interactive and because we're
using cache busting we're just grabbing
the updated content so it's just the
HTML file this might be something with a
single page application it's cached all
your JavaScript and you just have to
make a JSON request or something like
that so you can see there it's it's
loading
just about everything compassion for the
HTML page so we're gonna focus on some
speed improvements here we didn't I
thought that we had gzip going it turns
out I got a configuration file wrong and
we do
at all so I did some research and I
threw on broadly it's basically the new
gzip it has about a 25% smaller file
sizes when the compression is done
I added HTTP to two engines which
multiplex requests it can reuse TCP
connections which means you don't have
to deal with that latency for every
single pipe that you have open you just
open up a handful of them at the start
and then you can load up more stuff and
through those pipes I implemented a
fairly simple bundle splitting strategy
in web pack and so I think that there we
could do even more here but for now I
just wanted to separate our application
code and styles from our vendor code and
styles because the libraries and stuff
we use don't change nearly as often as
updates to our actual business logic and
in front-end code this will allow me to
cache that vendor file and just keep it
there for weeks at a time until we throw
in the new import while we're making
daily changes to the application yeah
some image resizing just cutting down
take a look like you're throwing on fun
awesome or something you don't need a
thousand icons you're probably just
using 50 in your app double check that
and lazy load user-generated images you
can grab them after you get
interactivity so we hit our goals with
these improvements alone we got it down
to just under two seconds to first paint
four and a half seconds to interactive
and really cut down on the amount of
data we're transferring and the the
overall size there so just with some
like simple improvements a couple of
server configurations lazy loading the
images and doing some bundle splitting
with web pack we see you know over sixty
percent performance improvement in the
metrics that matter you can see here
that that side that's those images that
were lazy loading so the paint happens
really quickly we're reusing a lot of
the you know same TCP connections with
HTTP to it gets to
activity and then we just grab the rest
of that user content subsequent loads
similar source of improvement we're down
to under a second on a bad connection
for first paint and interactivity and
we're only serving up 2.6 kilobytes just
the updated content on the page so I got
one minute and I'm just gonna touch on
serviceworkers really quickly here our
basic strategy we want to cache all the
static assets on install and serve them
with a cache first approach so this is
where cache busting comes in really
useful is that if you have that file
there just serve it up no need to go to
the network if you don't then fall back
to the network grab it cache it for next
time and then for the pages because
those might be updated with
user-generated content we want to do a
network first approach but keep them
cached so grab them from the network
grab the latest copy if you go offline
be able to serve that copy from your
cache so we're using service workers
we're using the cache API yeah and it
gets really fast so this is with online
we have half a second to interactivity
and most of that is a 400 millisecond
latency to to grab the updated HTML page
and that's what we see here so it's just
grabbing that stuff and then loading
everything from cache what's really
interesting is that offline is actually
the best performance because we don't
have that latency we don't have to hit
the network up it just loads the the
last version of everything we cached a
hundred milliseconds to get there in one
hundred and fifty know day to day
transferred so once we kind of wrap this
up you know make a couple more touch-ups
to our service workers I'm just gonna
tell aid workers in the field hit
airplane mode like download the latest
copy in the morning hit airplane mode do
your work all day on hit airplane mode
and and upload it at the end of the day
cool so thank you so much that's kind of
my talk I hoped it served as like a good
overview
of performance optimizations you can
make and JavaScript and a little bit
about the refugee aid movement you can
check out the offline functionality on
our app all the code is publicly
available on github and I'll be throwing
the slides up along with some links to
further research and tutorials on our
Twitter cool enjoy your lunch
[Applause]