Talk:ResourceLoader/Architecture

About this board

Mattflaschen (talkcontribs)

I removed the {{fixme}} in the styles section. Based on my testing locally and in prod (English Wikipedia), the docs mentioned are entirely correct. Even in production, in debug mode the CSS is loaded directly from the original static file(s). I also tested with uselang=he, and CSSJanus is not applied (there's no derivative file for debug mode that has been flipped).

This post was posted by Mattflaschen, but signed as Superm401.

Matma Rex (talkcontribs)
Mattflaschen (talkcontribs)

Good point. It turns out some CSS is loaded through ResourceLoader, and some is not. Your example demonstrates that, and I can also confirm that e.g. the GuidedTour CSS is not processed in debug mode even with uselang=he.

I'll update the fixme accordingly.

This post was posted by Mattflaschen, but signed as Superm401.

Krinkle (talkcontribs)

The distinction is that styles loaded by file modules from mw.loader trigger separate load.php requests that load each stylesheet from the direct file reference (not through load.php) which means that (as documented) no minification, embedding or flipping applies.

However there is one exception, and that is the Skin stylesheet. That stylesheet isn't loaded from mw.loader but from a hardcoded <link>-tag, which (obviously) has no javascript execution and as such goes through load.php and gets all the flipping applied.

Matma Rex (talkcontribs)

Is this expected behaviour? It seems pretty counterintuitive to me.

Krinkle (talkcontribs)

It is an unintended side-effect. It is known by design, but not really something we like.

This way simplifies the code a lot, but feel free to file a bug. It is certainly not desired behavior, but it was tolerable at the time (we were aware of it while implementing it).

The code has changed a lot since, maybe it is easier to fix now.

Reply to "Removed fixme"

Closures in debug mode?

3
Adamw (talkcontribs)

I was surprised by this detail listed in the "debug mode" section:

> Script resources: No longer minified, concatenated and loaded from load.php. Instead, load.php will instruct the client to request each source file directly. This makes debugging scripts easier with your browser's developer tools. Transformations such as closure don't apply, so scripts may execute in the global scope.

Relatedly, the JS coding conventions suggest that a namespace closure is mandatory around each file.

However, reading the implementation in ResourceLoader#makeLoaderImplementScript, I discovered that each file is automatically surrounded by a closure regardless of the debug flag. Also, some MediaWiki-core modules such as mediawiki.Title/Title.js are missing the closure. Experimenting with a local wiki confirms that the closure is always added around every file.

Based on this, shall we update the documentation to recommend no closures, to save a few bytes and a level of indentation?

Krinkle (talkcontribs)

Yes, and also no. It's complicated currently! In short:

  • Yes, files of package modules don't need file closures.
  • No, files of legacy modules may still need file closures.

The longer version:

[…] in ResourceLoader#makeLoaderImplementScript, I discovered that each file is automatically surrounded by a closure regardless of the debug flag.

The above is true, but the following is also true:

Debug mode: No longer […] loaded from load.php. […] the client request each file directly. This makes debugging easier. Transformations such as closure don't apply, so scripts may execute in the global scope.

Let's load the cookie module in debug mode. Here is what happens:

mw.loader.implement( "jquery.cookie@13ckt", [
    "/w/resources/lib/jquery.cookie/jquery.cookie.js?86bfb"
] );

This instructs the browser to load cookie.js directly from the source directory. It does not involve makeLoaderImplementScript or its closure maker. Debug mode promises that for a legacy module, the file names and line numbers in the browser will match your source code. This means we can't easily add a closure. This is why legacy files have global scope in debug mode. And for this reason, we have the convention of wrapping each file in their own closure. (For production this is indeed not needed, as you say.)

The mediawiki.Title module was ported to a Package module. These have can use relative file imports, virtual files, and per-file exports. These features require at least a basic form of encapsulation to work. This means we had to let go of the "debug mode is completely raw" here. It also has the happy side-effect that these files don't need a file closure. See what happens there:

mw.loader.implement( "mediawiki.Title@…", {
  main: "Title.js",
  files: {
    "Title.js": function ( require, module ) {
        
    },
    "phpCharToUpper.json": {
        
    }
  }
} );

See also T50886 and T85805, in which I propose to straight out this inconsistency.

Adamw (talkcontribs)

Thanks for the helpful explanation. I'll drop all closures after converting a module to packageFiles, and will follow T85805 because I'm also interested in the Webpack use case. This might be worth mentioning in the coding conventions doc, but it could also wait until everything is consistent.

Reply to "Closures in debug mode?"

Adding a link to toggle debug mode

2
He7d3r (talkcontribs)

Just in case someone find it useful: this script add a button to the sidebar to allow changing the mode easily using the cookie resourceLoaderDebug.

This post was hidden by Adamw (history)
Reply to "Adding a link to toggle debug mode"

Debug mode and VisualEditor

1
Winand (talkcontribs)

VisualEditor stucks on loading (progressbar value is 70%) unless I turn ON `debug` mode. There're no errors in console. I made a recording (from Chrome Performance tab) of both cases: https://yadi.sk/d/0Hn4f0JG3a2BAb

Maybe there's a problem with ResourceLoader?

System: MediaWiki 1.31, WAMPServer (PHP 7.2.8 + php_apcu, Apache 2.4.34), Windows 10 (32bit)

Reply to "Debug mode and VisualEditor"
Summary by Krinkle

ResourceLoader doesn't currently code explicitly for Server Push (there is not yet an established way to do so in PHP or Apache). But we also don't have a strong need for Server Push, and there are actually several problems with Server Push that can make things worse instead of better. Relatedly, we do support HTTP Preload, which is similar and has various benefits.

Alex Mashin (talkcontribs)

Is it or can it be enabled for ResourceLoader modules?

Jeblad (talkcontribs)

Push only works well for something that needs constant updating? Why would you update a RL module?

TheDJ (talkcontribs)

@Jeblad, no, that's not what push means in the context of HTTP/2. See also HTTP/2 Server Push.

The answer is, no it cannot be enabled for RL modules specifically. But we also don't need it as much, because we already have ResourceLoader (basically HTTP 2.0 push solves a problem that we already had to solve before http 2.0 became a thing). So while there are benefits to server push, we don't benefit as much of it as we would have, if we never would have had ResourceLoader.

If that makes sense.

Krinkle (talkcontribs)

As @TheDJ mentions, there isn't currently any code in ResourceLoader that relates to "Server Push" and we don't currently have a strong need to add explicit support for pushing responses given that we already have quite good performance without it.

Also, one should be careful with pushing resources because it can actually make performance worse. The main problem with Server Push is that it doesn't take into account the web browser's existing cache.

Without server push, the story is like this:

  • User visits their first page on a wiki.
  • User's web browser receives page HTML and makes subsequent requests for resources.
  • MediaWiki, being made for scale, allows these resources to be cached by the browser.
  • User visits another page on the wiki.
  • User's web browser receives page HTML and discovers urls for resources. Web browsers realises it has these in its cache already and makes 0 subsequent requests.

With basic server push, if you push the resources each time, it will saturate the bandwidth and therefore needlessly cause competition with other resources (such as images, and the HTML itself).

See also https://jakearchibald.com/2017/h2-push-tougher-than-i-thought/ and other articles about server push.

Lastly, note that in 2017, the Wikimedia Performance Team has introduces several uses of "preload" in MediaWiki and ResourceLoader. This browser feature is similar to push in that it allows telling a browser about a resource before it knows it needs it. The difference is that it makes the browser responsible for deciding to make a request, which means it works with browser cache.

Further reading:

There are no older topics
Return to "ResourceLoader/Architecture" page.