Profiling your Website’s Performance

Tom Grant
Hackers at Cambridge
9 min readFeb 9, 2020

Speed is important for any website; all users would rather have snappy load times, smooth animations, and low input latencies. However, quantifying this can be deceptively challenging — there is no *accurate* metric for user experience. As a result, it’s up to the developers to balance the various performance characteristics to meet the subjective needs of their users.

Although there are some good general practices such as in-lining code and minifying resources, these techniques can only provide so much benefit. It’s important to first understand where the performance bottleneck is so a tailored solution can be produced.

The Naive Approach

When a web browser loads a new page, it has to complete a number of steps before the website is visible and interactive. First it makes web requests to download the essential resources: the HTML, the render-blocking CSS, and the JavaScript. After all these resources have been downloaded, the browser can begin to visibly render the page. While rendering, the browser uses its freed bandwidth to focus on lower priority downloads — such as images and non-essential JavaScript files. Since these resources are much larger than the essential components they take longer to download, and as a result are deferred until everything essential is already in place. This means browsers can render the majority of the important content before these downloads have finished — significantly improving render times.

After the page has rendered and the final network request has been resolved, the browser considers the page to be loaded and calls the window.onload event to tell the page’s JavaScript that everything is ready. Because of this, measuring the time from the user’s initial request to the window.onload event has become a convenient and standard way to measure a page’s load time across all platforms and web browsers.

To find the load time of a page the following JavaScript can be placed at the top of the site’s header. It uses the window.onload event listener to measure the time between the initial HTML parse and a complete page load.

Measures the time between script parsing and the onload event

Furthermore, most browsers contain tools that can be used to measure the time from the initial request to the onload event. This is more accurate than measuring with pure JavaScript since the browser can also time the initial HTML response. In Chrome, the onload event is found by choosing the ‘Trace’ option in the ‘Audits’ tab of the DevTools.

Finding the onload time with Chrome. It is 430ms here

Unfortunately, despite its universal compatibility and simplicity, the onload event is rarely the best metric to measure a page’s performance. This is because in most scenarios, the user is able to view and interact with the website before every image has been downloaded —sometimes even before the whole DOM has been processed. As a result, it is often important to consider other performance characteristics that affect the user experience more significantly — such as the time to interactivity and the speed at which the page gets populated.

Lighthouse

There are an overwhelming number of tools to measure a website’s performance. However, the one I’ll be talking about is Google’s Lighthouse which now comes packaged with the Chrome browser. Lighthouse is Google’s attempt at quantifying the overall performance of a website by reporting on a number of metrics each of which is designed to measure a different aspect of the user experience. Depending on your website’s demographic and content, the most impactful metric will vary. Knowing this, the Lighthouse team do not claim their overall score completely represents the real world performance of a website and instead provide many finer tools to profile a few of the most important performance considerations.

This is only the tip of the iceberg though, Lighthouse can also suggest improvements to SEO, modern web design, and accessibility. Even if you’re happy with your website’s performance, it’ll still be able to give you some pretty insightful feedback; Lighthouse is definitely worth running even if you only want to see how your website performs against others.

Lighthouse can be found under the “Audits” tab of the DevTools.

Shows lighthouse which is found under the audits tab of the chrome DevTools
Lighthouse simulates the environment you specify

Here Lighthouse allows you to specify the environment which it’ll simulate and the audits which it’ll perform. Right now, I am only interested in improving desktop performance, however there is no limit to the number of audits you can run, so feel free to try them all. I’ve also selected the “Simulated Slow” option which performs significantly faster audits (4s rather that 15s) while normally remaining similarly accurate to the “Applied Slow”.

Running the audits give the following results.

Lists the audit metrics: First Paints, Time to Interactive, First CPU Idle, and Max input delay
Results of lighthouse’s audit

That’s quite a bit of jargon! Luckily its well documented :-D… click on expanded text to the right if you want to read the descriptions.

These metrics focus on different aspects of the loading process, ideally you would maximize all their scores. However, this is not always possible so compromises sometimes need to be made.

First contentful paint measures the time it takes the browser to begin visibly rendering the webpage; this shows the user that the page is actually loading. The content that gets rendered at this stage is unimportant since it only matters that the user sees some progress: it could be as simple as the background color updating or as complex as a custom loading splash screen.

This first paint can only happen after the browser has finished downloading and parsing the page’s HTML, render-blocking CSS, and Javascript. As a result, the first contentful paint depends on network speed and file size — caching essential files and reducing their complexity will improve the contentful paint performance.

2 seconds — fast: (75 percentile), 4 seconds — moderate (50th percentile), Slow (Below)
Lighthouse scoring of first contentful paint

First meaningful paint measures the time it takes the browser to display the page’s primary content (normally the largest visible element). This is the point that the page becomes useful to the user; they can see the layout and begin reading content. Improving the meaningful paint performance can make the overall load times feel substantially shorter since the user can see what the page looks like and even begin interacting with the site before all elements have finished loading.

First meaningful paint times can be improved similarly to first contentful paint times; reducing files size and complexity. However, there are also a number of methods to optimize the critical rendering path in order to prioritize the loading of large visible resources and make the website look better faster.

2 seconds — fast: (75 percentile), 4 seconds — moderate (50th percentile), Slow (Below)
Lighthouse scoring of first meaningful paint

Speed index is a measure of how fast the websites DOM gets rendered — pages with shorter speed indices will appear to populate and stabilize faster. This is desirable, especially for mobile users who can begin scrolling at this point without the page’s elements jumping around. After the time specified by the speed index, the page will appear fully loaded and the user can begin queuing their interactions. However, speed index is not equivalent to load time since images haven’t necessarily finished downloading (their size is known due the metadata which is downloaded before the rest of the image). Additionally, non-critical deferred CSS and Javascript may still be downloading in the background at this point.

4.3 seconds — fast: (75 percentile), 5.8 seconds — moderate (50th percentile), Slow (Below)
Lighthouse scoring of speed index

First CPU idle (also called First Interactive) measures the time until the page is capable of handling the majority of user inputs in a “reasonable” amount of time. This normally happens shortly after the first meaningful paint — the point where some inputs actually become available and enough of the site is visible to interact with. Although basic functionality such as scrolling and hyperlink navigation are likely to become available at this point, more complex behavior such as custom JavaScript event listeners might still be unavailable.

In sites where the render time is severely limited by CPU performance — as might be the case on slower hardware rendering complex a DOM, the first CPU idle could happen after the entire page has finished loading. This could look like the site has crashed since the user will be unable to navigate or interact (depending on the device). This can be avoided by simplifying the site’s structure and rendering only the most important content first.

4.7 seconds — fast: (75 percentile), 6.5 seconds — moderate (50th percentile), Slow (Below)
Lighthouse scoring of First CPU Idle

Time to Interactive measures the time until the user can meaningfully interact with the majority of the site with delays of under 50ms. Unlike the ‘CPU idle’ metric, Time to Interactive (TTI) requires the First contentful paint to have finished and most of the Javascript event listeners to have been registered. A page with a high TTI may appear to be fully loaded despite not yet being interactive, this is harmful to user experience since there isn’t necessarily a clear indication that the page’s logic is still invisibly loading and requires the user to wait. As a result, when nothing happens on interaction, it could be unclear to the user that the page just isn’t ready yet.

Time to interactive is particularly dependent on a page’s JavaScript performance; reducing the size of the JavaScript required to register the important event listeners as well as minimizing the number of libraries imported during the initial page load can have a large impact on this metric.

Under 5.2 seconds — fast (75th percentile). Under 7.3 seconds moderate (50th percentile)
Lighthouse scoring of Time to Interactive

Max Potential First Input Delay measures the maximum possible delay a user can experience after they attempt to interact with an element on the page. Lighthouse calculates this by measuring the duration of the longest task that can be performed after the first contentful paint — chosen because the user is unlikely to attempt interaction before any content has loaded. This metric affects user experience in a similar way to the ‘First CPU Idle’ and ‘Time to Interactive’ metrics with a longer time indicating a less responsive website.

Potential First Input Delay can be improved in similar ways to the other interactivity metrics; reducing the unnecessary JavaScript and simplifying the DOM in order to reduce the main thread’s workload. However, unlike the other metrics, First Input Delay can also be improved by focusing on the execution times of the tasks themselves rather than the whole page. For example, on slower devices, it might be beneficial to disable animations (or other expensive visual features such as blurs) to leave more of the device’s resources available to handle individual inputs.

Lighthouse scoring of Max Potential First Input Delay

Interestingly, Google claims these input delays were chosen based on human psychology — our perception of latency while interacting with static elements. Their research shows that responding to user input in under 100ms feels immediate and anything longer results in a slightly perceptible delay that leads to a fragmented experience. This research provides a good goal to work towards since it shows that its often beneficial to optimize inputs — regardless of First Input Delay — to response times of under 100ms. Additionally, it shows that after reaching this performance, it’s probably worthwhile to focus on other performance characteristics rather than continuing to make imperceivable improvements.

Conclusion:

Although Lighthouse is definitely a useful tool, its far from the only way to profile a website’s performance. Many other solutions exist which each have there own strengths and weaknesses. For example, JavaScript interactivity can be thoroughly profiled using Firefox’s Flame Chart and dynamic network requests can be easily visualized using Chrome’s Network Waterfall.

Hopefully this article has helped demonstrate that user experience depends on more than just page load time: it’s a complex and subjective concept that consists of many interconnected characteristics — it’s impossible for one metric to definitely measure a website’s performance. However, being aware of some of the important metrics will hopefully give you the tools you need to profile and improve your website.

In Summary:

  • Show the user something is happening —anything is better than nothing, just render it fast.
  • Become usable ASAP —show the important stuff first and reduce non-essential resources.
  • Respond to all interactions — even if the page hasn’t loaded, it should still acknowledge the user.

--

--