Performance is fundamentally, a UX concern. Sites that are slow to render or janky to interact with are a bad user experience. We strive to write performant code for our users, but users don’t directly interact with our code - it all happens through the medium of the browser. The browser is the middleman between us and our users; therefore to make our users happy, we first have to make the browser happy. But how exactly do we do that?
In this talk, we’ll learn how browsers work under the hood: how they request, construct, and render a website. At each step along the way, we’ll cover what we can do as developers to make the browser’s job easier, and why those best practices work. You’ll leave with a solid understanding of how to write code that works with the browser, not against it, and ultimately improves your users’ experience.
5. @ksylor
UX
WHAT MAKES USERS HAPPY?
▸ Fast rendering of content
(e.g. "fast loading")
▸ Instant feedback for clicks/taps/
keyboard interactions
▸ Smooth animations
▸ Don't use up their mobile data!
16. @ksylor
NAVIGATION - CONNECTION
https://mindblowncat.com
the
internet
3. SSL handshake
ClientHello
ServerHello & Certificate
Client key
FINISHED
FINISHED
1. DNS lookup
DNS server
what is the IP address for
mindblowncat.com?
162.144.26.144
SYN
SYN ACK
ACK
2. TCP handshake
mindblowncat.com
162.144.26.144
17. @ksylor
NAVIGATION - CONNECTION
https://mindblowncat.com
the
internet
3. SSL handshake
ClientHello
ServerHello & Certificate
Client key
FINISHED
FINISHED
1. DNS lookup
DNS server
what is the IP address for
mindblowncat.com?
162.144.26.144
SYN
SYN ACK
ACK
2. TCP handshake
4. Request
mindblowncat.com
162.144.26.144
HTTP GET
18. @ksylor
NAVIGATION - CONNECTION
https://mindblowncat.com
the
internet
3. SSL handshake
ClientHello
ServerHello & Certificate
Client key
FINISHED
FINISHED
1. DNS lookup
DNS server
what is the IP address for
mindblowncat.com?
162.144.26.144
SYN
SYN ACK
ACK
2. TCP handshake
4. Request
mindblowncat.com
162.144.26.144
HTTP GET
5. SERVER STUFF
6. SEND RESPONSE
19. @ksylor
NAVIGATION - CONNECTION
https://mindblowncat.com
the
internet
3. SSL handshake
ClientHello
ServerHello & Certificate
Client key
FINISHED
FINISHED
1. DNS lookup
DNS server
what is the IP address for
mindblowncat.com?
162.144.26.144
SYN
SYN ACK
ACK
2. TCP handshake
4. Request
mindblowncat.com
162.144.26.144
HTTP GET
5. SERVER STUFF
6. SEND RESPONSE
ACK
2nd HTTP RESPONSE (29kb)
3rd HTTP RESPONSE (57kb)
ACK
etc…
1st HTTP RESPONSE (14kb)
7. TTFB
20. @ksylor
NAVIGATION - CONNECTION
https://mindblowncat.com
the
internet
3. SSL handshake
ClientHello
ServerHello & Certificate
Client key
FINISHED
FINISHED
1. DNS lookup
DNS server
what is the IP address for
mindblowncat.com?
162.144.26.144
SYN
SYN ACK
ACK
2. TCP handshake
4. Request
mindblowncat.com
162.144.26.144
HTTP GET
5. SERVER STUFF
6. SEND RESPONSE
ACK
2nd HTTP RESPONSE (29kb)
3rd HTTP RESPONSE (57kb)
ACK
etc…
1st HTTP RESPONSE (14kb)
7. TTFB
8. Parse
21. @ksylor
NAVIGATION
WHAT DO WE CONTROL?
▸ Reduce server response time
▸ Cache cache cache cache cache
▸ Use a CDN
▸ Smaller files = fewer roundtrips
▸ Compression, tree-shaking, code-splitting
▸ First 14kb
▸ Preloading/prefetching, resource hints, HTTP/2
22. @ksylor
HOW DO BROWSERS WORK?
https://mindblowncat.com
4 PHASES
▸ Navigation
▸ Parsing
▸ Rendering
▸ Interaction
26. @ksylor
PARSING - HTML TO DOM
HTML
html
DOM NETWORK
RESPONSE HTML
Main
Worker
Network
Process
<html>
<head>
<title>Cats are fun!</title>
<link href="style.css".../>
<script src="script.js"></script>
</head>
<body>
<h1 class="title">Hi!</h1>
<p>Here is a cat.
<div class="border">
<img src="cat.gif" id="cat"
alt="Cat!"/>
</div>
</body>
</html>
27. @ksylor
<html>
<head>
<title>Cats are fun!</title>
<link href="style.css".../>
<script src="script.js"></script>
</head>
<body>
<h1 class="title">Hi!</h1>
<p>Here is a cat.
<div class="border">
<img src="cat.gif" id="cat"
alt="Cat!"/>
</div>
</body>
</html>
PARSING - HTML TO DOM
HTML
html
DOM
REQUEST STYLE.CSS
NETWORK
RESPONSE HTML
REQUEST SCRIPT.JS
REQUEST CAT.JPG
Main
Worker
Network
Process
28. @ksylor
<html>
<head>
<title>Cats are fun!</title>
<link href="style.css".../>
<script src="script.js"></script>
</head>
<body>
<h1 class="title">Hi!</h1>
<p>Here is a cat.
<div class="border">
<img src="cat.gif" id="cat"
alt="Cat!"/>
</div>
</body>
</html>
PARSING - HTML TO DOM
HTML
html
DOM
head
REQUEST STYLE.CSS
NETWORK
RESPONSE HTML
REQUEST SCRIPT.JS
REQUEST CAT.JPG
Main
Worker
Network
Process
29. @ksylor
<html>
<head>
<title>Cats are fun!</title>
<link href="style.css".../>
<script src="script.js"></script>
</head>
<body>
<h1 class="title">Hi!</h1>
<p>Here is a cat.
<div class="border">
<img src="cat.gif" id="cat"
alt="Cat!"/>
</div>
</body>
</html>
PARSING - HTML TO DOM
HTML
html
DOM
head
title
REQUEST STYLE.CSS
NETWORK
RESPONSE HTML
REQUEST SCRIPT.JS
REQUEST CAT.JPG
Main
Worker
Network
Process
30. @ksylor
<html>
<head>
<title>Cats are fun!</title>
<link href="style.css".../>
<script src="script.js"></script>
</head>
<body>
<h1 class="title">Hi!</h1>
<p>Here is a cat.
<div class="border">
<img src="cat.gif" id="cat"
alt="Cat!"/>
</div>
</body>
</html>
PARSING - HTML TO DOM
HTML
html
DOM
head
title
REQUEST STYLE.CSS
NETWORK
link
RESPONSE HTML
REQUEST SCRIPT.JS
REQUEST CAT.JPG
Main
Worker
Network
Process
31. @ksylor
PARSING - HTML TO DOM
HTML
html
DOM
head
link
title
<html>
<head>
<title>Cats are fun!</title>
<link href="style.css".../>
<script src="script.js"></script>
</head>
<body>
<h1 class="title">Hi!</h1>
<p>Here is a cat.
<div class="border">
<img src="cat.gif" id="cat"
alt="Cat!"/>
</div>
</body>
</html>
REQUEST STYLE.CSS
NETWORK
RESPONSE HTML
REQUEST SCRIPT.JS
script
REQUEST CAT.JPG
Main
Worker
Network
Process
32. @ksylor
PARSING - HTML TO DOM
HTML
html
DOM
head
link
title
<html>
<head>
<title>Cats are fun!</title>
<link href="style.css".../>
<script src="script.js"></script>
</head>
<body>
<h1 class="title">Hi!</h1>
<p>Here is a cat.
<div class="border">
<img src="cat.gif" id="cat"
alt="Cat!"/>
</div>
</body>
</html>
REQUEST STYLE.CSS
NETWORK
RESPONSE HTML
REQUEST SCRIPT.JS
script
REQUEST CAT.JPG
JAVASCRIPT IS RENDER BLOCKING*
*when included without defer or async attributes
Main
Worker
Network
Process
33. @ksylor
PARSING - HTML TO DOM
HTML
html
DOM
head
link
title
<html>
<head>
<title>Cats are fun!</title>
<link href="style.css".../>
<script src="script.js"></script>
</head>
<body>
<h1 class="title">Hi!</h1>
<p>Here is a cat.
<div class="border">
<img src="cat.gif" id="cat"
alt="Cat!"/>
</div>
</body>
</html>
REQUEST STYLE.CSS
NETWORK
RESPONSE HTML
REQUEST SCRIPT.JS
script
REQUEST CAT.JPG
BUT FIRST... CSS BLOCKS JS
RESPONSE STYLE.CSS
Main
Worker
Network
Process
41. @ksylor
PARSING - HTML TO DOM
HTML
html
DOM
head
link
title
<html>
<head>
<title>Cats are fun!</title>
<link href="style.css".../>
<script src="script.js"></script>
</head>
<body>
<h1 class="title">Hi!</h1>
<p>Here is a cat.
<div class="border">
<img src="cat.gif" id="cat"
alt="Cat!"/>
</div>
</body>
</html>
REQUEST STYLE.CSS
NETWORK
RESPONSE HTML
REQUEST SCRIPT.JS
script
REQUEST CAT.JPG
RESPONSE SCRIPT.JS
RESPONSE STYLE.CSS
Main
Worker
Network
Process
43. @ksylor
PARSING- JAVASCRIPT AST
JS ASTJS
function badIdea() {
var cat =
document.getElementById("cat");
cat.src = "another-cat.gif";
}
badIdea();
Program
body:
Main
Worker
Network
Process
go to: https://astexplorer.net
44. @ksylor
PARSING- JAVASCRIPT TO ABSTRACT SYNTAX TREE (AST)
ASTJS
function badIdea() {
var cat =
document.getElementById("cat");
cat.src = "another-cat.gif";
}
badIdea();
Main
Program
body:
FunctionDeclaration
id:
body:
45. @ksylor
PARSING- JAVASCRIPT TO ABSTRACT SYNTAX TREE (AST)
ASTJS
function badIdea() {
var cat =
document.getElementById("cat");
cat.src = "another-cat.gif";
}
badIdea();
Main
Program
FunctionDeclaration
Identifier
name: "badIdea"
id:
body:
body:
46. @ksylor
PARSING- JAVASCRIPT TO ABSTRACT SYNTAX TREE (AST)
ASTJS
function badIdea() {
var cat =
document.getElementById("cat");
cat.src = "another-cat.gif";
}
badIdea();
Main
Program
FunctionDeclaration
Identifier
name: "badIdea"
id:
body: BlockStatement
body:
47. @ksylor
VariableDeclaration
body:
id:
init:
PARSING- JAVASCRIPT TO ABSTRACT SYNTAX TREE (AST)
ASTJS
function badIdea() {
var cat =
document.getElementById("cat");
cat.src = "another-cat.gif";
}
badIdea();
Main
Program
FunctionDeclaration
Identifier
name: "badIdea"
id:
body: BlockStatement
body:
48. @ksylor
PARSING- JAVASCRIPT TO ABSTRACT SYNTAX TREE (AST)
ASTJS
function badIdea() {
var cat =
document.getElementById("cat");
cat.src = "another-cat.gif";
}
badIdea();
Main
Program
FunctionDeclaration
VariableDeclaration
Identifier
name: "badIdea"
id:
id:
body:
Identifier
name: "cat"
BlockStatement
body:
body:
init:
49. @ksylor
PARSING- JAVASCRIPT TO ABSTRACT SYNTAX TREE (AST)
ASTJS
function badIdea() {
var cat =
document.getElementById("cat");
cat.src = "another-cat.gif";
}
badIdea();
Main
Program
FunctionDeclaration
Identifier
name: "cat"
VariableDeclaration
Identifier
name: "badIdea"
id:
init:
id:
body: BlockStatement
body:
body:
CallExpression
callee:
arguments:
50. @ksylor
PARSING- JAVASCRIPT TO ABSTRACT SYNTAX TREE (AST)
ASTJS
function badIdea() {
var cat =
document.getElementById("cat");
cat.src = "another-cat.gif";
}
badIdea();
Main
Program
FunctionDeclaration
Identifier
name: "cat"
VariableDeclaration
Identifier
name: "badIdea"
CallExpression
id:
init:
id:
body: BlockStatement
body:
body:
callee:
arguments:
MemberExpression
object:
property:
51. @ksylor
PARSING- JAVASCRIPT TO ABSTRACT SYNTAX TREE (AST)
ASTJS
function badIdea() {
var cat =
document.getElementById("cat");
cat.src = "another-cat.gif";
}
badIdea();
Main
Program
FunctionDeclaration
Identifier
name: "cat"
VariableDeclaration
Identifier
name: "badIdea"
CallExpression
id:
init:
id:
body: BlockStatement
body:
body:
MemberExpressioncallee:
object: Identifier
name: "document"
property:
arguments:
52. @ksylor
PARSING- JAVASCRIPT TO ABSTRACT SYNTAX TREE (AST)
ASTJS
function badIdea() {
var cat =
document.getElementById("cat");
cat.src = "another-cat.gif";
}
badIdea();
Main
Program
FunctionDeclaration
Identifier
name: "cat"
VariableDeclaration
Identifier
name: "badIdea"
CallExpression
id:
init:
id:
body: BlockStatement
body:
body:
Identifier
name: "document"
MemberExpressioncallee:
object:
property: Identifier
name: "getElementById"
arguments:
53. @ksylor
PARSING- JAVASCRIPT TO ABSTRACT SYNTAX TREE (AST)
ASTJS
function badIdea() {
var cat =
document.getElementById("cat");
cat.src = "another-cat.gif";
}
badIdea();
Main
Program
FunctionDeclaration
Identifier
name: "cat"
VariableDeclaration
Identifier
name: "document"
Identifier
name: "badIdea"
MemberExpression
CallExpression
id:
init:
callee:
object:
Identifier
name: "getElementById"
id:
body: BlockStatement
Literal
value:"cat"
arguments:
body:
body:
property:
54. @ksylor
PARSING- JAVASCRIPT TO ABSTRACT SYNTAX TREE (AST)
ASTJS
function badIdea() {
var cat =
document.getElementById("cat");
cat.src = "another-cat.gif";
}
badIdea();
Main
Program
FunctionDeclaration
Identifier
name: "cat"
VariableDeclaration
Identifier
name: "badIdea"
CallExpression
id:
init:
id:
body: BlockStatement
body:
body:
Identifier
name: "document"
MemberExpressioncallee:
object:
property: Identifier
name: "getElementById"
Literal
value:"cat"
arguments:
ExpressionStatement
AssignmentExpression
operator: "="
left:
right:
expression:
65. @ksylor
PARSING - HTML TO DOM (AGAIN)
HTML
html
DOM
head
link
title
<html>
<head>
<title>Cats are fun!</title>
<link href="style.css".../>
<script src="script.js"></script>
</head>
<body>
<h1 class="title">Hi!</h1>
<p>Here is a cat.
<div class="border">
<img src="cat.gif" id="cat"
alt="Cat!"/>
</div>
</body>
</html>
REQUEST STYLE.CSS
NETWORK
RESPONSE HTML
REQUEST SCRIPT.JS
script
REQUEST CAT.JPG
RESPONSE SCRIPT.JS
RESPONSE STYLE.CSS
Main
Worker
Network
Process
66. @ksylor
<html>
<head>
<title>Cats are fun!</title>
<link href="style.css".../>
<script src="script.js"></script>
</head>
<body>
<h1 class="title">Hi!</h1>
<p>Here is a cat.
<div class="border">
<img src="cat.gif" id="cat"
alt="Cat!"/>
</div>
</body>
</html>
PARSING - HTML TO DOM (AGAIN)
HTML
html
DOM
head
link
title
NETWORK
script
REQUEST STYLE.CSS
RESPONSE HTML
REQUEST SCRIPT.JS
REQUEST CAT.JPG
RESPONSE SCRIPT.JS
RESPONSE STYLE.CSS
Main
Worker
Network
Process
67. @ksylor
<html>
<head>
<title>Cats are fun!</title>
<link href="style.css".../>
<script src="script.js"></script>
</head>
<body>
<h1 class="title">Hi!</h1>
<p>Here is a cat.
<div class="border">
<img src="cat.gif" id="cat"
alt="Cat!"/>
</div>
</body>
</html>
PARSING - HTML TO DOM (AGAIN)
HTML
html
DOM
head
link
title
NETWORK
body
script
REQUEST STYLE.CSS
RESPONSE HTML
REQUEST SCRIPT.JS
REQUEST CAT.JPG
RESPONSE SCRIPT.JS
RESPONSE STYLE.CSS
Main
Worker
Network
Process
68. @ksylor
<html>
<head>
<title>Cats are fun!</title>
<link href="style.css".../>
<script src="script.js"></script>
</head>
<body>
<h1 class="title">Hi!</h1>
<p>Here is a cat.
<div class="border">
<img src="cat.gif" id="cat"
alt="Cat!"/>
</div>
</body>
</html>
PARSING - HTML TO DOM (AGAIN)
HTML
html
DOM
head
link
title
NETWORK
body
h1
class:“title”
Hi!
script
REQUEST STYLE.CSS
RESPONSE HTML
REQUEST SCRIPT.JS
REQUEST CAT.JPG
RESPONSE SCRIPT.JS
RESPONSE STYLE.CSS
Main
Worker
Network
Process
69. @ksylor
<html>
<head>
<title>Cats are fun!</title>
<link href="style.css".../>
<script src="script.js"></script>
</head>
<body>
<h1 class="title">Hi!</h1>
<p>Here is a cat.
<div class="border">
<img src="cat.gif" id="cat"
alt="Cat!"/>
</div>
</body>
</html>
PARSING - HTML TO DOM (AGAIN)
HTML
html
DOM
head
link
title
NETWORK
paragraph
Here is a cat.
body
h1
class:“title”
Hi!
script
REQUEST STYLE.CSS
RESPONSE HTML
REQUEST SCRIPT.JS
REQUEST CAT.JPG
RESPONSE SCRIPT.JS
RESPONSE STYLE.CSS
Main
Worker
Network
Process
70. @ksylor
<html>
<head>
<title>Cats are fun!</title>
<link href="style.css".../>
<script src="script.js"></script>
</head>
<body>
<h1 class="title">Hi!</h1>
<p>Here is a cat.
<div class="border">
<img src="cat.gif" id="cat"
alt="Cat!"/>
</div>
</body>
</html>
PARSING - HTML TO DOM (AGAIN)
HTML
html
DOM
head
link
title
NETWORK
paragraph
Here is a cat.
div
class:”border”
body
h1
class:“title”
Hi!
script
REQUEST STYLE.CSS
RESPONSE HTML
REQUEST SCRIPT.JS
REQUEST CAT.JPG
RESPONSE SCRIPT.JS
RESPONSE STYLE.CSS
Main
Worker
Network
Process
71. @ksylor
<html>
<head>
<title>Cats are fun!</title>
<link href="style.css".../>
<script src="script.js"></script>
</head>
<body>
<h1 class="title">Hi!</h1>
<p>Here is a cat.
<div class="border">
<img src="cat.gif" id="cat"
alt="Cat!"/>
</div>
</body>
</html>
PARSING - HTML TO DOM (AGAIN)
HTML
html
DOM
head
link
title
NETWORK
paragraph
div
class:”border”
Here is a cat.
body
h1
class:“title”
Hi!
script
REQUEST STYLE.CSS
RESPONSE HTML
REQUEST SCRIPT.JS
REQUEST CAT.JPG
RESPONSE SCRIPT.JS
RESPONSE STYLE.CSS
image
id="cat"
Main
Worker
Network
Process
72. @ksylor
<html>
<head>
<title>Cats are fun!</title>
<link href="style.css".../>
<script src="script.js"></script>
</head>
<body>
<h1 class="title">Hi!</h1>
<p>Here is a cat.
<div class="border">
<img src="cat.gif" id="cat"
alt="Cat!"/>
</div>
</body>
</html>
PARSING - HTML TO DOM (AGAIN)
HTML
html
DOM
head
link
title
NETWORK
paragraph
div
class:”border”
Here is a cat.
body
h1
class:“title”
Hi!
script
image
id="cat"
REQUEST STYLE.CSS
RESPONSE HTML
REQUEST SCRIPT.JS
REQUEST CAT.JPG
RESPONSE SCRIPT.JS
RESPONSE STYLE.CSS
Main
Worker
Network
Process
86. @ksylor
+ BROWSER DEFAULT STYLES
+ USER-PROVIDED STYLESHEETS
RENDERING - STYLE CALCULATION
html
DOM
head
link
title
body
h1
class:“title”
paragraph
image
div
class:”border”
Hi!
Here is a cat.
CSSOM
body
font-family: sans-serif;
.border
border: 1px solid gray;
img
display:block;
margin: 1em;
.title
font-family: serif;
COMPUTED STYLE
root
<body>
font-family: sans-serif;
<h1>
color: magenta;
font-family: serif;
Hi!
<p>
font-family: sans-serif;
<div>
border: 1px solid gray;
font-family: sans-serif;
<img>
display:block;
margin: 1em;
Here is a cat.
h1
color: magenta;
script
Main Raster/
Compositor
Network
Process
93. @ksylor
RENDERING - LAYOUT
html/viewport
body
h1
Hi!
Here is a cat. p
root/html
<body>
font-family: sans-serif;
<h1>
color: magenta;
font-family: serif;
Hi!
<p>
font-family: sans-serif;
<div>
border: 1px solid gray;
font-family: sans-serif;
<img>
display:block;
margin: 1em;
Here is a cat.
COMPUTED STYLE
Main Raster/
Compositor
Network
Process
94. @ksylor
root/html
<body>
font-family: sans-serif;
<h1>
color: magenta;
font-family: serif;
Hi!
<p>
font-family: sans-serif;
<div>
border: 1px solid gray;
font-family: sans-serif;
<img>
display:block;
margin: 1em;
Here is a cat.
COMPUTED STYLE
RENDERING - LAYOUT
html/viewport
body
h1
Hi!
Here is a cat. p
div
Main Raster/
Compositor
Network
Process
95. @ksylor
RENDERING - LAYOUT
html/viewport
body
h1
Hi!
Here is a cat.
div
p
img
root/html
<body>
font-family: sans-serif;
<h1>
color: magenta;
font-family: serif;
Hi!
<p>
font-family: sans-serif;
<div>
border: 1px solid gray;
font-family: sans-serif;
<img>
display:block;
margin: 1em;
Here is a cat.
COMPUTED STYLE
Main Raster/
Compositor
Network
Process
99. @ksylor
RENDERING - PAINT
PIXELS ARE PAINTED ON LAYERS
RASTERIZE
Main Raster/
Compositor
Network
Process
*layers pictured are imaginary for
demonstration purposes only
▸ 3D transforms
▸ CSS animation using
opacity or transform
▸ will-change
▸ "accelerated" CSS
filters
▸ <video> or <canvas>
▸ z-index above another
layer
CREATE A NEW LAYER
112. @ksylor
THE TROUBLE WITH BROWSERS
THE MAIN THREAD DOES IT ALL
▸ Parsing HTML into DOM
▸ Parsing CSS into CSSOM
▸ JS into JS AST
▸ JS Execution
▸ Style Calculation (and re-style)
▸ Layout (and re-layout)
▸ Paint (and re-paint)
113. @ksylor
HOW DO BROWSERS WORK?
https://mindblowncat.com
4 PHASES
▸ Navigation
▸ Parsing
▸ Rendering
▸ Interaction
Hi!
Here is a cat.
114. @ksylor
INTERACTION
THE MAIN THREAD DOES IT ALL
▸ Parsing HTML into DOM
▸ Parsing CSS into CSSOM
▸ JS into JS AST
▸ JS Execution
▸ Style Calculation (and re-style)
▸ Layout (and re-layout)
▸ Paint (and re-paint)
▸ User interaction
116. @ksylor
INTERACTION - RESPOND TO INPUT
INPUT DELAY
parse & execute js
async request js
FirstPaint
style paint
composite
layoutparse html parse css parse html
preload scanner
DomInteractive &
DomContentLoaded
request html
Main
Worker
Network
Process
NavigationStart TTFB
User taps
button
First Input Delay
117. @ksylor
INTERACTION - RESPOND TO INPUT
UNBLOCK THE MAIN THREAD
▸ Ship less Javascript
▸ Code-splitting - load what you need to
render, then lazy load the rest
▸ Break up execution into smaller, async
tasks (requestIdleCallback)
▸ Measure first input delay and long tasks
▸ Audit frameworks, third party scripts, ads,
and trackers
121. @ksylor
INTERACTION - JANK
"DROPPING" FRAMES FROM THE MAIN THREAD
16.67ms
frame! frame!
re-style re-layoutjs event handler
button click opens
an overlay dialog
frame! frame! frame!
<div>'s style changes
from display: none;
to display: block;
re-paint
jank :( jank :( jank :( jank :(
re-composite
on the GPU
122. @ksylor
RENDERING - LAYERS
LAYERS ARE AWESOME
Main Raster/
Compositor
Network
Process
▸ Repaint only the layer that changed, all
other layers stay the same
▸ Easier to move/animate layers without
repainting the whole page.
▸ But layers are expensive in memory!
▸ Don't create layers that don't change how
the page is rendered.
124. @ksylor
INTERACTION - LESS JANK!
"DROPPING" FRAMES FROM THE MAIN THREAD
16.67ms
frame! frame!
stylejs event handler
button click opens
an overlay dialog
frame! frame! frame!
<div>'s style changes
from visibility: hidden;
to visibility: visible;
and uses css animations
jank :( jank :(
re-composite
on the GPU
frame! frame!frame!
125. @ksylor
HOW DO WE MAKE BROWSERS HAPPY?
https://mindblowncat.com
4 PHASES
▸ Navigation
GET IT OVER WITH!
▸ Parsing
DOM + CSSOM, ASAP
▸ Rendering
DO LESS WORK (ON THE CPU)
▸ Interaction
IMMEDIATE & JANK FREE
Hi!
Here is a cat.