This is a tracking task for improving page load performance of MediaWiki-powered page views. The scope and objective of this task is to reduce time durations as observed through metrics of the Paint Timing API (first-paint, and first-contentful-paint) and front-end metrics of the Navigation Timing API (responseEnd, domInteractive, domComplete, and loadEventEnd). We also care about the following perceptual metrics: "time to logo", "time to text", "time to first image", "time to interaction".
https://www.w3.org/TR/paint-timing/
https://www.w3.org/TR/navigation-timing-2/
The critical path is defined here as all downloading, parsing and execution in the browser up until loadEventEnd (when the browser's native loading indicator finishes), or the last visual change (whichever happens later). From a network perspective, this involves the following resources:
- One HTML document.
- One or more (blocking) stylesheets.
- Zero or more images requests that started before onload.
- Zero or more (async) JavaScript requests that started before onload.
Category: Improve caching
Improving the cachability of web responses used in the critical path.
Expected impact on repeat views (not first views):
- For any resources:
- Consume less bandwidth (reduces mobile data costs).
- Consume less power (no cell-radio activation required).
- For stylesheets:
- Improvement of all paint metrics. Cached stylesheets load faster without network roundtrip, allowing rendering to happen earlier.
- Reduce time to domComplete and loadEventEnd metrics. Stylesheets are subresources part of DOM completion.
- For JavaScript:
- Reduce "Time to Interactive". Cached scripts load (and parse) faster.
Tasks:
Category: Reduce 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 to rough skin layout and a bit of the article text. And do so in a way that isn't later moved around (more components may load later, but existing components should not move).
Vagues:
- Reduce amount of per-page header bloat (e.g. RLQ, mw.config, mw.loader).
- More minification of CSS, JavaScript and HTML within the <head>.
Tasks:
- Remove the header script for user.options. – T176159: Skip mw.loader.implement() boiler plate for no-op user.options
- Remove the header stylesheet for user.cssprefs.
- Remove uer.cssprefs module entirely. Change last use case (editfont user-css pref) to trigger via body-class instead. – T145015, 2c688cfb11ea6.
- Make user.cssprefs only load if settings vary from default. – T105313 eddbcab08aa8
- Remove editsection user-css pref. – T54811, f6aa7b3.
- Remove showtoc user-css pref. – T54813, aadd16aa.
- Remove justify user-css pref. – T54810, 2f9cfa3d26
- T36289: UserOptionsModule styles are loaded twice
- Move sidebar/header to above page content.
Category: Reduce size of stylesheet
Reducing the size of the main (blocking) stylesheet loaded by the HTML.
Expected impact on all views:
- Improvement of all paint metrics. Smaller stylesheets load and parse faster, allowing rendering to happen earlier.
- Reduce time to domComplete and loadEventEnd metrics. Stylesheets are subresources part of DOM completion.
- Consume less bandwidth (reduces mobile data costs).
- Consume less power (reduce CPU time for stylesheet parsing).
Tasks:
- Make JS aware of loaded stylesheets. – T87871: Loading with addModuleStyles() should set module state to "ready"
- Defect: Don't load user/site styles twice. – T108590: User and site CSS loaded twice
- Depended on T87871.
- Defect: Don't load gadget styles twice. – T42284: The CSS of each gadget is included two times
- Depended on T87871.
- Defect: Don't load user.options styles twice. T36289: UserOptionsModule styles are loaded twice
- Add detection for unused @embed. – T121144: Add detection for unused @embed data uris
- Remove unused @embed. – T121730: Audit use of @embed and remove where not needed (2019)
- CSSMin: Add minification for embedded SVG image icons. – T175318: Optimize SVGs in data URIs
- CSSMin: T36812: Implement minification for SVG files in ResourceLoader
Category: Reduce size of scripts
Reducing the amount of scripts loaded by default as part of the startup module, the base modules (jquery mediawiki), or module that are pre-loaded on a page. 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 domComplete and loadEventEnd metrics. These scripts are sub resources part of DOM completion.
- Consume less bandwidth (reduces mobile data costs).
Tasks:
- Audit all currently deployed modules for unused dependencies. – T159911: Audit modules (2017)
- Reduce size of startup manifest (tracking). – T202154: Audit modules 2018: Reduce registry overhead
- ...
Category: Reduce 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:
- https://github.com/wilsonpage/fastdom
- https://developers.google.com/web/fundamentals/performance/rendering/optimize-javascript-execution#use_requestanimationframe_for_visual_changes
- https://developers.google.com/web/fundamentals/performance/rendering/avoid-large-complex-layouts-and-layout-thrashing#avoid_forced_synchronous_layouts
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 loadEventEnd metrics. These finishing of initial scripts' execution holds back "loadEvent".
Tasks:
- Audit all currently deployed modules for common anti-patterns in their definition or initialisation code (such as opportunities for preloading, and avoiding forced style calculations). – T159911: Audit modules (2017)
- Consolidate top and bottom script queues. – T109837: Remove top/bottom queue distinction
- T142129: Source code eval should be async in mw.loader.work
- Avoid unnecessary delays between the fetching and applying of dynamic styles. – T175866: Wikipedia triggers multiple 20ms browser hangs for restyles for separate "addEmbeddedCSS" calls
- ..
Category: Reduce latency
Try to find ways to reduce latency from a browser discovering a resource and requesting it, and the browser receiving the response. Either by making the response happen faster, or by making it start earlier.
- Add "preload" link for site logo. – T100999: Make the logo's loading priority higher
- Add "preload" link for base modules request. – T164299: Preload base modules request
- Add "preconnect" link for thumbnail host. – T123582: Use "preconnect" resource hint for thumbnail host
- T120984: Evaluate alternatives for @embed
Other
- T144070: Examine critical rendering path (DevTools Timeline analysis)
- Decrease TTL in Varnish and $wgSquidMaxage in wmf-config. – T124954: Decrease max object TTL in varnishes
- T176262: Consider adding mw.loader.preload / OutputPage::preloadModules()