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.
Tracking:
- 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):