r100497 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r100496‎ | r100497 | r100498 >
Date:04:32, 22 October 2011
Author:liangent
Status:resolved (Comments)
Tags:
Comment:
Move styles in gadgets to the top of pages to avoid flash of unstyled content.
Those styles should be loaded after site and user styles to keep B/C.
Modified paths:
  • /trunk/extensions/Gadgets/Gadgets_body.php (modified) (history)

Diff [purge]

Index: trunk/extensions/Gadgets/Gadgets_body.php
@@ -11,7 +11,7 @@
1212 * @license GNU General Public Licence 2.0 or later
1313 */
1414
15 -class GadgetHooks {
 15+class GadgetHooks extends OutputPage {
1616 /**
1717 * ArticleSaveComplete hook handler.
1818 *
@@ -150,10 +150,12 @@
151151 $lb->setCaller( __METHOD__ );
152152 $pages = array();
153153
 154+ $styles = array();
154155 foreach ( $gadgets as $gadget ) {
155156 if ( $gadget->isEnabled( $wgUser ) && $gadget->isAllowed( $wgUser ) ) {
156157 if ( $gadget->hasModule() ) {
157 - $out->addModules( $gadget->getModuleName() );
 158+ $styles[] = $gadget->getModuleName();
 159+ $out->addModuleScripts( $gadget->getModuleName() );
158160 }
159161
160162 foreach ( $gadget->getLegacyScripts() as $page ) {
@@ -162,6 +164,9 @@
163165 }
164166 }
165167 }
 168+ $out->addHeadItem( 'ext.gadget', $out->makeResourceLoaderLink( $styles,
 169+ ResourceLoaderModule::TYPE_STYLES
 170+ ) );
166171
167172 $lb->execute( __METHOD__ );
168173

Follow-up revisions

RevisionCommit summaryAuthorDate
r100500Followup r100497: Indention tweakliangent05:59, 22 October 2011
r101827Followup r100497: Fix stuff described thereliangent16:11, 3 November 2011
r106007Followup r100497, r101827: use another way which doesn't look that hacky to l...liangent10:41, 13 December 2011

Comments

#Comment by Liangent (talk | contribs)   04:34, 22 October 2011

I have to extends OutputPage to use $out->makeResourceLoaderLink as it's protected. Since GadgetHooks is used statically only I see no harm.

I remember there was a bug report about this but I cannot find it now.

#Comment by Catrope (talk | contribs)   11:41, 25 October 2011

This should be reverted and done properly, by overriding ResourceLoaderModule::getPosition() in GadgetResourceLoaderModule.

#Comment by Catrope (talk | contribs)   11:44, 25 October 2011

Hmm, wait, it's not that easy. This is about loading just the styles in the head, not the scripts.

#Comment by Catrope (talk | contribs)   11:44, 25 October 2011

Still, what's wrong with using $out->addModuleStyles() here? Why must you use $out->addHeadItem() in conjunction with makeResourceLoaderLink()?

#Comment by Liangent (talk | contribs)   13:07, 25 October 2011

Styles added by $out->addModuleStyles() are loaded together with other RL styles. Gadget modules are in 'other' group, and in OutputPage.php, it says (in comments): "So the order has to be other, dynamic, site, private, user" so Gadget modules will be loaded firstly if they're added with $out->addModuleStyles(). However some of our existing gadgets depend on the fact that gadget styles are loaded after site (and maybe user) styles so site styles can be overridden. So I have to place gadget styles in HeadItems so they can be loaded after other styles which are loaded in CssLinks.

#Comment by Catrope (talk | contribs)   11:45, 25 October 2011

Also, the way this revision implements things, scripts will be loaded in the head as well, due to the usage of addModuleScripts(). This was probably unintended, right?

(I'm sorry for the comment flood.)

#Comment by Liangent (talk | contribs)   13:11, 25 October 2011

In my test, scripts are still loaded at the end. MediaWiki r100693.

#Comment by Catrope (talk | contribs)   13:14, 25 October 2011

Oh, right, I forgot what addModuleScripts does exactly.

Still, the way it's being done here is not optimal. I'll think about a better way to do this.

#Comment by Catrope (talk | contribs)   12:04, 3 November 2011

It looks like the addModuleScripts() usage here is breaking dependency resolution:

[11:53:18] <Beau_>	is resource loader or gadgets extension broken in trunk ? 
[11:53:34] <RoanKattouw>	Why?
[11:53:46] <Beau_>	it ignores dependencies
[11:54:06] <Beau_>	I have a gadget depending on mediawiki.util
[11:54:14] <Beau_>	and it gets loaded before it
[11:54:24] <RoanKattouw>	That's strange
[11:54:34] <RoanKattouw>	What's the definition for that gadget in Gadgets-definition?
[11:54:53] <Beau_>	* wikibugs [ResourceLoader | default | dependencies=mediawiki.util,mediawiki.user,jquery.ui.dialog] | JsMwApi.js | wikibugs.js | wikibugs.css
[11:57:34] <Beau_>	RoanKattouw: I have turned on debug and i get: [http://p.defau.lt/?_2Ca6g5lRMNdgLDM6IkqUA http://p.defau.lt/?_2Ca6g5lRMNdgLDM6IkqUA]
[11:57:44] <Beau_>	without debug it does not work either

Content of pastie:

<script src="[http://localhost/mwdev/load.php?debug=true&lang=pl&modules=ext.gadget.wikibugs&only=scripts&skin=vector&* http://localhost/mwdev/load.php?debug=true&lang=pl&modules=ext.gadget.wikibugs&only=scripts&skin=vector&*]"></script>
<script src="[http://localhost/mwdev/load.php?debug=true&lang=pl&modules=skins.vector&only=scripts&skin=vector&* http://localhost/mwdev/load.php?debug=true&lang=pl&modules=skins.vector&only=scripts&skin=vector&*]"></script>
<script>if(window.mw){
    mw.loader.load(["mediawiki.user", "mediawiki.util", "mediawiki.page.ready", "mediawiki.legacy.wikibits", "mediawiki.legacy.ajax", "mediawiki.action.watch.ajax", "ext.proofreadpage.article"]);
}

(bah, the CR parser is screwing up the URLs, but the point should be clear)

#Comment by Liangent (talk | contribs)   16:17, 3 November 2011

Fixed in r101827. I was wrong that I thought styles in gadgets are loaded after site and user css (actually they're loaded before those in both ResourceLoader and non-ResourceLoader gadgets), so it's safe to use addModuleStyles.

Since addModuleStyles and addModuleScripts don't check dependencies, I have to use addModules, but I kept addModuleStyles for the reason of FOUC. But will this delay page load?

I guess a new option for gadgets declaring their styles will cause FOUC so the extension can put their styles on the top of pages.

#Comment by Krinkle (talk | contribs)   00:15, 8 January 2012

What problem is attempted to be solved here ?

If a gadget needs styling, there shuld be no FOUC as ResourceLoader implements the style properties before executing the JavaScript, so it shouldb'e be possible for something to be unstyled, and if it is, it's not related to Gadgets.

If it is a gadget styling something already on the page by default, then it should probably be a gadget that is in it's entirety with "position" property of the module set to "top" (this is not settable from the definitions page in the MW1.19 version of the extension, but will be in the RL2 version).

#Comment by Liangent (talk | contribs)   02:16, 8 January 2012

I didn't have a look at the new version, but the problem to solve is:

  • A gadget styling something already on the page -- was causing FOUC
  • or, a CSS gadget styling page in a browser that doesn't support JS but supports CSS -- was showing no styles at all
#Comment by Krinkle (talk | contribs)   02:24, 8 January 2012
  • Styling core elements (most likely a CSS-only gadget):

This will be fixed by RL2, which allows a gadget to set the load position to "top", which will make it load from the top queue (with JavaScript, in the same request as most other modules), which will be loaded before the page is rendered.

  • CSS for any gadget in browsers without JS

Interesting case, although one could argue:

  • Browsers without JS aren't officially supported, although it is the goal to preserve core article reading in a pretty way for those browsers. Gadgets don't fall under that imho.
  • Adding a separate http request for all css sheets from the HEAD for each gadget doesn't seem ideal
  • By being in a ‎<link> in the HTML itself means cache updates are not propagated as fast as other parts of the module, which is exactly why ResourceLoader's client-side component uses dynamic loading through JavaScript powered by the startup module. Using a LINK undoes all those advantages and will cause this style to be updates less frequently, become part from the html output, and likely have a shorter cache duration (not as good for performance, although not a huge deal for logged-in only gadgets but we have the ability to load gadgets for anonymous users and all logged-in users as well, so I think it's worth considering not allowing gadgets to insert an additional LINK tag for this reason as it goes against the very principle that ResourceLoader is trying to acomplish).
  • Potential risk of CSS and JS of a gadget going out of sync.

Status & tagging log