Tip:
Highlight text to annotate it
X
EMCEE: It's Colt McAnlis, everyone.
COLT MCANLIS: Hello.
Good crowd today.
Are we on the videos up here?
No?
I'm going to stand awkwardly live on the internet
for awhile.
How about that?
There we go.
Fantastic.
Hey, guys, really quick, big round
of applause for Jake and Paul for emceeing this thing.
Right?
[APPLAUSE]
COLT MCANLIS: It's not every day you
get charismatic people able to keep a crowd entertained
while the rest of us babble on about
technical matters all day.
I am Colt McAnlis.
Hopefully my bald attenuation comes before me.
By the way, really quick before we talk,
because this is sort of the first talk
I've done since the pirate talk.
How many people have seen my pirate talk?
A round of applause.
The people on the screen can't hear you.
[APPLAUSE]
COLT MCANLIS: Yeah.
That's it.
So the reason I ask that is I've been approached by like six
people today, like, hey what are you doing today?
Is today National Speak Like a Carny Day or something?
What do you do?
And I have to tell you the story.
After the pirate talk, there was a serious memo
sent between my managers, like, he's not
going to do something crazy at Dev Summit, is he?
They were checking the schedule, like, no, no.
It's just National Hello Day.
He can't screw that up.
[LAUGHTER]
COLT MCANLIS: Hey, guys, thanks for your time today.
Thanks for listening so far.
I know that lunch is on the horizon.
I'm going to try to keep you entertained for the next 30
minutes here.
Really, #PERFMATTERS.
Yes?
A round of applause for #PERFMATTERS.
You follow this?
You use this?
[APPLAUSE]
COLT MCANLIS: It was a little weird
having Linus come up here and be like, perf is everything.
And I'm like, oh crap.
I didn't work on my slides that well.
So hopefully today we can move through it.
I've said this before.
I'll say this a million times.
Today we're going to be talking about tooling techniques
for the performance ninja.
If you see anything that inspires you,
any fact, any statistic you didn't know,
go to your social media outlet of choice,
put #PERFMATTERS on it, send it out today.
Keep the discussion going.
A year ago, think about a year ago.
We didn't even have mobile performance tooling.
That wasn't a thing.
And in a year, we've actually sort of built
this community of angry, angry web developers
who want better performance on the web.
And really, that's what today is about.
Because I think we can all agree that mobile
is all that matters right now.
If you're not spending 90% of your time optimizing
your mobile website for the next five billion humans
that are going to be coming on the web,
you're kind of wasting your time.
So let's all just come together [INHALING SOUND]
big, deep breath in, my website is slow on mobile.
I accept it.
Come on.
Everyone say it.
No?
Nobody?
OK.
That's fine.
[LAUGHTER]
COLT MCANLIS: That's right.
Self-denial.
It's a step.
You'll get there.
Don't worry.
It took me a little time.
I lost my hair, it comes through.
Really, mobile is all that matters.
And performance hasn't been good on mobile,
and I think we all need to be very blunt about that.
And I think one of the reasons is this.
I love this quote by Ilya.
He said this in a blog post a while ago--
"What you can measure, you can optimize."
And this is really sort of a telling thing.
Because if you think about it, we really
haven't had the ability to measure anything
in the mobile web.
Again, this time last year we didn't
have the concept of being able to get
data of a web page running on a mobile device.
But thankfully, today, with the help
of ADB extension and Chrome DevTools,
we actually have the ability to load a website
on a mobile device and actually get the information back
into Chrome DevTools.
So you can get the same power of your debugging on your desktop
and actually see the performance characteristics.
Now this is good and bad.
It's good because you have this power.
It's bad that everyone's starting to know about this.
So if your website is slow, there's no more excuses.
Sorry.
I actually had someone come to my desk one day
and they're like, wait a minute.
Wait a minute.
We have this power, so why are websites still slow?
It's the internet, buddy.
So once you get the ability to actually go
through this process and actually get
these powerful tools giving you the information that you need,
it's worth pointing out that that's not enough.
So for those of you who aren't versed in this repetitive
loop of performance optimization,
you need to understand that there's
three steps, three steps to performance tooling.
And it starts at the basic form, which is go get data.
If someone says, hey it's slow, you've got go figure out why.
So you have to go use DevTools, collect as much information,
and this usually ends up being some sort
of huge sheet of floating point numbers.
And this actually goes into stage two.
A huge sheet of floating point numbers really kind of sucks.
No one wants that, because it doesn't tell you anything.
This goes into the number two, which
is you have to gather insight from that sheet of numbers.
You have to figure out, wait a minute.
We're seeing all of these waterfall characteristics,
and it's pointing at this piece of data over here.
That's the insight.
Our site is slow because we have too many megabytes on the wire.
That's causing six-second load times.
That's why we're about to go bankrupt.
Woe is me.
Of course, these are the easy parts.
Chrome DevTools can really help you
get far enough along in this.
And the really hard part is stage three.
And anyone in here who's dealt with this
realizes that the third one, which is action,
is the hard part.
This is where you take all the numbers and all the insight
and you go, wait a minute.
It's because we have this five-megabyte GIF animating
on our main page that we can't do this.
And you have to go over to the designers and the artists
and you say, I need this removed.
And they go, nope.
A round of applause if that's happened to you.
Yeah?
[APPLAUSE]
COLT MCANLIS; See, I've to keep you guys awake
before lunch gets here.
One guy in the back is like, sandwiches!
This is really the tough part.
And probably the most important part of this loop,
though, is actually repeating it.
More times than, not what you're going to find
is that your website does not have a single performance
problem, but it has a plethora of performance problems.
Uncovering one perf problem and fixing it is not enough,
because chances are it was hiding something else.
And once you've unturned that stone,
you realize, oh wait a minute.
We've got an even bigger problem that we need to fight below it.
Now once you sort of realize that you're
going to have to continually go through this process of gather,
insight, action, repeat, gather, insight, action,
you start getting a sense that the world is not that easy.
And what we're going to talk about today
is only the gather and insight parts.
You can go argue the action parts with your web designers
later.
So when you're doing this, you need
to come to the understanding that there's
no longer a single pillar of web performance.
Up until now, we've really been talking
about networking, load time.
This has been the currency that we've all
traded amongst our web developer brethren
as the metric of performance on our sites.
Hey, dude, how fast does your website load?
Dude, two seconds, dude.
High five. [HIGH FIVING SOUND]
Anybody do that?
No one?
OK.
Maybe I'm in the wrong room.
OK.
But really what we've been seeing
is how web apps have developed, and the need,
and what users have demanded from our web applications
have brought these other two.
The next one is render.
Linus stood on stage today and said that.
Rendering is a performance problem on mobile right now,
and we need to fix that.
And guess what?
Now we finally have tools that allow you as the developer
to take control of your rendering performance,
figure out the problems that actually address them.
And then, of course, the final one
is compute, network, render, and compute.
Compute has been one of the brethren of network over time.
JavaScript performance, you see it over and over again.
Nowadays, VMs are so fast and so powerful,
you generally don't see that.
Of course, once you put it on a mobile device
and you get slower compute speed,
you may run into some problems.
So I generally hate doing this.
I hate standing on stage, and I hate
telling you, go fix these three things.
But today I'm going to make an exception, because I'm
particularly bald and angry today,
and I figure I can get away with stuff when I do that.
So here is your hit list.
We like to joke in the Perf Squad that there's a hit list.
Like if we had a performance assassin on your team
and he needed to take out three things, these would be it.
So under the networking list, you
should be optimizing critical path.
And I know this is the tip of the iceberg question.
We'll get into that in a minute.
For the render list, reduce your number of paints.
And for compute, reduce JavaScript execution time.
These are the things.
If you come away with nothing from this talk
other than that angry bald man yells loudly,
come away with these three things.
This is where you need to focus your performance time.
Now what we're going to do for the rest of the talk
here is we're going to talk a little bit about where
these things come from and how we
can dive in to diagnose them.
So let's start with network, load time.
Again, this is where we've been.
Unfortunately, "load time" is a really bad, bad term.
Measuring your performance of your network speed
by a load time is like measuring your cholesterol
by how many doughnuts you ate today.
It's an insanely complex procedure
with many dependent parts working together.
This is just one spec for timing on just getting data
off the wire.
It doesn't even talk about rendering or anything else.
So we actually have to change our vocabulary a little bit
here.
And we could actually probably use
a better term, which is "critical path."
So it's not just about loading.
It's about what pixels are needed to get to the screen.
So basically you have a mobile device,
and it's kind of waiting around.
The user types in some information.
That goes sent off into the intertubules,
amongst all the cats and everything else out there,
and it requests a site.
The site, of course, is then going
to return some sort of markup form.
Now what's going to happen here is that your page says, cool.
I've got HTML.
Let me go start parsing all this stuff
so that I can start painting.
Unfortunately, the web isn't that way anymore.
All the content isn't just contained in your HTML.
It's actually a complex dance of other resources.
And so we can't actually build our HTML
to start rendering yet.
Instead, we have to wait for all of these other dependencies
to get resolved.
This is the critical path.
If you haven't heard this term before,
this is the critical path.
It's the resolution of the dependencies of your assets
to get the first pixel on your screen.
Because if you have JavaScript that you're
loading that's going to affect how the DOM exists
or the CSS classes, that's got to be present.
If you've got 50 CSS classes, that's got to be present.
So this is what you need to optimize,
is the number of dependencies in your critical path.
And this really comes from two to three places.
The first one is that, once we put out a request like this,
you've got a lot of dependencies to other resources.
The number of requests that you send out there
actually has an implicit overhead for each one of them,
which even gets worse on mobile devices.
When you've got a 3G network radio that's
spinning up and going through cell towers and all sort
of other arcane magical technologies that existed back
in the caveman days, that we still have in our pocket,
oddly enough, that has overhead associated with it.
So the more requests you're doing,
the additional fat you're adding to your time
for each one of those requests.
So if you're looking at this, you need to say,
OK, one of our first things we need to do
is reduce the number of requests we're
doing to get assets, which kind of comes back to the fact
that you have to reduce the complexity of asset dependency
on your page.
I see some people sleeping.
Do I need to clap?
No.
Kidding.
I like that.
Who did that?
You get a t-shirt afterwards.
Everyone else is like, I'm clapping now.
Free stuff.
Let's go to the second one here.
So once you've actually got those requests out on the wire,
the next problem is page weight.
How fat are your assets.
And so I've kind of done a lot of study
in this over the past couple of months about compression
on the web.
Anyone read my series, "Compression on the Web"?
More?
Yes?
[APPLAUSE]
COLT MCANLIS: I saw one dude throw up the 10's in the back.
I like you, dude.
Two t-shirts.
The problem here is that a lot of us
are still making content for our website
as though you have a cable internet connection, when
the reality is that 3G kind of sucks.
Linus stood on the stage and said that earlier today.
Right?
We have assets that are too large.
If your assets are too large and the number of dependencies
you have are too large, of course
it's going to keep your critical path from being resolved.
So look at it from a #PERFMATTERS side of it.
Reduce the number of requests, and reduce
the size of the total number of requests.
So what happens here is this, is that once we get all this done,
we can finally get to a point that we
can build our DOM and our CSSOM or our Render Tree.
And then we can resolve this chaos
and actually finally start painting the page.
So the question for you then is, if all of this chaos
is going on under the hood that I have no idea about,
how do I use my tooling to find it?
So let's take a look at that really quick.
So this is The Verge.
It's a website.
It does some things.
I'm not going to go too deep into that.
But most of you already in the audience
here know the network tab.
So I've got The Verge set up here.
It's actually loading the mobile site.
We just hit reload here.
And you actually see immediately what's going on.
Now I can dive deep, deep, deep into this tool.
I think there's fantastic resources out there
that get that done better.
And I've only got 30 minutes today,
so I'm going to give you the high level one here.
So we're talking about reducing critical path.
If we scroll, keep scrolling, scroll all the way
to the bottom here, we see there's about 90 requests
to get this site on the screen, as well as 1.4 meg-- oh, it's
not even done.
Keep scrolling down.
1.4 megs of data.
OK.
Now for a mobile connection, that's actually a lot of data.
How many of you are in here from Europe
and other-- how many of you are on roaming charges right now?
A round of applause if you hate that.
[APPLAUSE]
COLT MCANLIS: A round of applause
if you'd like to see it less than 1.5 megs.
No.
It's okay.
We can take time.
It's cool.
We've got time.
I love confusing the audience.
They're like, wait.
Did we really want to do that?
I don't know.
And so the problem with this is that all of this
has to get down before we can do anything.
And so this is webpagetest.org.
Hopefully you guys are using this.
And you run The Verge through webpagetest.org,
you go down here into waterfall view,
and you can see that this green line--
everybody see this green line over here?
Yeah?
This green line represents when the page painting occurs.
Anything before this green line represents
assets and dependencies that have
to be resolved before we can put a pixel on the screen.
So now look at this.
What is this?
We keep scrolling down.
It looks like we've got maybe-- I'm
just going to give it to them here and say about 60 assets.
That's 60 requests on the wire.
I don't have the sizes of all of these assets here.
But that's 60 requests that had to go out there and get
resolved for it put a pixel on the screen.
Let's look at something that's a little bit better.
Granted, it's a different example.
But this is m.lanyard.com, all props to Jake Archibald.
And so we just hit reload here.
And was that one request?
No.
There we go.
This example is too good.
So you can see as a very different pace, this version
of the mobile site is actually 23 requests and about 125 K.
Still able to get to your data.
And I understand there's a design principle
difference between these two sites,
but you want to get it low.
And with the networking tab, you can figure this out.
And when you look over here at webpagetest details,
you can actually see that that green line actually
comes in at about 0.9 seconds.
Look at this.
We have maybe one, two, three assets,
three assets that had to be downloaded and resolved
before the critical path can start painting.
That's the website you want your users to load,
because that's where the money is.
All right.
We're running out of time.
I got to keep hurrying here.
So once you resolve the chaos, we get networking done.
Here's the thing-- I am just the Ghost of Christmas Present.
My job here is not to inform you guys.
My job is to set up these brave and awesome and smart
gentlemen.
More information will be brought to you
at this conference from Ilya on performance networking,
as well as Bryan on creating instant mobile apps.
So now let's talk about rendering.
So we've got a bunch of cat pictures.
We want to deliver the cat pictures in a friendly cat
picture way, because it's a cat picture world that we live in.
And we have to paint it.
So the cool thing is that a lot of people
didn't know until earlier this year that painting on a web
page was not free.
So there's actually a software resource.
Something has to happen.
So the user actually puts his finger on your site,
and he starts scrolling around.
And what happens is, we have to translate the page.
And then what's not visible to the page,
we have to actually spin up the CPU
and spend cycles rasterizing that content.
And this keeps occurring.
The user scrolls.
We have to rasterize content.
Now there's a good talk.
You can see the link on the bottom
here where we talk about the interdependency
between the CPU and the GPU.
I won't get into that today.
But the point that you need to take away
is that scrolling isn't the only place that painting occurs.
There's other things that the user
does that causes paints as well.
For example, let's say you have your DOM,
and the DOM's doing awesome, and it's a DOMmy-DOM day.
And the user clicks on something,
and you're like, dude, free stuff!
And you have to actually pop up a dialogue
to say, dude, free stuff!
And in doing so, you modify the DOM.
Well when you modify the DOM, all
of the properties of the DOM have to be recalculated,
because we have to figure out did you
change something that was visible.
When you do this, we have to rebuild everything,
which means things on the screen have changed,
which means we need to actually repaint things.
So when you change the DOM, you update properties to the DOM,
repaints have to occur.
Another great example.
So let's say we've got a user who's scrolling your site.
And a lot of mobile websites I see nowadays
use CSS properties to sort of store state.
So you've got some piece of code here
that's like, the user is scrolling now.
Let's add this class to the DOM that represents sticky.
We want a sticky header.
Anyone do this?
Don't raise your hand.
Don't.
Stop.
Don't.
You're about to find out-- don't.
Just don't raise your hand.
I'm giving you a warning.
What's good is on the live stream
they can't see this direction, so they don't see this.
What happens is, every time you modify the class list,
the CSS object model has to be rebuilt.
And, of course, this causes a repaint.
So you touch the DOM.
You touch CSS.
Repaints have to occur.
We call this "paint storming" if you
get into a weird cycle of this.
So let's take a look at a demo here.
Single demo-- this is super easy.
Paul Irish did a fantastic video of this earlier this year.
I just want to show what he did.
So this is scrolling a site.
And I'm just kind of scrolling slowly here,
but you can see it's actually just a little jittery.
I'm not sure how well this is coming on the stream.
But you can see some of these white boxes
here just aren't moving too well.
And so when -- hold on.
Doing live demos is awesome.
If we actually get recording on the timeline
here and start scrolling, we can see
sort of a plethora of these green and purples.
And what we're effectively looking at here
is, when you see green and purples on the timeline view,
these are recalc styles of layout.
So this is exactly what we were talking about.
We have some event going on.
When you mouse over them, you get to go down here
and say, hey here's the call stack that caused this.
And lo and behold, here is a JavaScript function
that's intermixed between the jQuery
that the user developers of this website actually wrote
and you can see here.
Basically what they're doing-- let
me see if I can zoom that in just a little bit.
What they're doing here is, every time the user scrolls,
they're toggling a class based upon some heuristic.
So every single mouse scroll, they're
updating the CSS tree, which then has to be rebuilt,
which then causes a repaint.
And we're seeing this here in the timeline as well.
Boom.
Scroll, recalculate, layout, paint, paint, paint, paint,
paint.
And now this actually is pretty bad.
This is 7 milliseconds on my desktop here.
We get into some pretty gnarly places
where this is 10 milliseconds.
Down here it looks like we've got some big, thick purples.
Big, thick purples.
[LAUGHTER]
COLT MCANLIS: Seven milliseconds there.
We're live on the internet guys.
Simmer down.
Simmer down.
So the point here is that you can actually
use the timeline view to find out
what's causing these recalcs and paints on your page.
So want more info?
jankfree.org.
These are the jank-busters.
These are the guys who invented the term "jank."
Go follow them.
They got a talk a little bit later.
Tom Wiltzius and Nat Duca, they'll
give you all the details you need
to make silky smooth rendering performance.
So let's go to my favorite area, compute.
This is the thing that I live and thrive on.
So let's say 16 milliseconds a frame.
You have 60 frames a second.
It means you have 16 milliseconds.
But the funny thing is, you don't have 16 milliseconds.
The browser has 16 milliseconds.
You have to share.
Remember your mom and your dad taught you
that when you were a kid, like, hey
you can't have your whole time with the truck.
You've got to trade the truck with Chrome.
Chrome needs time with the truck,
and then you can have the truck back.
And you're ilke, I want my time.
And Chrome's like, I want my time.
Anyhow, the point is that you don't have fully 16
milliseconds to do all your work.
When you get a rAF event, Chrome's doing other stuff.
Including that other stuff is a paint event.
It actually has to branch off and go
do painting and compositing and all this other stuff.
And that's intermixed with all the JavaScript
that you're trying to run for your application.
So what happens is, every 16 milliseconds
you'll get a rAF pulse, and this is fine,
until something happens in your code that actually pushes back
this designated work that Chrome's going to do anyway.
And when that happens, you miss that 16th frame and your rAF
skips.
And this is known as a skipped frame.
This is when users feel jank.
Now I know we're talking about a rendering
problem in the compute section, but bear with me now.
So the question is, what caused that JavaScript to get slow?
We need to make sure that we keep an eye on this.
60 frames a second means 16 milliseconds a frame.
You have to play nice, share.
So let's say you've got a cool game like Super Resident Raver,
and you're going along doing some cool touch stuff.
Touch Handler occurs, and you just do a flood of things.
The user touched.
So I need to go through and order a pizza, because I'm
hungry right now, and update 10 million zombies,
because they're going to attack the pizza,
and they're going to be doing cool stuff, too.
Well, the problem with this is that you miss your rAF target.
And, of course, the next rAF would
want to come immediately at that point.
But, again, it has to skip a frame.
So the problem here is that you end up
doing too much work in a single frame,
and you can end up pushing it back.
Another problem is probably a little bit more complex,
and I've done some talks about this in the past.
But let's say you've got just a ton of stuff going on.
By the way, if anyone sends me source code
of an HTML5 game they make that implements
all of those gestures at once, I will send you free stuff.
I just want to put that out there.
But let's say you've got 90 hands on a game right now,
and this is actually causing a lot of allocations.
What can actually occur is that during your update phase,
garbage collection can occur any time garbage collection feels
like it needs to occur, which can push out your update loop,
because it needs time to go.
And it's a single-threaded model,
which is then going to put your draw back,
which again is going to put your rAF back.
So I've got a little bit of time here.
I want to finish up on a high note.
So, actually, not to Paul Lewis yet.
He's bald.
OK.
So I want to show you what this looks like.
So if you're trying to track down performance issues
from compute-- here's Super Resident Raver--
there's two tools you need to check out.
First off is collecting a JavaScript CPU profile.
So I'm not going to play the game.
I'm just going to hit start here.
Well OK, maybe I'll make some stuff happen.
OK.
Things are going-- yes.
Good.
People are running around.
Chaos ensues.
Fantastic.
And I'm going to let that dude run around and get
eaten by zombies for a second.
But what you can actually see down here,
and this is one of my favorite things added
to Chrome DevTools-- is this is a flame chart, which
effectively shows me where all of my calls
are going for a given frame.
So I can actually see, hey wait a minute.
Where is my time going in my frame?
Who's responsible for it?
What's the function that's taking that time?
This allows me, again, to measure where my content is
going and update it accordingly.
The second thing you need to look
at when you're dealing with memory issues
is actually this record heap allocations.
Now for HTML5 game developers, this
is fantastic, because you can kind of just
hit Start and sit back.
Now for those of you who aren't versed in this tool,
it's actually fantastic, because it sort of melds
heap allocation tracking with a timeline view.
So what you're seeing at the top there
is allocations that have been allocated and freed.
Some of them are still resident on the stack.
You can see that in blue.
Some of them have been freed, and you can see that in gray.
And then you can find a specific portion here and actually drill
down and say, hey, wait a minute.
What was actually created during that frame
to create those allocations?
And if you're lucky, sometimes you
can actually figure out where in your code
it actually came from.
So here I could see that the fade timer
stream was actually created.
It was probably passed off to some anonymous function
that needed work done to it.
So with all of these tools, you kind of
start getting the sense that you can actually
measure what's going on in your mobile universe.
You can actually get to the data.
You can actually figure out what's going on,
take ownership of your website performance, and move forward.
I love this quote by Paul Lewis-- "Tools.
Not rules."
Anyone who stands on the stage at this
point-- Well OK, let's roll back for a minute.
About a year and a half ago, people
would give performance advice, but there
wasn't enough information on the client side
to actually give that advice.
Like, hey, your scrolling is slow.
Well how?
Well I don't know.
I kind of tossed some chicken bones around
and it said it was slow.
Sweet.
Chicken bones.
But now we have the tools, and now you
need to move towards that methodology.
Validate everything you're seeing.
Measure it.
Go forward with that methodology.
Don't just rely on a bunch of bald people standing
on stage telling you what to optimize.
Go find it in your tool chain in your application
and fix it there.
My name is Colt McAnlis.
Go to HTML5 Rocks if you want to become a performance guru.
Check out the slides in the other talks
we've been talking about today.
Here's how you get a hold of me, #perfmatters.
Thank you for your time today.
I appreciate it.
[APPLAUSE]