From raw bytes to pixels on your screen (in 1s)
<html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1">
<link href="style.css" rel="stylesheet">
<title>Critical Path</title>
</head>
<body>
<p>Hello <span>web performance </span>students!</p>
<div><img src="awesome-photo.jpg"></div>
</body>
</html>
/* style.css */
body { font-size: 16px; }
p { font-weight: bold; }
span { color: red; }
p span { display: none; }
img { float: right; }
Conversion
Tokenizing
Lexing
DOM construction
/* style.css */
body { font-size: 16px; }
p { font-weight: bold; }
span { color: red; }
p span { display: none; }
img { float: right; }
...
<script src="example.js" async></script>
<script src="example.js" defer></script>
...
Hello students
<p> (100%)
<img>
<div> (100%)
<html> <body> (viewport width=device-width)
Hello students
<p> (100%)
<img>
<div> (100%)
<html> <body> (viewport width=device-width)
Rasterizer draw calls:
+ imageDecode + [Resize]
RAIL / LIAR
Response | |
Animate | |
Idle | |
Load |
1000
50
16
100
ms
CSS Animations
Web Animation API
First measure then optimize
JS, Styles and Layout, Paint and Composite
Function.prototype.toString()
V8
// Which is faster:
for (var i = 0; i < len; i++) ...
// or
while (++i < len) ...
// ?
// We don't know
function animate() {
// cool animation frame stuff
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
#1
function animate() {
// cool animation frame stuff
setTimeout(animate, 4);
}
animate();
HTML5
Worker
worker.js
main-script.js
postMessage(data)
postMessage(data)
onmessage
onmessage
var worker = new Worker('worker.js');
worker.onmessage = function(e) {
console.log('Worker said: ', e.data);
};
worker.postMessage('Hello World');
this.onmessage = function(e) {
// long-running JS goes here
postMessage(e.data);
};
<section class="post">
<h1 class="title">Egestas</h1>
<p class="description big">Pellentesque morbi turpis egestas.</p>
</section>
<section class="post">
<h1 class="post__title">Egestas</h1>
<p class="post__description--big">Pellentesque morbi turpis egestas.</p>
</section>
.post {}
.post .title {}
.post .description .big {}
.post {}
.post__title {}
.post__description--big {}
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
.item:nth-child(3) {
color: #0f0;
}
<div class="item"></div>
<div class="item"></div>
<div class="item third"></div>
.item.third {
color: #0f0;
}
<div class="item"></div>
<div class="item"></div>
<div class="item--third"></div>
.item--third {
color: #0f0;
}
requestAnimationFrame(logBoxHeight);
function logBoxHeight() {
box.classList.add('super-big');
console.log(box.offsetHeight);
}
requestAnimationFrame(logBoxHeight);
function logBoxHeight() {
console.log(box.offsetHeight);
box.classList.add('super-big');
}
May the Forced syncronous layout NOT be with you!