Everything You Always Wanted to Know About
Maurizio Lupo @sithmel
(*But Were Afraid to Ask)
why is it important?
why is it important?
why is it important?
why is it important?
SEO: Faster sites get better ranking
why is it important?
"Usability engineering" Jacob Nielsen 1993
what to measure
Time to establish a connection
+
backend time
what to measure
what to measure
what to measure
how to measure it
www.webpagetest.org
Speedcurve
how to measure it
Browser API: window.performance
Real users monitoring
how to measure it
Syntethic: take the sample at the same time every day
RUM: watch long period trends
Understanding browser networking: bandwidth
Radius of the pipe
Not an official definition
Understanding browser networking: latency
Length of wires * speed of light + routers * time to route
Not an official definition
Understanding browser networking: latency
3G: 100ms latency
DSL: 5ms latency
San Francisco to NYC carries a minimum 40ms RTT
Understanding browser networking: latency
Understanding browser networking: TCP
TCP provides reliable, ordered, and error-checked delivery of a stream of octets between applications running on hosts communicating by an IP network
Understanding browser networking: TCP
If latency is 100ms, opening a connection costs 300ms!
Opening a connection:
Understanding browser networking: TCP
If we sum dns fetch, TCP handshake, tsl negotiation (on a 100ms latency network) it takes 1 second!!!
Understanding browser networking: TCP
Reliable is great but:
Acknowledge reception
Head of line blocking
Congestion control
Understanding browser networking: TCP
Congestion control: slow start
Understanding browser networking: TCP
Congestion control: slow start
Understanding browser networking: TCP
Default opening window size is of 10 packets (almost everywhere)
TCP packet is commonly 1500bytes (MTU)
First 15000 (14KB) are received in a single gulp
Understanding browser networking: TCP
Understanding browser networking: HTTP
Understanding browser networking: HTTP
but HTTP head of line blocking
Understanding browser networking: HTTP
:-( Every connection pays the price (slow start)
:-) Parallel download
Understanding browser networking: HTTP
Single connection
Uses binary frames for parallel transmission
HTTP3: http2 over UDP (quic)
What's next?
Understanding browser networking: HTTP
*only the ones impacting performances
Understanding browser networking: Caching
cache-control
Cache-control: must-revalidate
Cache-control: no-cache
Cache-control: no-store
Cache-control: no-transform
Cache-control: public
Cache-control: private
Cache-control: proxy-revalidate
Cache-Control: max-age=<seconds>
Cache-control: s-maxage=<seconds>
Cache-control: immutable
Cache-control: stale-while-revalidate=<seconds>
Cache-control: stale-if-error=<seconds>
Understanding browser networking: Caching
cache-control
Good practice: cache assets forever and change name when you need a new version
Understanding browser networking: Caching
conditional GET
1 - The server send the Etag header as key of a resource (not the only method)
2 - The browser asks for the same resource sending the Etag received previously
3 - If the resource didn't change the server respond with a 304: Not modified
HTTP/1.1 304 Not Modified
Date: Sat, 09 Feb 2013 16:09:50 GMT
Server: Apache/2.2.22 (Ubuntu)
Last-Modified: Sat, 02 Feb 2013 12:02:47 GMT
ETag: "c0947-b1-4d0258df1f625"
Understanding browser networking: Caching
Main page is never cached
You can change default behaviour using
Understanding browser networking: Compression
HTTP1.1 can optionally compress the data (gzip for example)
Understanding browser networking: Redirects
Very useful but may hurt performance
HTTP/1.1 301 Moved Permanently
Location: http://www.example.org/
Content-Type: text/html
Content-Length: 174
Understanding browser networking: Chunked encoding
In HTTP1.0 resources uses content-length header
You have to wait to reach that length before reading and parsing the resource
From HTTP1.1 you can use transfer-encoding: chunked
Resources can be parsed without waiting to be fully loaded
Increase number of parallel transmissions
Transmit cookies only from and to a single domain
HTTP2: They are antipatterns!!!!
HTTP2 multiplexing allows parallel transmissions
HPACK header compression avoid sending cookies more than once
HTTP1:
Mythbusting
HTTP2 or 3: use server push
HTTP1: faster because no extra request (no caching)
Mythbusting
HTTP2: still important but smaller bundles (more granular caching)
HTTP1: faster and more efficient
Mythbusting
To be continued ....
Parsing and rendering: HTML
*HTTP chunked transfer encoding
Parsing and rendering: HTML
Phase 0: preparsing
Super fast scan of the document searching for resources to download
Parsing and rendering: HTML
Phase 1: parsing
The browser builds the DOM. But it stops on blocking resources.
The CSS should be parsed and the CSSOM built before proceding
JS should be executed before proceding
Parsing and rendering: HTML
Phase 2: rendering
The browser paints on the screen. An update of the CSSOM may trigger a repaint. The content too, but it is rare.
Parsing and rendering: HTML
but also of "client hints":
<link rel="dns-prefetch" href="//example.com">
<link rel="preconnect" href="http://css-tricks.com">
<link rel="preload" href="image.png">
Preparser initiate the download of:
<script src="script.js"></script>
<link rel="stylesheet" href="main.css"/>
<img src="image.jpg"/>
Parsing and rendering: CSS
It blocks the parsing and it can't be parsed progressively.
It can be loaded asynchronously using javascript (but it has to be done cleverly to be picked up by the preparser)
<link
rel="preload"
href="path/to/mystylesheet.css"
as="style"
onload="this.rel='stylesheet'">
Parsing and rendering: CSS
Any resource referenced by the CSS is downloaded only when the rule matches
Example: img tag vs background-image CSS rule
img is always downloaded!
Parsing and rendering: CSS
Minified css is faster to download and parse
Browsers allow link and style tags in the body. It should only block the html underneath
It is also a good idea bundling many css together
Parsing and rendering: JS
It blocks the parsing (unless asynchronous) and it can't be parsed progressively.
Parsing and rendering: JS
It can be an antipattern during page load (no preparser involved)
<script>
var script = document.createElement('script');
script.src = "//somehost.com/awesome-widget.js";
document.getElementsByTagName('head')[0].appendChild(script);
</script>
Parsing and rendering: JS
async: execute as soon as it is ready
defer: execute when html parse is over (it retains the original ordering, but not for inline scripts)
The image is misleading. Download is initiated by the preparser
Parsing and rendering: JS
works the same as defer
It enables ESM in the browser (import)
imported modules are bad news for performance, unless you use something like this:
<script type="module">
import {addTextToBody} from './utils.mjs';
addTextToBody('Modules are pretty cool.');
</script>
<link rel="modulepreload" href="./utils.mjs">
Parsing and rendering: JS
JS can be minified and bundled
Big bundles takes longer to download/parse/execute
Different scripts depending from each others require to be executed in order (no async attribute)
Parsing and rendering: images
They never block rendering but:
Trigger a repaint if width and height are not specified
Parsing and rendering: images
Progressive JPEG improve speed perception
Parsing and rendering: fonts
They don't block but text is not rendered if font missing
Parsing and rendering: fonts
You can wait to have the font and then apply the font
Parsing and rendering: fonts
The default pattern to download the font is terribly inefficient
better (also avoids foit/fout)
This works but defeat caching
CSS font-display
@font-face {
font-family: "Open Sans Regular";
font-weight: 400;
font-style: normal;
src: url("fonts/OpenSans-Regular-BasicLatin.woff2") format("woff2");
font-display: swap;
}
Webkit and Mozilla only (no IE or old edge)
Parsing and rendering: fonts
Note: woff fonts are binary and are subjected to same domain policy
No worries you can use CORS
This is going to cost you an extra round trip!
Mythbusting
busted
Mythbusting
partially busted (not on load)
Mythbusting
True: even if content is gzipped verbose js and css is longer to decompress and parse
Questions?