Page MenuHomePhabricator

Make top queue fully asynchronous
Closed, ResolvedPublic


📘 See also Perf Matters at Wikipedia on our blog.

We should get rid of this last remaining synchronous part of ResourceLoader (aside from the stylesheet request).

Performance metrics, timelines and waterfalls clearly identify our blocking/synchronous top queue (startup module and the first dynamic load request) as a major pitfall blocking the first paint.

This is especially bad considering our pages are actually fully built server-side. The rare few exceptions to this are isolated to run-time features or enhancements based on user-interaction. Not the first paint.


  • Move handling of client-nojs/client-js to a new place (embedded in HTML instead of in a top-loading module).
    • Also requires it to be refactored to work without access to isCompatible from the startup module. Let's swap the class unconditionally, and add it back at runtime if needed (applies to browser that are unsupported but support some level of JavaScript).
  • Make modules=startup request asynchronous.
    • Refactor base modules request inside startup (for jquery/mediawiki) to use DOM (async) instead of document.write.
    • Refactor embedded script tags to buffer their statements into a queue instead of running immediately.
  • Make top mw.loader.load() queue asynchronous.
    • Remove synchronous handling from mw.loader class.
  • T102077: Load legacy modules "site" and "user" asynchronously.
    • Ensure "user" will still execute after "site".
  • Disabling "legacy" gadgets (T75810: Require all gadgets to load via ResourceLoader):

Related Objects

Event Timeline

There are a very large number of changes, so older changes are hidden. Show Older Changes

Issues uncovered so far:

  • T107979 – VE load order had a race condition that was much more common with async; fixed thank to Krinkle/Roan.
  • T107980 – Above-the-fold FOUC for VE edit tab (showstopper in my POV)
  • T107968 – Looks/looked like a mw.EmbedPlayer issue but was being masked by T107979; now seems gone, but no merges in the past few hours?
  • unfiled – At least twice VE gave the 'anon' notice (so mw.user.isAnon() presumably returned false) despite depending on mediawiki.user; not yet reliably reproducible.
  • unfiled – Dozens of times, VE causing Chrome to crash tab (unrelated?)
  • unfiled – RESTbase fetch via load.php seems to be failing at times (unrelated?)

Change 229994 had a related patch set uploaded (by Krinkle):
resourceloader: Async all the way

Change 229994 merged by Ori.livneh:
resourceloader: Async all the way


I've seen anouncements on Wikitech-ambassadors about the document.write breaking change, but nothing about legacy gadgets which as far as the French Wikipedia is concerned breaks much more things.

Sorry if I missed it, but now there seems to be a lot of stuff to unbreak there, since about 30 gadgets have never been ported to ResourceLoader.

Anyway, congratulations for the improvements!

Seems to have caused T108359 (broken iframe embedding for audio/video files)... I can fix it using window.RLQ directly but that feels dirty... proper fix is to rewrite the iframe embedding entirely to not be weird and scary, I'll probably do that later. :)

Can we measure how long does it take for a styled page to appear (and the difference between this and the "first to display" could be the FOUC factor)?

Apart from T115692 I have seen reports that it takes a very long time to load and style the page right after the first install and also for a first time when visiting an previously not visited wiki.

Also which got featured in tech talks at various conferences over the past few months (incl. Velocity 2015 New York, and Chrome Dev Summit 2015).

capture.png (914×1 px, 248 KB)

(Paper trail: this change was the cause of T110501.)