Wikimedia Performance Team/Page load performance

This document describes aspects of a web page that impact page load performance, and what results can be expected when those aspects are improved. This was originally drafted in February 2016 (T127328) and was revised in October 2018.

We focus in particular on the following three metrics:


 * Visual rendering: Most of the page should render to completion as quickly as possible. Observed through the Paint Timing API (first-paint, first-contentful-paint).
 * Total page load time: The load indicator in web browsers, tracks the download and rendering of HTML document and the download and initial execution of its sub resources (JS, CSS, IMG). Observed through the Navigation Timing API (domComplete, loadEventEnd).
 * Responsiveness: When interacting with the page it should not lag or freeze. Measuring uncertain, but experimentally possible via Time-To-Interactive (in synthetic tests) and potentially via the Long Tasks API.

HTTP caching
Improving the cachability of responses to web requests used in the critical path, is expected to have the following impact:


 * First views: None.
 * Repeat views:
 * For any resources:
 * Consume less bandwidth (reduces mobile data costs).
 * Consume less power (no cell-radio activation required).
 * For CSS files:
 * Improvement of all paint metrics. Cached stylesheets load faster without network roundtrip, allowing rendering to happen earlier.
 * Reduce time to  and   metrics. Stylesheets are subresources part of DOM completion.
 * For JavaScript files:
 * Reduce "Time to Interactive". Cached scripts load (and parse) faster.

Size of HTML payload
Reducing the size of the main HTML payload. Specifically, we're focussing on the first 14 KB of the HTML (TCP slow-start), which should ideally contain everything needed to render the skin layout and a bit of the article text. And it should do so in a way that isn't later moved around (more components may appear later, but existing components should not change position).

For example:


 * Reduce amount of per-page header bloat, e.g.  tags, RLQ, mw.config, mw.loader.
 * Better minification for inline CSS, inline JavaScript and HTML within the.
 * Arranging the HTML to ensure layout and start of content render first.

Size of stylesheets
Reducing the size of the main (blocking) stylesheet loaded by the HTML, is expected to have the following impact:


 * All views (first view, and repeat view):
 * Improvement of all paint metrics. Smaller stylesheets load and parse faster, allowing rendering to happen earlier.
 * Reduce time to  and   metrics. Stylesheets are subresources part of DOM completion.
 * Consume less bandwidth (reduces mobile data costs).
 * Consume less power (reduce CPU time for stylesheet parsing).

Size of scripts
Reducing the amount of scripts loaded by default as part of the startup module and base modules. This does not include scripts that are lazy-loaded after document-ready.

Expected impact on all views:


 * Reduce "Time to Interactive". Less code to download, parse, and execute.
 * Reduce time to  and   metrics. These scripts are sub resources part of DOM completion.
 * Consume less bandwidth (reduces mobile data costs).

The scripts happen in three major phases. Earlier phases naturally have a bigger impact when improved because it allows later phases to start sooner:


 * 1) Inline scripts in HTML   (including page configuration, page module queue, and the async request to the Startup module).
 * 2) The Startup module (including module registry, module dependency tree, site configuration, and the mw.loader client source code).
 * 3) The page modules (the source code of modules loaded on the current page, and their dependencies).

Processing cost of scripts
Reduce the amount of time spend in executing JavaScript code during the critical path. This includes:


 * Deferring work that does not need to happen before rendering.


 * Splitting up work in smaller idle-time chunks to avoid blocking the main thread for too long (non-interactive "jank").


 * Re-arranging code so that there are no style reads after style writes in the same event loop. The browser naturally alternates between a cycle of JS execution and a cycle of style computation and rendering. If styles are changed in the main JS cycle and then read back within that same cycle, the browser is forced to pause the script and perform an ad-hoc render cycle before being able to resume the script. See also:
 * wilsonpage/fastdom (github.com
 * Use requestAnimationFrame for visual changes (Web Fundamentals, Google Developers)
 * Avoid forced synchronous layouts (Web Fundamentals, Google Developers)

Expected impact on all views:


 * Reduce "Time to Interactive". Less execution before the page is ready. Less uninterrupted execution which blocks interactions Fewer "forced synchronous layouts" which significantly slow down code execution.
 * Reduce time to  metrics. These finishing of initial scripts' execution holds back "loadEvent".

Reduce latency
Try to find ways to reduce latency from a browser discovering a resource and requesting it, and the browser receiving the response.

Mainly in two ways:


 * 1) By making the response complete sooner. For example by improving backend response times on the server, or by improving network routing, or by adding data centres closer to the user.
 * 2) By making the request start earlier. For example, with the "dns-prefetch", "preconnect" and "preload" instructions.