A framework for web performance

Here at Clearleft, we’ve recently been doing some front-end consultancy. That prompted me to jot down thoughts on design principles and performance:

We continued with some more performance work this week. Having already covered some of the nitty-gritty performance tactics like font-loading, image optimisation, etc., we wanted to take a step back and formulate an ongoing strategy for performance.

When it comes to web performance, the eternal question is “What should we measure?” The answer to that question will determine where you then concentrate your efforts—whatever it is your measuring, that’s what you’ll be looking to improve.

I started by drawing a distinction between measurements of quantities and measurements of time. Quantities are quite easy to measure. You can measure these quantities using nothing more than browser dev tools:

  • overall file size (page weight + assets), and
  • number of requests.

I think it’s good to measure these quantities, and I think it’s good to have a performance budget for them. But I also think they’re table stakes. They don’t actually tell you much about the impact that performance is having on the user experience. For that, we need to enumerate moments in time:

  • time to first byte,
  • time to first render,
  • time to first meaningful paint, and
  • time to first meaningful interaction.

There’s one more moment in time, which is the time until DOM content is loaded. But I’m not sure that has a direct effect on how performance is perceived, so it feels like it belongs more in the category of quantities than time.

Next, we listed out all the factors that could affect each of the moments in time. For example, the time to first byte depends on the speed of the network that the user is on. It also depends on how speedily your server (or Content Delivery Network) can return a response. Meanwhile, time to first render is affected by the speed of the user’s network, but it’s also affected by how many blocking elements are on the critical path.

By listing all the factors out, we can draw a distinction between the factors that are outside of our control, and the factors that we can do something about. So while we might not be able to do anything about the speed of the user’s network, we might well be able to optimise the speed at which our server returns a response, or we might be able to defer some assets that are currently blocking the critical path.

Factors
1st byte
  • server speed
  • network speed
1st render
  • network speed
  • critical path assets
1st meaningful paint
  • network speed
  • font-loading strategy
  • image optimisation
1st meaningful interaction
  • network speed
  • device processing power
  • JavaScript size

So far, everything in our list of performance-affecting factors is related to the first visit. It’s worth drawing up a second list to document all the factors for subsequent visits. This will look the same as the list for first visits, but with the crucial difference that caching now becomes a factor.

First visit factors Repeat visit factors
1st byte
  • server speed
  • network speed
  • server speed
  • network speed
  • caching
1st render
  • network speed
  • critical path assets
  • network speed
  • critical path assets
  • caching
1st meaningful paint
  • network speed
  • font-loading strategy
  • image optimisation
  • network speed
  • font-loading strategy
  • image optimisation
  • caching
1st meaningful interaction
  • network speed
  • device processing power
  • JavaScript size
  • network speed
  • device processing power
  • JavaScript size
  • caching

Alright. Now it’s time to get some numbers for each of the four moments in time. I use Web Page Test for this. Choose a realistic setting, like 3G on an Android from the East coast of the USA. Under advanced settings, be sure to select “First View and Repeat View” so that you can put those numbers in two different columns.

Here are some numbers for adactio.com:

First visit time Repeat visit time
1st byte 1.476 seconds 1.215 seconds
1st render 2.633 seconds 1.930 seconds
1st meaningful paint 2.633 seconds 1.930 seconds
1st meaningful interaction 2.868 seconds 2.083 seconds

I’m getting the same numbers for first render as first meaningful paint. That tells me that there’s no point in trying to optimise my font-loading, for example …which makes total sense, because adactio.com isn’t using any web fonts. But on a different site, you might see a big gap between those numbers.

I am seeing a gap between time to first byte and time to first render. That tells me that I might be able to get some blocking requests off the critical path. Sure enough, I’m currently referencing an external stylesheet in the head of adactio.com—if I were to inline critical styles and defer the loading of that stylesheet, I should be able to narrow that gap.

A straightforward site like adactio.com isn’t going to have much to worry about when it comes to the time to first meaningful interaction, but on other sites, this can be a significant bottleneck. If you’re sending UI elements in the initial HTML, but then waiting for JavaScript to “hydrate” those elements into working, the user can end up in an uncanny valley of tapping on page elements that look fine, but aren’t ready yet.

My point is, you’re going to see very different distributions of numbers depending on the kind of site you’re testing. There’s no one-size-fits-all metric to focus on.

Now that you’ve got numbers for how your site is currently performing, you can create two new columns: one of those is a list of first-visit targets, the other is a list of repeat-visit targets for each moment in time. Try to keep them realistic.

For example, if I could reduce the time to first render on adactio.com by 0.5 seconds, my goals would look like this:

First visit goal Repeat visit goal
1st byte 1.476 seconds 1.215 seconds
1st render 2.133 seconds 1.430 seconds
1st meaningful paint 2.133 seconds 1.430 seconds
1st meaningful interaction 2.368 seconds 1.583 seconds

See how the 0.5 seconds saving cascades down into the other numbers?

Alright! Now I’ve got something to aim for. It might also be worth having an extra column to record which of the moments in time are high priority, which are medium priority, and which are low priority.

Priority
1st byte Medium
1st render High
1st meaningful paint Low
1st meaningful interaction Low

Your goals and priorities may be quite different.

I think this is a fairly useful framework for figuring out where to focus when it comes to web performance. If you’d like to give it a go, I’ve made a web performance chart for you to print out and fill in. Here’s a PDF version if that’s easier for printing. Or you can download the HTML version if you want to edit it.

I have to say, I’m really enjoying the front-end consultancy work we’ve been doing at Clearleft around performance and related technologies, like offline functionality. I’d like to do more of it. If you’d like some help in prioritising performance at your company, please get in touch. Let’s make the web faster together.

Have you published a response to this? :

Responses

Magnus

Customer: please make it faster Provider: where would you like to start? first arrival? Homepage? Account pages? Customer: yes please, make it fast.

# Posted by Magnus on Friday, September 21st, 2018 at 6:23pm

tommy george

“useful framework for figuring out where to focus when it comes to web performance.” - adactio.com/journal/14355 With optional, handy, downloadable fill-in-the-blank templates, if you’re into worksheet type things! 😃 —- Thanks @adactio!

40 Shares

# Shared by Dave Foresman on Thursday, September 20th, 2018 at 4:28pm

# Shared by A.J. Kandy on Thursday, September 20th, 2018 at 4:28pm

# Shared by Gorzas on Thursday, September 20th, 2018 at 4:29pm

# Shared by Dr Mark Everitt on Thursday, September 20th, 2018 at 4:31pm

# Shared by Chriztian Steinmeier on Thursday, September 20th, 2018 at 4:32pm

# Shared by Leonardo Toledo Sarmento Ribeiro on Thursday, September 20th, 2018 at 4:38pm

# Shared by Andrew Hiles on Thursday, September 20th, 2018 at 4:42pm

# Shared by Hennes on Thursday, September 20th, 2018 at 4:42pm

# Shared by Luis Calvo on Thursday, September 20th, 2018 at 4:42pm

# Shared by Carlos Molina on Thursday, September 20th, 2018 at 5:47pm

# Shared by Gareth Davies on Thursday, September 20th, 2018 at 6:58pm

# Shared by davenewman on Thursday, September 20th, 2018 at 6:58pm

# Shared by FE Performance on Thursday, September 20th, 2018 at 7:13pm

# Shared by WPO Berlin on Thursday, September 20th, 2018 at 7:17pm

# Shared by A Book Apart on Thursday, September 20th, 2018 at 7:36pm

# Shared by Afonso Pacifer on Thursday, September 20th, 2018 at 7:43pm

# Shared by Juan M Lopez on Thursday, September 20th, 2018 at 7:53pm

# Shared by Dan Johnson on Thursday, September 20th, 2018 at 8:08pm

# Shared by Chris Love - The PWA Guy 📳📱 on Friday, September 21st, 2018 at 9:20am

# Shared by Aleyda Solis on Friday, September 21st, 2018 at 9:26am

# Shared by Louise Amor on Friday, September 21st, 2018 at 10:36am

# Shared by Sergey Chernyshev on Friday, September 21st, 2018 at 3:37pm

# Shared by Planet Performance on Friday, September 21st, 2018 at 3:37pm

# Shared by Jens Grochtdreis on Friday, September 21st, 2018 at 6:14pm

# Shared by Steve Souders on Friday, September 21st, 2018 at 7:37pm

# Shared by Achinth Gurkhi on Friday, September 21st, 2018 at 7:42pm

# Shared by LUEshi@CEOtaku on Friday, September 21st, 2018 at 7:49pm

# Shared by Erlend ⚡️ Eide on Friday, September 21st, 2018 at 7:58pm

# Shared by An Event Apart on Saturday, September 22nd, 2018 at 3:29am

# Shared by Matteo Cargnelutti on Saturday, September 22nd, 2018 at 4:28am

# Shared by Jon Harvey on Saturday, September 22nd, 2018 at 8:31am

# Shared by Eli Silva Montgomery on Saturday, September 22nd, 2018 at 8:36am

# Shared by Rajashekhar Reddy Ch on Saturday, September 22nd, 2018 at 8:52am

# Shared by Patsy on Sunday, September 23rd, 2018 at 8:53pm

# Shared by Henri Helvetica ❇️ 200 on Monday, September 24th, 2018 at 11:49pm

# Shared by Courtney Akua on Monday, September 24th, 2018 at 11:58pm

# Shared by Simeon.__proto__ on Tuesday, September 25th, 2018 at 12:10am

# Shared by nedter nedt on Wednesday, September 26th, 2018 at 11:10am

# Shared by Brandt Kurowski on Thursday, September 27th, 2018 at 6:34pm

# Shared by Stefan Böck on Wednesday, October 3rd, 2018 at 8:30pm

137 Likes

# Liked by Chriztian Steinmeier on Thursday, September 20th, 2018 at 4:40pm

# Liked by Anas A. on Thursday, September 20th, 2018 at 4:40pm

# Liked by Pedro Menezes on Thursday, September 20th, 2018 at 4:40pm

# Liked by Christian Alden Jacobs on Thursday, September 20th, 2018 at 4:40pm

# Liked by Erik Vorhes on Thursday, September 20th, 2018 at 4:40pm

# Liked by Anomynous on Thursday, September 20th, 2018 at 4:40pm

# Liked by Jay 🇪🇺 on Thursday, September 20th, 2018 at 4:40pm

# Liked by Andy Bell on Thursday, September 20th, 2018 at 4:40pm

# Liked by Alex Carpenter on Thursday, September 20th, 2018 at 4:40pm

# Liked by 木贵 on Thursday, September 20th, 2018 at 4:40pm

# Liked by Leonardo Toledo Sarmento Ribeiro on Thursday, September 20th, 2018 at 4:40pm

# Liked by Dan Manchester on Thursday, September 20th, 2018 at 4:40pm

# Liked by Dave Foresman on Thursday, September 20th, 2018 at 4:40pm

# Liked by Andrew Hiles on Thursday, September 20th, 2018 at 5:10pm

# Liked by Luis Calvo on Thursday, September 20th, 2018 at 5:10pm

# Liked by Lydia Wozniak on Thursday, September 20th, 2018 at 5:10pm

# Liked by Web Design Smarty on Thursday, September 20th, 2018 at 5:10pm

# Liked by Mariam! on Thursday, September 20th, 2018 at 5:10pm

# Liked by Mark Jones on Thursday, September 20th, 2018 at 5:10pm

# Liked by Beyoncé Owles on Thursday, September 20th, 2018 at 5:10pm

# Liked by Andy Davies on Thursday, September 20th, 2018 at 5:10pm

# Liked by s1lentechoes on Thursday, September 20th, 2018 at 5:10pm

# Liked by vollepeer on Thursday, September 20th, 2018 at 5:45pm

# Liked by Thomas Morris on Thursday, September 20th, 2018 at 5:45pm

# Liked by Amy on Thursday, September 20th, 2018 at 5:45pm

# Liked by cuss pumpkin on Thursday, September 20th, 2018 at 5:45pm

# Liked by Jeff Bridgforth on Thursday, September 20th, 2018 at 5:45pm

# Liked by Nikita on Thursday, September 20th, 2018 at 5:45pm

# Liked by Dzhavat Ushev on Thursday, September 20th, 2018 at 5:45pm

# Liked by Rasmus Kaj on Thursday, September 20th, 2018 at 5:45pm

# Liked by trying my best on Thursday, September 20th, 2018 at 5:45pm

# Liked by aaron van ruler on Thursday, September 20th, 2018 at 6:15pm

# Liked by Mathias Rando Juul on Thursday, September 20th, 2018 at 6:15pm

# Liked by Fabio Venni on Thursday, September 20th, 2018 at 6:16pm

# Liked by Brett Evans on Thursday, September 20th, 2018 at 6:16pm

# Liked by Patrick Ashe on Thursday, September 20th, 2018 at 6:16pm

# Liked by Aron on Thursday, September 20th, 2018 at 6:16pm

# Liked by Marc Stalfoort on Thursday, September 20th, 2018 at 6:16pm

# Liked by Dilip Shukla on Thursday, September 20th, 2018 at 6:47pm

# Liked by Gareth Davies on Thursday, September 20th, 2018 at 7:21pm

# Liked by davenewman on Thursday, September 20th, 2018 at 7:21pm

# Liked by James Lindeman on Thursday, September 20th, 2018 at 7:21pm

# Liked by Ari Palo on Thursday, September 20th, 2018 at 7:49pm

# Liked by Afonso Pacifer on Thursday, September 20th, 2018 at 7:49pm

# Liked by Henrique Mirai on Thursday, September 20th, 2018 at 7:49pm

# Liked by Ghada Kandil on Thursday, September 20th, 2018 at 7:49pm

# Liked by Max Knee on Thursday, September 20th, 2018 at 7:49pm

# Liked by Joshua Iz on Thursday, September 20th, 2018 at 7:49pm

# Liked by studio.bio on Thursday, September 20th, 2018 at 7:49pm

# Liked by Sarah Dennis on Thursday, September 20th, 2018 at 8:14pm

# Liked by Ed O'Keeffe on Thursday, September 20th, 2018 at 8:14pm

# Liked by Graham Harper on Thursday, September 20th, 2018 at 8:14pm

# Liked by Vipascal on Thursday, September 20th, 2018 at 8:14pm

# Liked by Dan Johnson on Thursday, September 20th, 2018 at 8:14pm

# Liked by Denish Gandhi on Thursday, September 20th, 2018 at 8:14pm

# Liked by Maximiliano Firtman @ 🇮🇪 Dublin on Thursday, September 20th, 2018 at 8:14pm

# Liked by Juan C. Camus on Thursday, September 20th, 2018 at 8:14pm

# Liked by Far Left Jeff on Thursday, September 20th, 2018 at 8:42pm

# Liked by Juanjo Fernández on Thursday, September 20th, 2018 at 8:42pm

# Liked by Maya Benari on Thursday, September 20th, 2018 at 8:42pm

# Liked by Ryan Noon on Thursday, September 20th, 2018 at 9:08pm

# Liked by Simon St.Laurent on Thursday, September 20th, 2018 at 9:35pm

# Liked by YannPicarddeMuller on Thursday, September 20th, 2018 at 10:16pm

# Liked by NSJ on Thursday, September 20th, 2018 at 10:16pm

# Liked by Jon Brain on Thursday, September 20th, 2018 at 10:16pm

# Liked by J. Ky Marsh on Thursday, September 20th, 2018 at 10:48pm

# Liked by Claude Ayitey on Thursday, September 20th, 2018 at 10:48pm

# Liked by Tereza Kubátová on Thursday, September 20th, 2018 at 11:24pm

# Liked by Pavel Gerega on Thursday, September 20th, 2018 at 11:50pm

# Liked by Marc Drummond on Friday, September 21st, 2018 at 1:12am

# Liked by John F Croston III on Friday, September 21st, 2018 at 2:03am

# Liked by Boris Piqué on Friday, September 21st, 2018 at 8:41am

# Liked by Chris Love - The PWA Guy 📳 📱 on Friday, September 21st, 2018 at 9:46am

# Liked by Stephen on Friday, September 21st, 2018 at 9:46am

# Liked by Aleyda Solis on Friday, September 21st, 2018 at 9:46am

# Liked by David Gstrein 🤘 on Friday, September 21st, 2018 at 9:46am

# Liked by sleepOne on Friday, September 21st, 2018 at 10:53am

# Liked by twoskinz on Friday, September 21st, 2018 at 10:53am

# Liked by Simon Cox on Friday, September 21st, 2018 at 10:53am

# Liked by Hélio Correia on Friday, September 21st, 2018 at 1:23pm

# Liked by Peter Duncanson on Friday, September 21st, 2018 at 3:29pm

# Liked by Sergey Chernyshev on Friday, September 21st, 2018 at 4:02pm

# Liked by Nathan Bower on Friday, September 21st, 2018 at 4:02pm

# Liked by John Riviello on Friday, September 21st, 2018 at 4:28pm

# Liked by Jeff Posnick on Friday, September 21st, 2018 at 4:29pm

# Liked by Rowan Merewood on Friday, September 21st, 2018 at 4:56pm

# Liked by Jens Grochtdreis on Friday, September 21st, 2018 at 6:26pm

# Liked by Dennis Frank on Friday, September 21st, 2018 at 7:02pm

# Liked by Spillebeen Mathieu on Friday, September 21st, 2018 at 7:38pm

# Liked by Marijn de Römph on Friday, September 21st, 2018 at 7:38pm

# Liked by Derek on Friday, September 21st, 2018 at 7:38pm

# Liked by Alfredo Lopez on Friday, September 21st, 2018 at 8:11pm

# Liked by pawel_lekki on Friday, September 21st, 2018 at 8:11pm

# Liked by Jeremy Vanderlan on Friday, September 21st, 2018 at 8:11pm

# Liked by Benjamin Walsh on Friday, September 21st, 2018 at 8:11pm

# Liked by ant on Friday, September 21st, 2018 at 8:11pm

# Liked by Matthew Bennett on Friday, September 21st, 2018 at 8:11pm

# Liked by Massive Dadzone on Friday, September 21st, 2018 at 8:11pm

# Liked by LUEshi@CEOtaku on Friday, September 21st, 2018 at 8:11pm

# Liked by Zach Leatherman on Friday, September 21st, 2018 at 8:11pm

# Liked by Guilherme on Friday, September 21st, 2018 at 8:40pm

# Liked by Markus Köbel on Friday, September 21st, 2018 at 8:40pm

# Liked by kvervo on Friday, September 21st, 2018 at 9:44pm

# Liked by Jesse Ezell on Friday, September 21st, 2018 at 9:44pm

# Liked by Thejdeep on Friday, September 21st, 2018 at 10:14pm

# Liked by Slightly Warped on Friday, September 21st, 2018 at 10:14pm

# Liked by Franco Valentino on Friday, September 21st, 2018 at 11:11pm

# Liked by year of jubilee on Friday, September 21st, 2018 at 11:44pm

# Liked by roycifer on Saturday, September 22nd, 2018 at 4:35am

# Liked by Luke Hewlett on Saturday, September 22nd, 2018 at 4:35am

# Liked by Matteo Cargnelutti on Saturday, September 22nd, 2018 at 4:35am

# Liked by Steve Karsch on Saturday, September 22nd, 2018 at 4:35am

# Liked by Josh Barr on Saturday, September 22nd, 2018 at 4:35am

# Liked by Nelly on Saturday, September 22nd, 2018 at 5:33am

# Liked by KatSmith37 on Saturday, September 22nd, 2018 at 5:33am

# Liked by Benjy Stanton on Saturday, September 22nd, 2018 at 6:10am

# Liked by litenjacob on Saturday, September 22nd, 2018 at 8:15am

# Liked by Jon Harvey on Saturday, September 22nd, 2018 at 8:44am

# Liked by Ashish Kumar on Saturday, September 22nd, 2018 at 8:44am

# Liked by Rajashekhar Reddy Ch on Saturday, September 22nd, 2018 at 9:11am

# Liked by Travis Maynard on Saturday, September 22nd, 2018 at 12:58pm

# Liked by cloudsh on Saturday, September 22nd, 2018 at 2:37pm

# Liked by Michael Ewins on Saturday, September 22nd, 2018 at 6:12pm

# Liked by Jagdish Sonawane on Sunday, September 23rd, 2018 at 3:45am

# Liked by jeana on Sunday, September 23rd, 2018 at 7:54am

# Liked by Houssein Djirdeh on Monday, September 24th, 2018 at 11:56pm

# Liked by Ian Feather on Tuesday, September 25th, 2018 at 12:26am

# Liked by Simeon.__proto__ on Tuesday, September 25th, 2018 at 12:26am

# Liked by Katie Sylor-Miller on Tuesday, September 25th, 2018 at 12:53am

# Liked by LaQuita G 😎 on Tuesday, September 25th, 2018 at 12:54am

# Liked by A Web Dev in Dublin on Tuesday, September 25th, 2018 at 1:52am

# Liked by Tatiana Uspenskaia on Tuesday, September 25th, 2018 at 1:52am

# Liked by nedter nedt on Wednesday, September 26th, 2018 at 11:31am

# Liked by Leonidas Tsementzis on Wednesday, September 26th, 2018 at 11:32am

# Liked by Uldis Bojars on Wednesday, October 3rd, 2018 at 8:32pm

# Liked by Stefan Böck on Wednesday, October 3rd, 2018 at 8:32pm

# Liked by Kristof Neirynck on Monday, December 17th, 2018 at 6:31pm

Related posts

Speedier tunes

Improving performance with containment.

Speedy tunes

Improving performance on The Session.

The intersectionality of web performance

Business, sustainability, and inclusivity.

JavaScript

Inside me there are two wolves. They’re both JavaScript.

Portals and giant carousels

Trying to understand why people think they need to make single page apps.

Related links

Care

I know that the number one cause of jank and breakage is another developer having messed with the browser’s default way of doing things.

THIS!!! A thousand times, THIS!

Tagged with

What Is A Single-page Application?: HeydonWorks

You can’t create a complex modern web application like Google Mail without JavaScript and a SPA architecture. Google Mail is a webmail client and webmail clients existed some time before JavaScript became the language it is today or frameworks like Angular JS or Angular BS existed. However, you cannot create a complex modern web application like Google Mail without JavaScript. Google Mail itself offers a basic HTML version that works perfectly well without JavaScript of any form—let alone a 300KB bundle. But, still, you cannot create a complex modern web application like Google Mail without JavaScript. Just keep saying that. Keep repeating that line in perpetuity. Keep adding more and more JavaScript and calling it good.

Tagged with

JavaScript Bloat in 2024 @ tonsky.me

This really is a disgusting exlusionary state of affairs.

I hate to be judgy, but I honestly wonder how the people behind some of these decisions can call themselves web developers.

Tagged with

Cameron Dutro on ruby.social

Here’s the inside scoop on why Github is making a bizarre move from working web components to a legacy React stack.

Most of what I heard in favor of React was a) it’s got a good DX, b) it’s easy to hire for, and c) we only want to use it for a couple of features, not the entire website.

It’s all depressingly familiar, but it’s very weird to come across this kind of outdated thinking in 2023.

My personal prediction is that, eventually, the company (and many other companies) will realize how bad React is for most things, and abandon it. I guess we’ll see.

Tagged with

The Cost Of JavaScript - 2023 - YouTube

A great talk from Addy on just how damaging client-side JavaScript can be to the user experience …and what you can do about it.

Tagged with

Previously on this day

18 years ago I wrote Web Directions South

Australia, here I come.

20 years ago I wrote Dark side of the brain

I was having an iChat with a friend, who I had previously considered to be a reasonably well-adjusted chap, when he asked me out of the blue if I had heard that Pink Floyd’s Dark Side Of The Moon was an alternate soundtrack for The Wizard Of Oz.

22 years ago I wrote Angry Bed Positions

From the same man that brought you "things my girlfriend and I argue about" comes "angry bed positions".

22 years ago I wrote Would you like some tact with that?

How can we measure the cost of human life? What price freedom?

22 years ago I wrote Orisinal : Morning Sunshine

Here’s a collection of wonderfully cute Flash games for you to while away your time with.