How slow is your web app and how to make it faster
Damian Kowalski
dkowalski@pgs-soft.com
1. User perception - how late is too late?
2. Browser, what took you so long?
3. How to speed up page loading
4. Summary
WAITING
Active phase
Passive phase
https://www.smashingmagazine.com/2015/11/why-performance-matters-part-2-perception-management/
1
1
A
A
A
A
P
P
P
P
Goal: display something meaningfull to the user
within 1 second
pgs-soft.com
Critical Rendering Path
1
Delay | User perception |
---|---|
instant | |
still focused | |
I think I will eat burger today | |
I'll come back later (or not) |
0 - 250 ms
250 ms - 1000 ms
1 s - 10 s
10 s +
We have to keep user attention
1
60% - 85% of users expect mobile site will load as fast or faster than desktop
Connection | Download |
---|---|
3G | 750Kb/s |
LTE | 4Mb/s |
WiFi | 30Mb/s |
1
1. Critical Rendering Path < 1s
2. Over 1s - users go away
3. Users expect fast mobile experience
1
DNS
TCP
Request
Response
Server side processing
file transfer finished
GET pgs-soft.com/
DNS lookup could be 100 ms, 150 ms, or sometimes longer
started sending data (TTFB)
Max 6 concurrent requests per domain
Client side processing
2
<!DOCTYPE html>
<html>
<head>
<title>Critical Rendering Path</title>
<link href="styles.css" rel="stylesheet">
<script src="scripts.js"></script>
</head>
<body>
<h1>Hello <span>world!</span></h1>
<img src="pgs.png"/>
</body>
</html>
CSS is Render blocking
JS is Parser blocking
h1 {
color: red;
}
h1 span {
display: none;
}
styles.css
var span = document.getElementsByTagName('span')[0];
// change DOM text content
span.textContent = 'Software Talks!';
// change CSSOM property
span.style.display = 'inline';
scripts.js
scripts.js: Uncaught TypeError: Cannot set property 'textContent' of undefined
2
2
MEASURE FIRST!
3
Metrics to look at:
<!DOCTYPE html>
<html>
<head>
<title>Critical Rendering Path</title>
<link href="styles.css" rel="stylesheet">
</head>
<body>
<h1>Hello <span>world!</span></h1>
<img src="pgs.png"/>
<script src="script1.js"></script>
<script src="script2.js" async></script>
</body>
</html>
script1 is no longer parser blocking and is not part of the critical rendering path
script2 is like script1 but also don't wait for styles.css and script1 to load
With "async" - no execution order quarantee !
3
Original | Minified | Gzipped |
---|---|---|
147 KB | 123 KB | 20 KB |
Twitter Bootstrap CSS
use cache & version your files so you can cache forever
Original | Minified | Gzipped |
---|---|---|
234 KB | 74 KB | 27 KB |
Vue
3
https://www.npmjs.com/package/gulp-rev (unicorn-d41d8cd98f.css)
<link href="mobile.css" rel="stylesheet" media="(max-width: 979px) and (orientation: landscape)">
<link href="desktop.css" rel="stylesheet" media="min-width: 980px">
<!DOCTYPE html>
<html>
<head>
<title>Critical Rendering Path</title>
<style>
body { ... } h1 { ... }
</style>
</head>
<body>
<h1>Hello <span>world!</span></h1>
<img src="pgs.png"/>
<script src="scripts.js"></script>
<script>
loadLater('styles.css');
</script>
</body>
</html>
https://developers.google.com/speed/docs/insights/OptimizeCSSDelivery
loadLater()
https://github.com/addyosmani/critical
Keep your html under 14 KB to avoid multiple roundtrips
3
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 400;
src: url(opensans.woff) format('woff');
}
body {
font-family: 'Open Sans', 'Arial', sans-serif;
}
3
<link rel="dns-prefetch" href="hostname_to_resolve.com">
Pre-resolve DNS hostnames for assets later in the page (Most browsers)
3
https://www.smashingmagazine.com/2016/02/preload-what-is-it-good-for/
<link rel="preload" href="late_discovered_thing.js" as="script">
Preload resource with high priority (Chrome, Opera)
<link rel="prefetch" href="details-page.css">
Prefetch asset for a future navigation, place in cache (Most browsers)
https://blog.cloudflare.com/http-2-for-web-developers/
3
Performance optimization | HTTP/1.x | HTTP/2 |
---|---|---|
Domain sharding | DO | DON'T |
Concatenate files | DO | DON'T |
Inline assets | DO | DON'T* |
* use server push instead (not widely supported yet)
3
3