@SimonHearne

Web Performance Workshop

Simon Hearne

Web Performance Consultant

Agenda

  1. Introduction
  2. Measuring Performance
  3. Network
  4. Devices
  5. Images
  6. JavaScript
  7. CSS & Fonts
  8. Caching
  9. Third-party Content
  10. Automation
  11. Advanced Concepts

We know that speed matters

The BBC loses an additional 10% of users for every additional second it takes to load
Pinterest improved load time by 40% and saw 15% increase in SEO traffic and 15% increase in conversions
Financial Times added a one second delay to every page view and saw a 4.9% drop in the number of articles users read over a 7 day window
For every 100ms decrease in homepage load speed, Mobify's customer base saw a 1.11% lift in session based conversion

wpostats.com/tags/engagement/

Speed is a ranking factor

Speed is now a landing page factor for Google Search and Ads

Everyone is impacted by site speed

SEO
Product
Marketing
Operations
Development
User Experience
Business Intelligence

But who owns it?

Measuring Performance

Measurement:

  • Rule-based
  • Ad hoc
  • Synthetic
  • Real User
  • Application

Measurement:

  • Rule-based

Google Lighthouse

In Chrome Developer Tools / Audits

developers.google.com/web/tools/lighthouse/#devtools

Google Lighthouse

developers.google.com/web/tools/lighthouse/#cli

Google PageSpeed Insights

developers.google.com/speed/pagespeed/insights/

PageSpeed is a Ranking Factor

Calibre | How PageSpeed Works

Measurement:

  • Rule-based
  • Ad hoc

Developer Tools

Identify large & slow resources

Developer Tools

Identify rendering & JavaScript bottlenecks

Works on real devices too

developers.google.com/web/tools/chrome-devtools/remote-debugging/

WebPageTest.org

webpagetest.org

WPT Waterfall

Analyse resources over the network.

Amazon.com Waterfall

WPT Filmstrip

Compare visual output to the network waterfall.

Amazon.com Filmstrip

Host your own WPT

Test internal environments, bulk tests, API key management.

WPT Private Instances

Ad Hoc Summary

  • Results in seconds
  • High level of detail
  • Does not scale well
  • Relies on device emulation

Measurement:

  • Rule-based
  • Ad hoc
  • Synthetic

Synthetic Monitoring

Actively measure performance

Regular tests on fixed pages / journeys, using browsers hosted on servers.

Good for testing availability and infrastructure performance.

Synthetic Monitoring Tools

* other services are available

Synthetic Summary

  • Tests production environment
  • Active monitoring 24x7
  • Lab testing - easy to spot changes
  • Small number of test locations
  • Does not measure user experience
  • Difficult to test pre-production

Measurement:

  • Rule-based
  • Ad hoc
  • Synthetic
  • Real User

Real User Monitoring (passive)

Collect performance data from every visitor

Real User Monitoring Tools

* other services are available

Real User Monitoring Summary

  • Measures real user experience!
  • Correlate performance with business metrics
  • Global coverage
  • Requires implentation in client-side code
  • May be blocked by tracker blockers
  • Can only measure in production

Measurement:

  • Rule-based
  • Ad hoc
  • Synthetic
  • Real User
  • Application

Application Performance Measurement (APM)

APM Tools

* other services are available

APM Summary

  • Code-level profiling
  • Database query profiling
  • Architecture discovery
  • Priced per server / VM
  • Limited / no view of UX

Measurement:

  • Rule-based
  • Ad hoc
  • Synthetic
  • Real User
  • Application

Browser APIs

Provide data for synthetic & real user monitoring

  • Navigation Timing API
  • Resource Timing API
  • User Timing API

Navigation Timing API

Resource Timing API

* only total duration for crossorigin requests without timing-allow-origin response header

User Timing API

Browser APIs

  • Navigation Timing API - page load timings
  • Resource Timing API - individual resource performance
  • User Timing API - bespoke performance measures for you

The Network

A simple example...

WebPageTest.org

Network requests are complex

Network Fundamentals

  • DNS
  • TCP
  • TLS
  • HTTP/1.1
  • HTTP/2
  • Congestion Control
  • HTTP/3

Network Fundamentals

  • DNS

DNS Performance

  • Increase TTL to 24 - 48h
  • Use a high-performance DNS provider
  • Pre-connect additional domains*

* <link rel="dns-prefetch" href="//thirdparty.com"/>

Network Fundamentals

  • DNS
  • TCP

TCP Performance

Reducing tound-trip latency *

  • Use a CDN!
  • Re-use connections
  • Keep requests < 14kb (one packet on most networks)

* optimising RTT benefits all stages

Network Fundamentals

  • DNS
  • TCP
  • TLS

TLS 1.3

TLS 1.3

Approximately 50% faster than TLS 1.2!

TLS 1.3 Performance Features

  • Session Resumption
  • TLS False Start
  • 0-RTT

Network Fundamentals

  • DNS
  • TCP
  • TLS
  • HTTP/1.1

HTTP/1.1

  • Six connections per host
  • No header compression
  • FIFO downloads

HTTP/1.1 Performance Challenges

  • Keeping requests smaller than one packet
  • Maximising use of connections

HTTP/1.1 Performance Techniques

  • Shard across domains
  • Bundle resources
  • Sprite images
  • Cookie-less domains for static content

Network Fundamentals

  • DNS
  • TCP
  • TLS
  • HTTP/1.1
  • HTTP/2

HTTP/2

  • One connection per host
  • HPACK header compression
  • Downloads multiplexed on connection

HTTP/1.1 vs HTTP/2

HTTP/2 Performance Challenges

  • Minimising impact of packet loss
  • Prioritising resources
  • Managing browser behaviour

HTTP/2 Performance Techniques

  • Defer non-critical content
  • Increase initial congestion window

Network Fundamentals

  • DNS
  • TCP
  • TLS
  • HTTP/1.1
  • HTTP/2
  • Congestion Control

TCP Congestion Control

Finding the maximum safe bandwidth on a connection

*HTTP/2 only has one connection per domain, packet loss has a greater impact than HTTP/1.x

Fraida Fund | TCP congestion control in lossy wireless networks

TCP Congestion Control

Ensure that your HTML document (including response headers) fits comfortably into your initial congestion window (initcwnd * 1400B)

Tyler Cipriani | The 14KB In The TCP Initial Window

Network Fundamentals

  • DNS
  • TCP
  • TLS
  • HTTP/1.1
  • HTTP/2
  • Congestion Control
  • HTTP/3

HTTP/3

Rewriting the network layer

Network Fundamentals

  • DNS
  • TCP
  • TLS
  • HTTP/1.1
  • HTTP/2
  • Congestion Control
  • HTTP/3

Other Optimisations

  • Resource Hints
  • Priority Hints
  • Lazy Loading

Resource Hints

<link rel="dns-prefetch|preconnect|prefetch|preload" href="...">
  • dns-prefetch - resolve hostname as soon as possible
  • preconnect - establish TCP & TLS connection
  • prefetch - download this when you're ready
  • preload - download this as soon as possible!

* use with caution - too many can break browser prioritisation and make a page slower!

MDN | Preloading Content

Priority Hints

Tell the browser what is important

<link rel="dns-prefetch|preconnect|prefetch|preload" href="...">

Available in Chrome 74 as origin trial, general availability in Chrome 76

Google Developers | Priority Hints

(Native) Lazy Loading

Free up the network for critical resources

<img loading="auto|eager|lazy" src="...">
<iframe loading="auto|eager|lazy" src="..."></iframe>
                        

Addy Osmani | Native image lazy-loading for the web!

Images

The rise of Images

HTTP Archive | State of Images

The rise of Images

Desktop Image Bytes are up 330% since 2011

Mobile Image Bytes are up 1050% since 2011

HTTP Archive | State of Images

Bitmap vs. Vector

Bitmap (PNG / JPG)

Grid of pixels, does not scale well

Vector (SVG)

Shapes defined in XML, scales infinitely!

Bitmap Scaling

150px

20kB

300px

27kB

450px

86kB

Vector Scaling

150px

18kB

300px

18kB

450px

18kB

Choose Appropriate Formats

Photo Imagery

JPG
(lossy compression)

Icons & Graphics

SVG / PNG(lossless compression)

Animations

GIF / CSS(lossless compression)

Browser-Specific Formats

Chrome & Opera

Safari

Internet Explorer

Baseline vs. Progressive JPEGs

Faster Photos in Facebook for iOS

Optimising JPEG Images

Optimising PNG Images

Optimising SVG Images

Responsive Images

Responsive web design gives us an image problem.

Responsive Images: srcset

Send the right DPR image, e.g. 1x to desktop & 2x to retina

<img src="src.png" srcset="1x.png 1x, 2x.png 2x, 3x.png 3x, 4x.png 4x">

Responsive Images: srcset

You probably don't need > 2x?

Visual acuity and device-pixel-ratio

Responsive Images: srcset

Send an image scaled to the viewport

<img src="medium.jpg" srcset="medium.jpg 500w, large.jpg 1000w, extralarge.jpg">

Responsive Images: srcset

Is the viewport relevant to image size?

Responsive Images: srcset

Including responsive breakpoints


                            <img src="medium.jpg" srcset="medium.jpg 800w, large.jpg" sizes="(max-width: 800px) 100vw, 33vw">
                      

Responsive Images: <picture>

Art direction for different displays


                                <picture>
                                <source srcset="wide.png" media="(min-width: 800px)">
                                <img src="slim.png" srcset="slim.png">
                                </picture>
                          

<picture> & srcset

It gets complicated...


                        <picture>
                            <source srcset="xsmall.jpg 1x, xsmall@2x.jpg 2x" media="(max-width: 37.4375em)">
                            <source srcset="small.jpg 1x, small@2x.jpg 2x" media="(min-width: 37.5em) and (max-width: 64.4375em)">
                            <source srcset="medium.jpg 1x, medium@2x.jpg 2x" media="(min-width: 64.5em) and (max-width: 79.9375em)">
                            <source srcset="large.jpg 1x, large@2x.jpg 2x" media="(min-width: 80em) and (max-width: 119.9375em)">
                            <source srcset="xlarge.jpg 1x, xlarge@2x.jpg 2x" media="(min-width: 120em)">
                            <img src="medium.jpg">
                        </picture>
                        

Responsive Images: client hints

Perform content selection on the server / CDN

developers.google.com | Automating Content Selection with Client Hints

Lazy-Loading Images

<img loading="auto|eager|lazy" src="...">

Allows the browser to determine which images to download immediately, based on viewport and connection speed.

Available in Chrome 76, polyfill with lazysizes.js

Addy Osmani | Native image lazy-loading for the web!

Images Summary

  • Send different images based on device requirements
  • Defer non-critical images
  • Select format & compression to minimise bytes

JavaScript

JavaScript

You’re building your own maze, in a way,
and you might just get lost in it.

Marijn Haverbeke, Eloquent JavaScript: A Modern Introduction to Programming

The rise of JavaScript

HTTP Archive | State of JavaScript

The rise of JavaScript

Desktop JavaScript is up 350% since 2011

Mobile JavaScript is up 650% since 2011

HTTP Archive | State of JavaScript

The cost of JavaScript

  • Downloading the files
  • Parsing the content
  • Compiling the code
  • Executing

Devices are unequal

The Cost of JavaScript in 2019

Optimisation Techniques

  • ES Modules
  • Dynamic Import
  • Bundle Analysis & Tree Shaking
  • Optimising for the Event Loop

Measuring JavaScript Performance

  • Use a low-end device

CSS & Fonts

Caching

Cache control headers

  • cache-control
  • last-modified
  • etag
  • pragma
  • expires
  • last-modified

Cache forever

Use for immutable, versioned assets. Best possible caching!


cache-control: immutable, max-age=31536000
  • Do not revalidate, even on page reload
  • Cache for up to a year

Cache, with revalidation (1)

Use for assets which may change. Validation uses an extra round-trip.


cache-control: max-age:86400
ETag: "33a64...f89d4"

  • Cache for up to a day
  • Serve cached asset if ETag matches

Cache, with revalidation (2)

Use for assets which may change. Validation uses an extra round-trip.


cache-control: max-age:86400
Last-Modified:

  • Cache for up to a day
  • Check if the resource has changed

Forced revalidation

Use for frequently updated assets (feeds, product lists)


cache-control: no-cache
ETag: "33a64...f89d4"

  • Do not use without validation
  • (must include a last-modified or ETag header)

Don't cache!

Use for sensitive responses (set-cookie, user-specific)


cache-control: no-store
  • Do not store anything about the response

Caching Summary

Google Web Fundamentals | HTTP Caching

CDN Considerations

  • stale-while-revalidate
  • vary
  • no-transform

Devices 📱

Device Characteristics:

  • Screen resolution (DPR)
  • Processing (CPU & RAM)
  • Mobile Network
  • Browsing Context

Device Characteristics:

  • Screen resolution (DPR)

Device Characteristics:

  • Screen resolution (DPR)
  • Processing (CPU & RAM)

Device Characteristics:

  • Screen resolution (DPR)
  • Processing (CPU & RAM)
  • Mobile Network

Device Characteristics:

  • Screen resolution (DPR)
  • Processing (CPU & RAM)
  • Mobile Network
  • Browsing Context

Device Characteristics:

  • Screen resolution (DPR)
  • Processing (CPU & RAM)
  • Mobile Network
  • Browsing Context

Third-party Content

Third-party scripts account for
>70% of requests

requestmap.webperf.tools

Tags serve business goals

  • Measurement & Analytics
  • Ads & Retargeting
  • Optimisation & Testing
  • Comments & Live Chat
  • Tag Management

Blocking tags create availability risk

<script src="//code.jquery.com/jquery-1.7.1.min.js"></script>

Single Point of Failure blank screen duration:
Windows: 30s | Android: 60s | MacOS: 75s | iOS: 75s

WebPageTest | businessinsider.com

Tags create performance risk

Main thread blocked for over six seconds by Campaign Monitor

Tags can cause frustration!

1.6s delay on click event, caused by third-party scripts

Tags can cost us $£€ 😱

Guardian | BA faces £183m fine over passenger data breach

Managing Third Parties

  • Subresource Integrity
  • Content Security Policy
  • Reporting API
  • Self-hosting & Proxying
  • Service Worker

Subresource Integrity

Validate resources against a crypto hash.
Protects against malicious code changes, not poor performance!


                            <script 
                            src="//thirdparty.com/script.js"
                            integrity="sha256-ivk71nXhz9nsyFDoYoGf2...=">
                            </script>

MDN | Subresource Integrity

Content Security Policy

Only allow scripts / images / frames from pre-approved domains


                                Content-Security-Policy:
                                default-src 'self';
                                img-src *;
                                media-src media1.com media2.com;
                                script-src userscripts.example.com
                            

MDN | Content Security Policy

Reporting API

Validate resources against a crypto hash.
Protects against malicious code changes, not poor performance!


                                Report-To:
                                {
                                    "group": "csp-endpoint",
                                    "max_age": 10886400,
                                    "endpoints": [{
                                        "url": "https://example.com/csp-reports"
                                    }]
                                },{
                                    "group": "network-endpoint",
                                    "max_age": 10886400,
                                    "endpoints": [{
                                        "url": "https://example.com/network-errors"
                                    }]
                                },{
                                    "max_age": 10886400,
                                    "endpoints": [{
                                        "url": "https://example.com/browser-errors"
                                    }]
                                }

MDN | Subresource Integrity

Self-hosting & Proxying

Serve third party content from your domain

Optimizely self-hosting for Akamai users

Service Worker

Time out slow responses


                                    function timeout(delay) {
                                        return new Promise(function(resolve, reject) {
                                            setTimeout(function(){
                                                resolve(new Response('', {
                                                    status: 408,
                                                    statusText: 'Request timed out.'
                                                }));
                                            }, delay);
                                        });
                                    }
                                    
                                    self.addEventListener('fetch', function(event) {
                                        if (/\.js$/.test(event.request.url)) {
                                            event.respondWith(Promise.race([timeout(2000), fetch(event.request.url)]));
                                        } else {
                                            event.respondWith(fetch(event.request));
                                        }
                                    });

Akamai | 5 ways to prevent slow 3rd party front-end services

Managing Third Parties

  • Subresource Integrity - protects from malicious code
  • Content Security Policy - only run expected code
  • Reporting API - report on code erros & CSP violations
  • Self-hosting & Proxying - maintain control of delivery
  • Service Worker - race third parties against timeouts

Automation

Tooling

  • Adhoc
  • CI / CD
  • Alerting

Adhoc Tooling

YellowLab Tools
WebPageTest
RequestMap

Advanced Concepts

Bring on the workers!

  • Web Worker
  • Service Worker
  • Edge Worker

Web Worker

  • 100% extra threads! 💯
  • Logical separation of compute vs. UI
  • postMessage communication is slow
  • Only ArrayBuffers can be transferred for free

Service Worker

  • Can serve content when offline
  • Proxy third-party requests and apply timeouts
  • Augment requests to add context (e.g. image width)
  • Does not work for first view
  • Only one permitted per domain
  • Hard to test & debug

Edge Worker

  • Logic at the edge means ⬇️ latency
  • Offload expensive logic from the client
  • Lack of standards = vendor lock-in
  • Basic functionality only - geo / user agent / cookies

Worker Summary

  • Web Worker - offload intensive JS to another thread
  • Service Worker - a JS proxy in your browser
  • Edge Worker - serverless at the edge

Web Assembly (WASM)

CSS Paint API

Thank you 🙏

simon@hearne.me

simonhearne.com/presentations/workshop/