Page MenuHomePhabricator

ResourceLoader: Module loaded with addModules should load CSS even when JavaScript is disabled
Closed, DeclinedPublic

Description

The discussion on https://gerrit.wikimedia.org/r/74662 has ballooned because of this bug.

addModules(), when called on a module that has no JavaScript, is something I'd expect to work everywhere. But, when JS is disabled, evidently the CSS doesn't get loaded, because addModules() loads everything, even CSS, via JavaScript.

It might take some creativity, but is there a way we can load JS and CSS via a More Normal Method that would not necessarily require JavaScript? Maybe, if there's some good reason for not loading CSS if JS doesn't load, we could add a 'requireJavascript' => true option to the module definition array.

This is an optimistic bug report - I suspect that we'll continue doing this "wrong" (in my opinion) for the near future. If I'm thinking about it wrong and there's a better way to be able to rely on the ResourceLoader while maintaining compatibility with no-js clients, I'd love to hear it.

Thanks!


Version: unspecified
Severity: normal

Details

Reference
bz52718

Event Timeline

bzimport raised the priority of this task from to Needs Triage.Nov 22 2014, 2:05 AM
bzimport set Reference to bz52718.
bzimport added a subscriber: Unknown Object (MLST).

I could swear that there was already a bug for this, but I can't for the life of me find it.

  • bug 34904 is relevant.
  • also related, bug 29693 - When you do load using both addModules and addModuleStyles CSS is double-loaded since the JS can't understand the css is already in the page.

Btw, just to add insult to injury; bug 45229, addModuleStyles may sort modules alphabetically. So you can load your css via addModules and have it show up in order but not work for users without JS. Or your can load your css via addModuleStyles and have it show up for users without JS but take a chance that the addModuleStyles may screw up the load order potentially breaking your css (in addition to completely excluding yourself from the ability to have dependencies).

The solution for these issues I've been thinking of is:

  • Add something like a data-modules attribute to styles added server-side so that the JS loader can understand what css has already been loaded.
  • Add a new RL key to mark modules whose css should be loaded directly via <link> rather than using JS. We can then deprecate addModule{Scripts,Styles}
  • Start doing minimal dependency handling on the server so that when you mark a module to be loaded server side, css for modules it depends on (at least the ones that also say should be loaded server side) will actually be loaded instead of loaded by JS.

I won't close this bug yet to allow for elaboration in case I misunderstood the use case.

From what I can this bug is simply invalid and acting on wrong premises.

Loading a module, especially if the module contains both javascript and CSS, means both are acting in conjunction and one is useless if not problematic without the other.

If you have stylesheets that apply to content generated and output server-side and those stylesheets are critical for basic consumption of the content, those stylesheets should be put in a separate module and that module loaded through addModuleStyles.

The reason you don't want to use addModuleStyles is probably because you want to have what addModules does, which is dependency resolution and max cache urls.

The reason addModuleStyles can't give you that is because there is no way to both output html that is max cachable and also have that url contain the dependencies and timestamps.

So we can only have:

  1. mw.loader.load calls that then (through data from the startup module) grab dependencies and construct max cache urls (30 days+) with timestamps). aka addModules.

or:

  1. <link modules=...> without dependencies or timestamps, cached for a relatively short duration (1 day, 1 hour, 30 min, 5 min, whatever your RL cache maxage config is for unversioned load.php requests. aka addModuleStyles.

The only option I see here would be if we use ESI, which right now doesn't seem to be on the horizon just yet, And even then we probably shouldn't use it to something that has no fallback (e.g. with ESI dependencies and without ESI no dependencies is unacceptable, afaik we should only use ESI to enhance, not make things possible).

By fallback I mean when ESI is unavailable, misconfigured or simply not installed on the third party web server.

A possible enhancement would be to at least give the addModuleStyles urls a timestamp, that would make them perform much better.

Also note that you should be aware of something else: We do not actively care even the tiniest bit (aside from regular access to information and reading pages) about clients without javascript. Get over it, it's 2013.

If it wasn't for Opera 11 (or Opera 12) not supporting <noscript><link/></noscript> we would've dropped non-JS support entirely and even load addModuleStyles with javascript.

(In reply to comment #2)

I won't close this bug yet to allow for elaboration in case I misunderstood
the use case.

Closing, pretty sure I understood the question.