<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Demos</title>
<style>
body {font-size: 16px;}
p {color: red;}
p span {display:none;}
span {font-size: 14px;}
img {float: right;}
</style>
</head>
<body>
<p>Hello <span>berwin</span></p>
<span>Berwin</span>
<img src="https://p1.ssl.qhimg.com/t0195d63bab739ec084.png" />
</body>
</html>
Blocking
Build DOM
CSSOM Blocking
Build DOM
Minify the file
Cache
Compress
Remove
unnecessary
styles
Minify
Cache
Compress
<link href="print.css" rel="stylesheet" media="print">
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Demos</title>
<link rel="stylesheet" href="https://static.xx.fbcdn.net/rsrc.php/v3/y6/l/1,cross/9Ia-Y9BtgQu.css">
</head>
<body>
Hello
</body>
</html>
First Paint
First Paint
<link href="print.css" rel="stylesheet" media="print" onload="this.media='all'">
<link rel="preload" href="style.css" as="style" onload="this.rel='stylesheet'">
<link rel="alternate stylesheet" href="style.css" onload="this.rel='stylesheet'">
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Demos</title>
<link rel="stylesheet" href="http://127.0.0.1:8887/style.css">
<link rel="stylesheet" href="https://lib.baomitu.com/CSS-Mint/2.0.6/css-mint.min.css">
</head>
<body>
<div class="cm-alert">Default alert</div>
</body>
</html>
First Paint
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Demos</title>
<link rel="stylesheet" href="http://127.0.0.1:8887/style.css">
</head>
<body>
<div class="cm-alert">Default alert</div>
</body>
</html>
// style.css
@import url('https://lib.baomitu.com/CSS-Mint/2.0.6/css-mint.min.css');
body{background:red;}
First Paint
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Demos</title>
<link rel="stylesheet" href="https://static.xx.fbcdn.net/rsrc.php/v3/y6/l/1,cross/9Ia-Y9BtgQu.css">
</head>
<body>
<p class='_159h'>aa</p>
<script async src="http://qiniu.bkt.demos.so/static/js/app.53df42d5b7a0dbf52386.js"></script>
</body>
</html>
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Demos</title>
<link rel="stylesheet" href="https://static.xx.fbcdn.net/rsrc.php/v3/y6/l/1,cross/9Ia-Y9BtgQu.css">
</head>
<body>
<p class='_159h'>aa</p>
<script src="http://qiniu.bkt.demos.so/static/js/app.53df42d5b7a0dbf52386.js"></script>
</body>
</html>
Users perceive animations as smooth so long as 60 new frames are rendered every second.
Users feel like the result is immediate.
Users lose focus on the task they are performing.
users are frustrated and are likely to abandon tasks.
Any longer, and the connection between action and reaction is broken.
1000/60 = 16.666666...
requestAnimationFrame(
slideAnimation
)
recalculate style
Layout
UI Event
Everything...
const testWorker = new Worker('./worker.js')
setTimeout(_ => {
testWorker.postMessage({})
testWorker.onmessage = function (ev) {
console.log(ev.data)
}
}, 5000)
// worker.js
self.onmessage = function () {
const start = performance.now()
while (performance.now() - start < 1000) {}
postMessage('done!')
}
Layout
UI Event
recalculate style
Everything...
function block () {
ts(function* () {
const start = performance.now()
while (performance.now() - start < 1000) {
console.log(11)
yield
}
console.log('done!')
})
}
setTimeout(block, 5000)
function ts (gen) {
if (typeof gen === 'function') gen = gen()
if (!gen || typeof gen.next !== 'function') return
(function next () {
const res = gen.next()
if (res.done) return
setTimeout(next)
})()
}
1
2
.box:nth-child(3)
.box--three
Roughly 50% of the time used to calculate the computed style for an element is used to match selectors
// Set the width.
el.style.width = '100px';
// Then ask for it.
const width = el.offsetWidth;
// Get the last known width.
const width = el.offsetWidth;
// Then update it.
el.style.width = '100px';
const container = document.querySelector('.container');
const boxes = document.querySelectorAll('p');
for (var i = 0; i < boxes.length; i++) {
// Read a layout property
const newWidth = container.offsetWidth;
// Then invalidate layouts with writes.
boxes[i].style.width = newWidth + 'px';
}
const container = document.querySelector('.container');
const boxes = document.querySelectorAll('p');
// Read a layout property
const newWidth = container.offsetWidth;
for (var i = 0; i < boxes.length; i++) {
// Then invalidate layouts with writes.
boxes[i].style.width = newWidth + 'px';
}