How fast is your website really?

Spoiler Alert

 User-Centric Performance

  Capture Metrics from End User Devices

⬛  Continuous Observability

Page Load event

const start = Date.now();

window.addEventListener('load', () => {
  console.log({ load: Date.now() - start });
});

Performance Inspector

Navigation Timing API

https://www.w3.org/TR/navigation-timing-2/

window.performance.timing

Adobe

Airbnb Inc

Akamai Technologies

Alibaba Group

Apple, Inc.

Baidu, Inc.

BBC

Cloudflare

Facebook

Fastly

Google LLC

Microsoft Corporation

Mozilla Foundation

Salesforce

Shopify

The New York Times

Wikimedia Foundation

W3C Web Performance Working Group

User Centric PerformancE

  • Perceived Load Speed
  • Load Responsiveness
  • Runtime Responsiveness
  • Visual stability
  • Smoothness

https://web.dev/user-centric-performance-metrics/

User-Centric PerformancE

https://web.dev/user-centric-performance-metrics/

TTFB

Time to First Byte

FCP

First Contentful Paint

LCP

Last Contentful Paint

FID

First Input Delay

INP

Interaction to Next Paint

CLS

Cumulative Layout Shift

https://developer.mozilla.org/en-US/docs/Glossary/time_to_first_byte

the time between the browser requesting a page and when it receives the first byte of information from the server.

TTFB

Time to First Byte

https://www.mindspun.com/blog/time-to-first-byte-ttfb/

TTFB

Time to First Byte

GOOD

POOR

NEEDS
IMPROVEMENT

800ms

1.8s

https://web.dev/ttfb/

TTFB

Time to First Byte

https://web.dev/fcp/

the time from when the page starts loading to when any part of the page's content is rendered on the screen...

FCP

First Contentful Paint

https://macklin.me/7-useful-tools-for-monitoring-web-performance-user-experience

FCP

First Contentful Paint

GOOD

POOR

NEEDS
IMPROVEMENT

1.8 sec

3.0 sec

https://web.dev/fcp/

FCP

First Contentful Paint

https://calibreapp.com/blog/largest-contentful-paint

...tracks how many seconds it takes for your page’s most data-intensive, above-the-fold element to load.

LCP

Largest Contentful Paint

https://macklin.me/7-useful-tools-for-monitoring-web-performance-user-experience

LCP

Largest Contentful Paint

GOOD

POOR

NEEDS
IMPROVEMENT

2.5 sec

4.0 sec

https://web.dev/lcp/

LCP

Largest Contentful Paint

https://web.dev/fid/

the time from when a user first interacts with a page[...] to the time when the browser is actually able to begin processing event handlers...

FID

First Input Delay

https://requestmetrics.com/web-performance/first-input-delay

FID

First Input Delay

GOOD

POOR

NEEDS
IMPROVEMENT

100ms

300ms

https://web.dev/fid/

FID

First Input Delay

https://web.dev/inp/

...represents a page's overall responsiveness by measuring all click, tap, and keyboard interactions made with a page.

INP

Interaction to Next Paint

https://web.dev/inp/

INP

Interaction to Next Paint

GOOD

POOR

NEEDS
IMPROVEMENT

200ms

500ms

https://web.dev/inp/

INP

Interaction to Next Paint

https://web.dev/cls/

[a calculated score] for every unexpected layout shift that occurs during the entire lifespan of a page...

CLS

Cumulative Layout Shift

https://macklin.me/7-useful-tools-for-monitoring-web-performance-user-experience

CLS

Cumulative Layout Shift

CLS

Cumulative Layout Shift

GOOD

POOR

NEEDS
IMPROVEMENT

0.1

0.25

https://web.dev/cls/

CLS

Cumulative Layout Shift

Core Web Vitals

https://developers.google.com/search/blog/2020/11/timing-for-page-experience

Atomicity

TTFB ≈ 50ms

FCP ≈ 500ms

LCP ≈ 1.625 sec

https://csswizardry.com/2022/08/measure-what-you-impact-not-what-you-influence/

https://web.dev/vodafone/

Case Studies

Goals

✅  User-Centric Performance

⬛  Capture Metrics from End User Devices

⬛  Continuous Observability

Ad-hoc Testing

Synthetic Monitoring

Real User Monitoring (RUM)

Capture Methods

Ad-hoc Testing

Lighthouse for
Google Chrome

Ad-hoc Testing

web.dev/measure

Ad-hoc Testing

👍  Free

👍  No setup required

👎  Once-off, manual tests only

👎  Unlikely to represent real world traffic

Synthetic Monitoring

Calibre

https://calibreapp.com/features/pull-request-reviews

Synthetic Monitoring

👍  CI/CD + scheduled automation

👍  Monitor change over time

👎  Not free

👎  Still not representative of real world traffic

Browser Engine

Blink

75%

Webkit

21%

Form Factor

Mobile

77%

Desktop

20%

https://infrequently.org/2021/03/the-performance-inequality-gap/#mind-the-gap

GEEKBENCH 4 Single-Core

The Performance INequality Gap

Moto E
710

iPhone 12
6940

~10x

https://infrequently.org/2021/03/the-performance-inequality-gap/#mind-the-gap

Environment Changes Performance

Alex Russel - Progressive Performance (Chrome Dev Summit 2016) https://www.youtube.com/watch?v=4bZvq3nodf4

4g is widely available

https://engineering.linecorp.com/en/blog/the-baseline-for-web-development-in-2022

86.8%

4g is Pulling us forward

https://www.speedtest.net/global-index/united-states

3G

4G

 <1 second

 ~2.3 seconds

4 second budget

4g Median Network Speed

18.0 Mb/s

177.0 Mb/s

~9.8x

https://www.speedtest.net/performance/australia/western-australia

4g Median Network Latency

144 ms

10 ms

~14.4x

https://www.speedtest.net/performance/australia/western-australia

Real User Monitoring (RUM)

Real User Monitoring (RUM)

Capturing performance metrics directly from devices to observe differences in functionality, reliability, and responsiveness.

Chrome User Experience Report

https://developers.google.com/web/tools/chrome-user-experience-report

👍  Free, publicly available data

👍  Real user monitoring

👎  Delayed, monthly aggregation

👎  Google Chrome devices only

Chrome User Experience Report

Core Web Vitals Checker

https://calibreapp.com/tools/core-web-vitals-checker

DDD Perth 2022
Sponsor Leaderboard

Pos Origin TTFB FCP LCP ⇩ FID INP CLS
- MakerX - - - - - -
- Valrose - - - - - -
- Sentient Computing - - - - - -

https://calibreapp.com/tools/core-web-vitals-checker

Pos Origin TTFB FCP LCP ⇩ FID INP CLS
16 Mantel Group 1.1s 2.5s 3.71s 10ms 135ms 0.03
17 MOQdigital 2.02s 2.79s 3.76s 12ms 125ms 0.31
18 Microsoft 1.65s 3.46s 3.88s 14ms 202ms 0.06
19 Family Zone 2.05s 3.99s 4.08s 13ms 141ms 0 ⭐️
20 VGW 😳 1.73s 2.85s 4.12s 69ms 523ms 0.09
21 Insight 1.87s 7.87s‼️ 7.45s‼️ 13ms 232ms 0.06
- MakerX - - - - - -
- Valrose - - - - - -
- Sentient Computing - - - - - -

https://calibreapp.com/tools/core-web-vitals-checker

Pos Origin TTFB FCP LCP ⇩ FID INP CLS
7 CyberCX 902ms 1.33s 2.13s 12ms 130ms 0.03
8 Elastic 933ms 2.03s 2.19s 7ms 71ms 0.11
9 AWS 867ms 1.97s 2.83s 23ms 258ms 0.05
10 Bankwest 577ms⭐️ 2.26s 2.9s 10ms 146ms 0.05
11 Auth0 1.11s 1.89s 3s 15ms 205ms 0.02
12 Telstra Purple 1.41s 2.76s 3.22s 5ms⭐️ 84ms 0.05
13 Bunnings 2.26s‼️ 2.94s 3.57s 127ms‼️ 992ms‼️ 0.13
14 Planit 2.06s 3.04s 3.66s 14ms 117ms 1‼️
15 Twilio 1.41s 2.92s 3.68s 16ms 222ms 0.04

https://calibreapp.com/tools/core-web-vitals-checker

Pos Origin TTFB FCP LCP ⇩ FID INP CLS
🥇 Github 995ms 1.43s 1.73s⭐️ 8ms 83ms 0.03
🥈 DDD Perth 1.15s 1.28s⭐️ 1.81s 12ms 144ms 0.05
🥉 First Mode 994ms 1.63ms 1.93s 11ms 82ms 0.08
4 Keystart 1.11s 1.46s 1.97s 12ms 193ms 0.02
5 Versent⭐️ 737ms 1.32s 2.07s 7ms 62ms⭐️ 0⭐️
6 CyberCX 902ms 1.33s 2.13s 12ms 130ms 0.03

https://calibreapp.com/tools/core-web-vitals-checker

Goals

✅  User-Centric Performance

✅  Capture Metrics from End User Devices

⬛  Continuous Observability 

User Centric Performance Capture Metrics from Real Users Continuous Observability
window.onload()
Google Lighthouse
Calibre
Chrome User Experience Report
Web Vitals Checker
???

Can we Build It Ourselves?

web-vitals

https://github.com/GoogleChrome/web-vitals

import { sendToAnalytics } from './';
import { getTTFB, getFCP, getLCP, getFID, getINP, getCLS } from 'web-vitals';

getTTFB(sendToAnalytics);
getFCP(sendToAnalytics);
getLCP(sendToAnalytics);
getFID(sendToAnalytics);
getINP(sendToAnalytics);
getCLS(sendToAnalytics);

window.addEventListener(`securitypolicyviolation`, sendToAnalytics);
window.addEventListener(`error`, sendToAnalytics);

web-vitals

export const sendToAnalytics = data => {

  const body = JSON.stringify(data);

  // Use navigator.sendBeacon() if available, fall back to fetch().
  (navigator.sendBeacon 
  	&& navigator.sendBeacon('/analytics', body)) 
  	|| fetch('/analytics', { 
      method: 'POST', keepalive: true, body,
    });
}

web-vitals

import express from 'express';
import { Summary } from 'prom-client';

const ttfb = new Summary({ name: `ttfb_summary`, help: `summary for ttfb web vital`, labelNames: [`path`] });
const fcp =  new Summary({ name: `fcp_summary`,  help: `summary for fcp web vital`, labelNames: [`path`] });
const lcp =  new Summary({ name: `lcp_summary`,  help: `summary for lcp web vital`, labelNames: [`path`] });
const fid =  new Summary({ name: `fid_summary`,  help: `summary for fid web vital`, labelNames: [`path`] });
const inp =  new Summary({ name: `inp_summary`,  help: `summary for inp web vital`, labelNames: [`path`] });
const cls =  new Summary({ name: `cls_summary`,  help: `summary for cls web vital`, labelNames: [`path`] });

express()
  .post(`/analytics`, (req, res) => {
    const { path, body: { metric, value } } = req;
    switch (metric) {
      case `TTFB`: ttfb.labels(path).observe(value); break;
      case `FCP`:  fcp.labels(path).observe(value);  break;
      case `LCP`:  lcp.labels(path).observe(value);  break;
      case `FID`:  fid.labels(path).observe(value);  break;
      case `INP`:  inp.labels(path).observe(value);  break;
      case `CLS`:  cls.labels(path).observe(value);  break;
    }
    res.status(200).send({});
  })
  .listen(8000);

Analytics Server

Prometheus + Grafana

Grafana

Prometheus

GET /metrics

POST /analytics

Analytics Service

Data Analytics

Amazon S3

Amazon Kinesis Firehose

Snowflake

POST /analytics

Analytics Service

Recap

✅  User-Centric Performance

✅  Capture Metrics from End User Devices

✅  Continuous Observability

Macklin Hartley

         @macklin_hartley

         macklin.me

Resources

Metrics

Tools

Questions?

How Fast is your Website Really?

By Macklin Hartley

How Fast is your Website Really?

I presented this talk at DDD Perth 2022. Watch the talk here; https://macklin.me/talk-how-fast-is-your-website-really

  • 376