MediaWiki Developers,
Over the past couple of months, Roan Kattouw and I (Trevor Parscal) have been working on a JavaScript and CSS delivery system called ResourceLoader. We're really excited about this technology, and hope others will be too.
This system has been proving itself to be able to seriously improve front-end performance. Just for starters, we're talking about taking the Vector skin from 35 requests @ 30kB gzipped to 1 request @ 9.4kB gzipped (see http://www.mediawiki.org/wiki/ResourceLoader/Benchmarks)
We are looking to make this the standard way to deliver Javascript, CSS, and small images in MediaWiki and on Wikimedia projects, and we're seeking your comments and help.
== Background ==
The goals of the project were to improve front-end performance, reduce the complexity of developing JavaScript libraries and user-interfaces, and get the ball rolling on a rewrite/refactoring of all JavaScript and CSS code in MediaWiki.
What's wrong with things as they are now?
* Too many individual requests are being made. All JavaScript, CSS and image resources are being loaded individually, which causes poor performance on the cluster and users experience the site as being slow. * We are wasting too much bandwidth. We are sending JavaScript and CSS resources with large amounts of unneeded whitespace and comments. * We are purging our caches too much. Many user interface changes require purging page caches to take effect and many assets are unnecessarily being purged from client machines due to the use of a single style version for all assets * We are sending people code they don't even use. Lots of JavaScript is being sent to clients whose browsers will either crash when it arrives (BlackBerry comes to mind), just not use it at all (older versions of many browsers) while parsing it unnecessarily (this is slow on older browsers, especially IE 6) or isn't even being completely utilized (UsabilityInitiative's plugins.combined.min.js for instance) * Internationalization in JavaScript is a mess. Developers are using many different ways -- most of which are not ideal -- to get their translated messages to the client. * Right-to-left support in CSS is akward. Stylesheets for right-to-left must to be either hand-coded in a separate stylesheet, generated each time a change is made by running CSSJanus, or an extra style-sheet which contains a series of over-rides. * There's more! These and other issues were captured in our requirements gathering process (see http://www.mediawiki.org/wiki/ResourceLoader/Requirements )
What does ResourceLoader do to solve this?
* Combines resources together. Multiple scripts, styles, messages to be delivered in a single request, either at initial page load or dynamically; in both cases resolving dependencies automatically. * Allows minification of JavaScript and CSS. * Dramatically reduces the number of requests for small images. Small images linked to from CSS code can be automatically in-lined as data URLs (when the developer marks it with a special comment), and it's done automatically as the file is served without requiring the developer to do such steps manually. * Allows deployment changes to all pages for all users within minutes, without purging any HTML. ResourceLoader provides a short-expiry start-up script which then decides to continue loading more JavaScript or not, and if so has a complete manifest of all scripts and styles on the server and their most recent versions, Also, this startup script will be able to be inlined using ESI (see http://en.wikipedia.org/wiki/Edge_Side_Includes ) when using Squid or Varnish, reducing requests and improving performance even further. * Provides a standard way to deliver translated messages to the client, bundling them together with the code that uses them. * Performs automatic left-to-right/right-to-left flipping for CSS files. In most cases the developer won't have to do anything before deploying. * Does all kinds of other cool tricks, which should soon make everyone's lives better
What do you want from me?
* Help by porting existing code! While ResourceLoader and traditional methods of adding scripts to MediaWiki output can co-exist, the performance gains of ResourceLoader are directly related to the amount of software utilizing it. There's some more stuff in core that needs to be tweaked to utilize the ResourceLoader system, such as user scripts and site CSS. We also need extensions to start using it, especially those we are deploying on Wikimedia sites or thinking about deploying soon. Only basic documentation exists on how to port extensions, but much more will be written very shortly and we (Roan and I) be leading by example by porting the UsabilityInitiative extensions ourselves. If you need help, we're usually on IRC. (See http://www.mediawiki.org/wiki/ResourceLoader/Getting_Started ) * Help writing new code! While wikibits.js is now also known as the "mediawiki.legacy.wikibits" module, the functionality that it and basically all other existing MediaWiki JavaScript code provide is being deprecated, in favor of new modules which take advantage of jQuery and can be written using a lot less code while eliminating the current dependence on a large number of globally accessible variables and functions (see http://www.mediawiki.org/wiki/ResourceLoader/JavaScript_Deprecations ) * Some patience and understanding... Please... While we are integrating into trunk, things might break unexpectedly. We're diligently tracking down issues and resolving them as fast as we can, but help in this regard is much needed and really appreciated. But most of all, we're sorry if something gets screwed up, and we're trying our best to make this integration smooth. * Enthusiasm!
Documentation is coming online as fast as we can write it. There's a very detailed design specification document at http://www.mediawiki.org/wiki/ResourceLoader/Design_Specification and more information in general at http://www.mediawiki.org/wiki/ResourceLoader , where we will be adding more and more documentation as time goes on. If you can help with documentation, please feel free to edit boldly - just try not to modify the design specification unless you are also modifying the software :)
While this project has been bootstrapped by Roan and myself in a branch, we're really excited about bringing it to trunk and hope the community can start taking advantage of the new features right away.
Tracking bug for tracking things that ResourceLoader will fix: http://bugzilla.wikimedia.org/show_bug.cgi?id=24415
Bugzilla Component: https://bugzilla.wikimedia.org/buglist.cgi?query_format=advanced&bug_sta...
- Trevor (and Roan, who's committing the merge to SVN right now)
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256
On 9/3/2010 10:59 PM, Trevor Parscal wrote:
- Trevor (and Roan, who's committing the merge to SVN right now)
Pssst, it's broken.
- -- var src=mediaWiki.config.get('server')+'/load.php - --
Hurm, what's server?
mediaWiki.config.get('server')
"http://www.thedarkcitadel.com/w/load.php"
http://www.thedarkcitadel.com/w/load.php/load.php => 404 => broken legacy scripts => no working JavaScript
PHP Path-info made this work, despite being horribly broken.
Fixed in r72355. Thanks for poking!
- Trevor
On 9/3/10 9:43 PM, Q wrote:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256
On 9/3/2010 10:59 PM, Trevor Parscal wrote:
- Trevor (and Roan, who's committing the merge to SVN right now)
Pssst, it's broken.
var src=mediaWiki.config.get('server')+'/load.php
Hurm, what's server?
mediaWiki.config.get('server')
"http://www.thedarkcitadel.com/w/load.php"
http://www.thedarkcitadel.com/w/load.php/load.php => 404 => broken legacy scripts => no working JavaScript -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.14 (MingW32) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
iQEcBAEBCAAGBQJMgc5/AAoJEL+AqFCTAyc2LEMIAKQaeR9jMLXdXE+s366n2Sj/ HHW6Wu8bJ8gQ60gMdF1RYkIFWQLRfVyb63vl5cw4QinhBdOHrkXzzicfy7UhGqcf JWNeAb/qF8y+ZBb4HI2af6OdvHoGhow4udzB2yUGIShhQEPpTfnHNFgR0M/mMo8L 5jhyizIaVc/yWo0EeYQG4RTU4BzjyQCWZlR/bFksCLpgyQ/deF/voPL2XFGRUPXR 31/lOlG8+9BiT741AbFsUNaa6VhFH0iZ/5UExigs/9HyJwq/E9lcBTQow3mIEXXN oYWOAX/AXmE80E+VclVSh7DqEGiLZSVBX8RW4kGCJr9Fj+KzQhvEGsGEDuS7yro= =LHAO -----END PGP SIGNATURE-----
Wikitech-l mailing list Wikitech-l@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/wikitech-l
On 4 September 2010 06:59, Trevor Parscal tparscal@wikimedia.org wrote:
MediaWiki Developers,
- Right-to-left support in CSS is akward. Stylesheets for right-to-left
must to be either hand-coded in a separate stylesheet, generated each time a change is made by running CSSJanus, or an extra style-sheet which contains a series of over-rides.
- Performs automatic left-to-right/right-to-left flipping for CSS files.
In most cases the developer won't have to do anything before deploying.
Does this affect in any way the possibility of fixing the long-standing LTR-RTL problem, where page direction depends on the content language? It should depend on the user language instead, and it should be possible to have content in different direction. Or is this just automation of the work which was previously done by hand or not done at all?
-Niklas
When you combine ResourceLoader's ability to flip css on the fly with changes made in r72366, what you are asking for should work with just a bit more tweaking. r72367 and 72368 make strides towards solving the issue of going to Arabic Wikipedia and using English as your language, ensuring we don't just flip on RTL, we flip when the user language is not the same direction as the content language, and only do this for CSS hosted on the wiki. Unfortunately because site CSS is still not passed through ResourceLoader this is not a complete solution.
- Trevor
On 9/4/10 1:11 AM, Niklas Laxström wrote:
On 4 September 2010 06:59, Trevor Parscaltparscal@wikimedia.org wrote:
MediaWiki Developers,
- Right-to-left support in CSS is akward. Stylesheets for right-to-left
must to be either hand-coded in a separate stylesheet, generated each time a change is made by running CSSJanus, or an extra style-sheet which contains a series of over-rides.
- Performs automatic left-to-right/right-to-left flipping for CSS files.
In most cases the developer won't have to do anything before deploying.
Does this affect in any way the possibility of fixing the long-standing LTR-RTL problem, where page direction depends on the content language? It should depend on the user language instead, and it should be possible to have content in different direction. Or is this just automation of the work which was previously done by hand or not done at all?
-Niklas
On 09/04/2010 05:59 AM, Trevor Parscal wrote:
Over the past couple of months, Roan Kattouw and I (Trevor Parscal) have been working on a JavaScript and CSS delivery system called ResourceLoader. We're really excited about this technology, and hope others will be too.
Cool! There have been many complaints with the introduction of Vector that Wikimedia sites are taking longer to load, hopefully this will be fixed soon. :)
church.of.emacs.ml wrote:
On 09/04/2010 05:59 AM, Trevor Parscal wrote:
Over the past couple of months, Roan Kattouw and I (Trevor Parscal) have been working on a JavaScript and CSS delivery system called ResourceLoader. We're really excited about this technology, and hope others will be too.
Cool! There have been many complaints with the introduction of Vector that Wikimedia sites are taking longer to load, hopefully this will be fixed soon. :)
It will be interesting to see the reactions for the sites which get vector and the resourceloader at the same time.
On 9/4/10 8:31 AM, Platonides wrote:
church.of.emacs.ml wrote:
On 09/04/2010 05:59 AM, Trevor Parscal wrote:
Over the past couple of months, Roan Kattouw and I (Trevor Parscal) have been working on a JavaScript and CSS delivery system called ResourceLoader. We're really excited about this technology, and hope others will be too.
Cool! There have been many complaints with the introduction of Vector that Wikimedia sites are taking longer to load, hopefully this will be fixed soon. :)
It will be interesting to see the reactions for the sites which get vector and the resourceloader at the same time.
Wikitech-l mailing list Wikitech-l@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/wikitech-l
Well, given we've recently switched all projects to Vector (are there any we have yet to switch that I don't know of?) that's not really possible anymore.
- Trevor
On Fri, Sep 3, 2010 at 11:59 PM, Trevor Parscal tparscal@wikimedia.org wrote:
Over the past couple of months, Roan Kattouw and I (Trevor Parscal) have been working on a JavaScript and CSS delivery system called ResourceLoader. We're really excited about this technology, and hope others will be too.
Awesome! Now maybe our front-end code won't be absolutely horrible. If only browsers supported some way of debugging minified code sanely . . .
What do you want from me?
. . .
- Enthusiasm!
I'll stick to this, since I've never done too much front-end work. :)
On Sat, Sep 4, 2010 at 10:17 AM, church.of.emacs.ml church.of.emacs.ml@googlemail.com wrote:
Cool! There have been many complaints with the introduction of Vector that Wikimedia sites are taking longer to load, hopefully this will be fixed soon. :)
That's mainly due to JS execution time, isn't it? A resource loader won't speed up page loads much if at all on a hot cache, so this probably won't offset that.
2010/9/5 Aryeh Gregor Simetrical+wikilist@gmail.com:
On Fri, Sep 3, 2010 at 11:59 PM, Trevor Parscal tparscal@wikimedia.org wrote:
Over the past couple of months, Roan Kattouw and I (Trevor Parscal) have been working on a JavaScript and CSS delivery system called ResourceLoader. We're really excited about this technology, and hope others will be too.
Awesome! Â Now maybe our front-end code won't be absolutely horrible. If only browsers supported some way of debugging minified code sanely . . .
Or just use ?debug=true and we'll serve you unminified, uncombined code.
Roan Kattouw (Catrope)
On Mon, Sep 6, 2010 at 10:15 AM, Roan Kattouw roan.kattouw@gmail.com wrote:
Or just use ?debug=true and we'll serve you unminified, uncombined code.
Then you have to hope that the bug still occurs. Probably it will, but you never know. Plus, it would be nice if there weren't that extra step. Of course, even if they de-minified things, you'd still have no comments and so on, but at least the line number would mean something.
2010/9/6 Aryeh Gregor Simetrical+wikilist@gmail.com:
Then you have to hope that the bug still occurs. Â Probably it will, but you never know. Â Plus, it would be nice if there weren't that extra step. Â Of course, even if they de-minified things, you'd still have no comments and so on, but at least the line number would mean something.
Actually, the line number would not mean a great deal because the scripts would still be combined, comments frequently take up entire lines and the deminifier cannot account for blank lines, statements broken over multiple lines, or multiple statements on one line. All this means it's impossible to map the line number to a source line and file, although I agree it does map it to a statement: someone else can add a breakpoint at the same line of the same combined+minified output (provided they're also hitting the same load.php URL) and have that break at the exact statement the reporter got their error on.
But all that is just theorizing about deminifying debuggers, which I don't think exist right now. The only thing we can do in practice is change the environment to remove the impediments to debugging we introduced and hope that doesn't make any bugs go away. We do this not only by obtaining each module's JS unminified in a separate request (unfortunately, we can't request CSS style sheets separately for dynamically requested modules because the technique needed for this is not as widely supported), but also by ensuring that all manipulation of JS and CSS we do (such as wrapping JS in a mediaWiki.loader.implement() call, direction flipping in CSS and image embedding in CSS) don't introduce or remove any lines, thereby preserving line numbers.
Roan Kattouw (Catrope)
Roan Kattouw <roan.kattouw <at> gmail.com> writes:
Actually, the line number would not mean a great deal because the scripts would still be combined, comments frequently take up entire lines and the deminifier cannot account for blank lines, statements broken over multiple lines, or multiple statements on one line. All this means it's impossible to map the line number to a source line and file, although I agree it does map it to a statement: someone else can add a breakpoint at the same line of the same combined+minified output (provided they're also hitting the same load.php URL) and have that break at the exact statement the reporter got their error on.
It shouldn't be too hard to have the minification script create a line number translation table; just delay stripping newlines until the end, and create an index of newline positions in the original and minified versions of the code. (You would need error offsets for that to be useful, though; I don't know which browsers provide that.)
Hi,
On 9 September 2010 09:36, Tgr gtisza@gmail.com wrote:
Roan Kattouw <roan.kattouw <at> gmail.com> writes:
Actually, the line number would not mean a great deal because the scripts would still be combined, comments frequently take up entire lines and the deminifier cannot account for blank lines, statements broken over multiple lines, or multiple statements on one line. All this means it's impossible to map the line number to a source line and file, although I agree it does map it to a statement: someone else can add a breakpoint at the same line of the same combined+minified output (provided they're also hitting the same load.php URL) and have that break at the exact statement the reporter got their error on.
It shouldn't be too hard to have the minification script create a line number translation table; just delay stripping newlines until the end, and create an index of newline positions in the original and minified versions of the code. (You would need error offsets for that to be useful, though; I don't know which browsers provide that.)
Why not leave line endings in place (with multiple line endings trimmed to one)? Or are the line endings a significant part of the minification gain?
On 9/9/10 12:42 AM, Jean-Marc van Leerdam wrote:
Hi,
On 9 September 2010 09:36, Tgrgtisza@gmail.com wrote:
Roan Kattouw<roan.kattouw<at> gmail.com> writes:
Actually, the line number would not mean a great deal because the scripts would still be combined, comments frequently take up entire lines and the deminifier cannot account for blank lines, statements broken over multiple lines, or multiple statements on one line. All this means it's impossible to map the line number to a source line and file, although I agree it does map it to a statement: someone else can add a breakpoint at the same line of the same combined+minified output (provided they're also hitting the same load.php URL) and have that break at the exact statement the reporter got their error on.
It shouldn't be too hard to have the minification script create a line number translation table; just delay stripping newlines until the end, and create an index of newline positions in the original and minified versions of the code. (You would need error offsets for that to be useful, though; I don't know which browsers provide that.)
Why not leave line endings in place (with multiple line endings trimmed to one)? Or are the line endings a significant part of the minification gain?
Or just use debug mode...
The purpose of using the debug mode (a feature of ResourceLoader) is not only to not minify the code, but also to not concatenate. The difference in performance between debug-mode and normal mode is enormous, and trying to find middle ground is unlikely to be fruitful.
Debug mode is useful, we should be embracing the concept and improving on it, rather than sacrificing the speed of the web-site as hundreds of millions of people experience it, just to appease lazy developers who don't want to type debug=true at the end of a URL.
- Trevor
At 2010-09-09 10:15, Trevor Parscal wrote:
On 9/9/10 12:42 AM, Jean-Marc van Leerdam wrote:
Hi,
On 9 September 2010 09:36, Tgrgtisza@gmail.com wrote:
Roan Kattouw<roan.kattouw<at> gmail.com> writes:
Actually, the line number would not mean a great deal because the scripts would still be combined, comments frequently take up entire lines and the deminifier cannot account for blank lines, statements broken over multiple lines, or multiple statements on one line. All this means it's impossible to map the line number to a source line and file, although I agree it does map it to a statement: someone else can add a breakpoint at the same line of the same combined+minified output (provided they're also hitting the same load.php URL) and have that break at the exact statement the reporter got their error on.
It shouldn't be too hard to have the minification script create a line number translation table; just delay stripping newlines until the end, and create an index of newline positions in the original and minified versions of the code. (You would need error offsets for that to be useful, though; I don't know which browsers provide that.)
Why not leave line endings in place (with multiple line endings trimmed to one)? Or are the line endings a significant part of the minification gain?
Or just use debug mode...
The purpose of using the debug mode (a feature of ResourceLoader) is not only to not minify the code, but also to not concatenate. The difference in performance between debug-mode and normal mode is enormous, and trying to find middle ground is unlikely to be fruitful.
Debug mode is useful, we should be embracing the concept and improving on it, rather than sacrificing the speed of the web-site as hundreds of millions of people experience it, just to appease lazy developers who don't want to type debug=true at the end of a URL.
- Trevor
Why not making this set-able through cookies? below: $this->debug = $request->getVal( 'debug' ) === 'true' || $request->getBool( 'debug' ); add something like: if (!$this->debug) { $cookieval = $request-> getCookie( 'debug', 'resource_loader_', false); $this->debug = (!empty($cookieval)); }
This would allow developers add debugging bookmark like this: javascript:alert(document.cookie="resource_loader_debug=1;%20path=/")
Regards, Nux.
On 9/9/10 7:33 AM, Maciej Jaros wrote:
At 2010-09-09 10:15, Trevor Parscal wrote:
On 9/9/10 12:42 AM, Jean-Marc van Leerdam wrote:
Hi,
On 9 September 2010 09:36, Tgrgtisza@gmail.com wrote:
Roan Kattouw<roan.kattouw<at> gmail.com> writes:
Actually, the line number would not mean a great deal because the scripts would still be combined, comments frequently take up entire lines and the deminifier cannot account for blank lines, statements broken over multiple lines, or multiple statements on one line. All this means it's impossible to map the line number to a source line and file, although I agree it does map it to a statement: someone else can add a breakpoint at the same line of the same combined+minified output (provided they're also hitting the same load.php URL) and have that break at the exact statement the reporter got their error on.
It shouldn't be too hard to have the minification script create a line number translation table; just delay stripping newlines until the end, and create an index of newline positions in the original and minified versions of the code. (You would need error offsets for that to be useful, though; I don't know which browsers provide that.)
Why not leave line endings in place (with multiple line endings trimmed to one)? Or are the line endings a significant part of the minification gain?
Or just use debug mode...
The purpose of using the debug mode (a feature of ResourceLoader) is not only to not minify the code, but also to not concatenate. The difference in performance between debug-mode and normal mode is enormous, and trying to find middle ground is unlikely to be fruitful.
Debug mode is useful, we should be embracing the concept and improving on it, rather than sacrificing the speed of the web-site as hundreds of millions of people experience it, just to appease lazy developers who don't want to type debug=true at the end of a URL.
- Trevor
Why not making this set-able through cookies? below: $this->debug = $request->getVal( 'debug' ) === 'true' || $request->getBool( 'debug' ); add something like: if (!$this->debug) { $cookieval = $request-> getCookie( 'debug', 'resource_loader_', false); $this->debug = (!empty($cookieval)); }
This would allow developers add debugging bookmark like this: javascript:alert(document.cookie="resource_loader_debug=1;%20path=/")
Regards, Nux.
Wikitech-l mailing list Wikitech-l@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/wikitech-l
We would need to vary on that cookie, but yes, this seems like a cool idea.
- Trevor
On 09/09/2010 10:56 AM, Trevor Parscal wrote:
We would need to vary on that cookie, but yes, this seems like a cool idea.
- Trevor
Previously when we had this conversation, I liked the idea of setting a user preference. http://lists.wikimedia.org/pipermail/wikitech-l/2010-May/047800.html
This is easiset to setup with the existing setup, since we already have cache destroying things in the preferences anyway.
--michael
I don't know about the rest of you, but I am the kind of person who would forget that they were in debug mode, or would leave it "on" all the time anyway.
Just a suggestion, but if there's a cookie or pref I feel it should add something visible to the page, to let you know you are in debug mode. Maybe an extra CSS rule that changes the logo or something.
Otherwise, I'm not looking forward to even more complaints about why the site is slow. ;)
On 9/9/10 10:56 AM, Trevor Parscal wrote:
On 9/9/10 7:33 AM, Maciej Jaros wrote:
This would allow developers add debugging bookmark like this: javascript:alert(document.cookie="resource_loader_debug=1;%20path=/")
At 2010-09-09 21:18, Neil Kandalgaonkar wrote:
I don't know about the rest of you, but I am the kind of person who would forget that they were in debug mode, or would leave it "on" all the time anyway.
Just a suggestion, but if there's a cookie or pref I feel it should add something visible to the page, to let you know you are in debug mode. Maybe an extra CSS rule that changes the logo or something.
Otherwise, I'm not looking forward to even more complaints about why the site is slow. ;)
I doubt developers will complain about that, but in any case the cookie will expire at the end of session (thought I know people that close their browser about once in a month or so ;-)). And besides as developers are developers they can add something to the page themselves. Personally I prefer to have a skin chooser on top of the page in my test mode.
Regards, Nux.
Please fix https://bugzilla.wikimedia.org/show_bug.cgi?id=25239
-- Leinad
Another bugs: * https://bugzilla.wikimedia.org/show_bug.cgi?id=25251 * https://bugzilla.wikimedia.org/show_bug.cgi?id=25252 * https://bugzilla.wikimedia.org/show_bug.cgi?id=25253
-- Leinad
2010/9/22 Daniel ~ Leinad danny.leinad@gmail.com:
Please fix https://bugzilla.wikimedia.org/show_bug.cgi?id=25239
Daniel ~ Leinad wrote:
Another bugs:
Bugzilla tracks these issues so that this mailing list (and its users) don't have to. As long as the bugs are in the "Resource Loader" component, someone will eventually take a look at them. :-)
MZMcBride
* Aryeh Gregor Simetrical+wikilist@gmail.com [Mon, 6 Sep 2010 14:31:45 -0400]:
On Mon, Sep 6, 2010 at 10:15 AM, Roan Kattouw roan.kattouw@gmail.com wrote:
Or just use ?debug=true and we'll serve you unminified, uncombined
code.
Then you have to hope that the bug still occurs. Probably it will, but you never know. Plus, it would be nice if there weren't that extra step. Of course, even if they de-minified things, you'd still have no comments and so on, but at least the line number would mean something.
Do browsers support streamed and combined (archive-like) gz-encoded content? Then probably minifying will not be neccessary. Also, it would be great if these high-level JS-libraries like jQuery actually were ported into DOM API level (native browser's implementation instead of extra JS layer). However, these questions are to FF/IE/Opera developers... Dmitriy
2010/9/7 Dmitriy Sintsov questpc@rambler.ru:
Do browsers support streamed and combined (archive-like) gz-encoded content? Then probably minifying will not be neccessary.
Minification makes a shocking difference: remember that it's not just whitespace being stripped, it's comments as well. For example, in /trunk/extensions/UsabilityInitiative/js we have:
plugins.combined.js: 259281 bytes plugins.combined.min.js: 142565 bytes plugins.combined.js.gz: 65569 bytes plugins.combined.min.js.gz: 32740 bytes
So not only is the minified JS roughly half the size in both the compressed and the uncompressed cases, it actually /compresses better/ (3.95x vs. 4.35x).
Also, it would be great if these high-level JS-libraries like jQuery actually were ported into DOM API level (native browser's implementation instead of extra JS layer). However, these questions are to FF/IE/Opera developers...
I definitely think this is the future, provided it's implemented reliably cross-browser. Also, you'd probably want to have a fallback library for browsers that have no or incomplete (e.g. missing a jQuery feature that's newer than the browser) native support.
Roan Kattouw (Catrope)
On 07/09/10 17:44, Roan Kattouw wrote:
2010/9/7 Dmitriy Sintsov questpc@rambler.ru:
Do browsers support streamed and combined (archive-like) gz-encoded content? Then probably minifying will not be neccessary.
Minification makes a shocking difference: remember that it's not just whitespace being stripped, it's comments as well. For example, in /trunk/extensions/UsabilityInitiative/js we have:
plugins.combined.js: 259281 bytes plugins.combined.min.js: 142565 bytes plugins.combined.js.gz: 65569 bytes plugins.combined.min.js.gz: 32740 bytes
So not only is the minified JS roughly half the size in both the compressed and the uncompressed cases, it actually /compresses better/ (3.95x vs. 4.35x).
Note that the advantage of minification is somewhat inflated due to the nature of the source. There seems to be a "because we can" element to it: because the developers are so impressed by the concept of minification, they write excessively verbose and excessively many comments. For example:
// create the span wrapper for the matched text var spannode = document.createElement( 'span' ); spannode.className = 'highlight'; // shave off the characters preceding the matched text var middlebit = node.splitText( pos ); // shave off any unmatched text off the end middlebit.splitText( pat.length ); // clone for appending to our span var middleclone = middlebit.cloneNode( true ); // append the matched text node to the span spannode.appendChild( middleclone ); // replace the matched node, with our span-wrapped clone of the matched node middlebit.parentNode.replaceChild( spannode, middlebit );
Or a doc comment:
/** * This plugin provides a generic way to add suggestions to a text box. * * Usage: * * Set options: * $('#textbox').suggestions( { option1: value1, option2: value2 } ); * $('#textbox').suggestions( option, value ); * Get option: * value = $('#textbox').suggestions( option ); * Initialize: * $('#textbox').suggestions(); * * Options: * * fetch(query): Callback that should fetch suggestions and set the suggestions property. Executed in the context of the * textbox * Type: Function * cancel: Callback function to call when any pending asynchronous suggestions fetches should be canceled. * Executed in the context of the textbox * Type: Function * special: Set of callbacks for rendering and selecting * Type: Object of Functions 'render' and 'select' * result: Set of callbacks for rendering and selecting * Type: Object of Functions 'render' and 'select' * $region: jQuery selection of element to place the suggestions below and match width of * Type: jQuery Object, Default: $(this) * suggestions: Suggestions to display * Type: Array of strings * maxRows: Maximum number of suggestions to display at one time * Type: Number, Range: 1 - 100, Default: 7 * delay: Number of ms to wait for the user to stop typing * Type: Number, Range: 0 - 1200, Default: 120 * submitOnClick: Whether to submit the form containing the textbox when a suggestion is clicked * Type: Boolean, Default: false * maxExpandFactor: Maximum suggestions box width relative to the textbox width. If set to e.g. 2, the suggestions box * will never be grown beyond 2 times the width of the textbox. * Type: Number, Range: 1 - infinity, Default: 3 * positionFromLeft: Whether to position the suggestion box with the left attribute or the right * Type: Boolean, Default: true * highlightInput: Whether to hightlight matched portions of the input or not * Type: Boolean, Default: false */
I think it's ironic that this style arises in JavaScript, given that it's a high-level language and relatively easy to understand, and that you could make a technical case in favour of terseness. C has an equally effective minification technique known as compilation, and its practitioners tend to be terse to a fault. For instance, many Linux kernel modules have no comments at all, except for the license header.
-- Tim Starling
2010/9/7 Tim Starling tstarling@wikimedia.org:
Note that the advantage of minification is somewhat inflated due to the nature of the source. There seems to be a "because we can" element to it: because the developers are so impressed by the concept of minification, they write excessively verbose and excessively many comments. For example:
[...]
I think it's ironic that this style arises in JavaScript, given that it's a high-level language and relatively easy to understand, and that you could make a technical case in favour of terseness. C has an equally effective minification technique known as compilation, and its practitioners tend to be terse to a fault. For instance, many Linux kernel modules have no comments at all, except for the license header.
I don't think terseness is a good thing necessarily. Some comments are unnecessarily verbose, yes (your first example, for instance), but I think Javadoc-style comments for non-trivial functions are essential, and class/file/interface comments describing an interface other code can interact with (your second example) are also very useful. Both, especially the former, are used throughout MediaWiki's PHP code, and the JS code is no exception. I also don't think that the verbosity you mentioned is caused by a "because we can" mentality, but rather by the authors themselves: 2 of the 3 main authors of UsabilityInitiative have a habit of writing verbose comments, both in JS and in PHP. (I remember you criticizing PHP code written by Trevor in July 2009 for containing comments verbose to the point of almost insulting the reader's intelligence.) However, clear and adequately complete documentation should not be confused for excessive verbosity. I agree that your second example is a long doc comment, but I don't think it's excessive for what it's supposed to be documenting (the interface to .suggestions(), which takes 12 arguments of various types and with various semantics, allowed values and default values).
Roan Kattouw (Catrope)
Tim Starling wrote:
On 07/09/10 17:44, Roan Kattouw wrote:
2010/9/7 Dmitriy Sintsov questpc@rambler.ru:
Do browsers support streamed and combined (archive-like) gz-encoded content? Then probably minifying will not be neccessary.
Minification makes a shocking difference: remember that it's not just whitespace being stripped, it's comments as well. For example, in /trunk/extensions/UsabilityInitiative/js we have:
plugins.combined.js: 259281 bytes plugins.combined.min.js: 142565 bytes plugins.combined.js.gz: 65569 bytes plugins.combined.min.js.gz: 32740 bytes
So not only is the minified JS roughly half the size in both the compressed and the uncompressed cases, it actually /compresses better/ (3.95x vs. 4.35x).
Note that the advantage of minification is somewhat inflated due to the nature of the source. There seems to be a "because we can" element to it: because the developers are so impressed by the concept of minification, they write excessively verbose and excessively many comments. For example:
// create the span wrapper for the matched text var spannode = document.createElement( 'span' ); spannode.className = 'highlight'; // shave off the characters preceding the matched text var middlebit = node.splitText( pos ); // shave off any unmatched text off the end middlebit.splitText( pat.length ); // clone for appending to our span var middleclone = middlebit.cloneNode( true ); // append the matched text node to the span spannode.appendChild( middleclone ); // replace the matched node, with our span-wrapped clone of the matched node middlebit.parentNode.replaceChild( spannode, middlebit );
Or a doc comment:
/**
- This plugin provides a generic way to add suggestions to a text box.
- Usage:
- Set options:
$('#textbox').suggestions( { option1: value1, option2: value2 } );
$('#textbox').suggestions( option, value );
- Get option:
value = $('#textbox').suggestions( option );
- Initialize:
$('#textbox').suggestions();
- Options:
- fetch(query): Callback that should fetch suggestions and set the
suggestions property. Executed in the context of the
textbox
Type: Function
- cancel: Callback function to call when any pending asynchronous
suggestions fetches should be canceled.
Executed in the context of the textbox
Type: Function
- special: Set of callbacks for rendering and selecting
Type: Object of Functions 'render' and 'select'
- result: Set of callbacks for rendering and selecting
Type: Object of Functions 'render' and 'select'
- $region: jQuery selection of element to place the suggestions below
and match width of
Type: jQuery Object, Default: $(this)
- suggestions: Suggestions to display
Type: Array of strings
- maxRows: Maximum number of suggestions to display at one time
Type: Number, Range: 1 - 100, Default: 7
- delay: Number of ms to wait for the user to stop typing
Type: Number, Range: 0 - 1200, Default: 120
- submitOnClick: Whether to submit the form containing the textbox
when a suggestion is clicked
Type: Boolean, Default: false
- maxExpandFactor: Maximum suggestions box width relative to the
textbox width. If set to e.g. 2, the suggestions box
will never be grown beyond 2 times the width of the textbox.
Type: Number, Range: 1 - infinity, Default: 3
- positionFromLeft: Whether to position the suggestion box with the
left attribute or the right
Type: Boolean, Default: true
- highlightInput: Whether to hightlight matched portions of the input
or not
Type: Boolean, Default: false
*/
I think it's ironic that this style arises in JavaScript, given that it's a high-level language and relatively easy to understand, and that you could make a technical case in favour of terseness. C has an equally effective minification technique known as compilation, and its practitioners tend to be terse to a fault. For instance, many Linux kernel modules have no comments at all, except for the license header.
-- Tim Starling
This brings up a question, what's the comparison between unminified, minified, just stripping comments, and their gzipped versions? Does minified+gzipped provide any significant size savings over simple commentstripped+gzipped?
If not, then there's something to say about that since only erasing comments would still make debugging somewhat doable since you should be able to get a good enough line number to use find with some nearby code to track down where the bug is. (You also won't run into server-side js syntax-error issues due to needing to minify actual code)
~Daniel Friesen (Dantman, Nadir-Seen-Fire) [http://daniel.friesen.name]
On 09/07/2010 01:39 AM, Tim Starling wrote:
I think it's ironic that this style arises in JavaScript, given that it's a high-level language and relatively easy to understand, and that you could make a technical case in favour of terseness. C has an equally effective minification technique known as compilation, and its practitioners tend to be terse to a fault. For instance, many Linux kernel modules have no comments at all, except for the license header.
I would quickly add that it would be best to promote JSDoc style comments ( as I have slowly been doing for mwEmbed ). This way eventually we could have ( Google Closure Compiler ) read these comments to better optimize JavaScript compilation:
http://code.google.com/closure/compiler/docs/js-for-compiler.html
Also we can create pretty JSDoc style documentation for people that are into that sort of thing.
--michael
Hi,
On Tue, Sep 7, 2010 at 9:44 AM, Roan Kattouw roan.kattouw@gmail.com wrote:
Also, it would be great if these high-level JS-libraries like jQuery actually were ported into DOM API level (native browser's implementation instead of extra JS layer). However, these questions are to FF/IE/Opera developers...
I definitely think this is the future, provided it's implemented reliably cross-browser. Also, you'd probably want to have a fallback library for browsers that have no or incomplete (e.g. missing a jQuery feature that's newer than the browser) native support.
Please, no. The various browsers all have their problems with standards even now, and I don't expect they'd get a jquery (or whatever JS framework) clientside implemented without having all sorts of problems.
Marco
On Mon, Sep 6, 2010 at 10:59 PM, Dmitriy Sintsov questpc@rambler.ru wrote:
Do browsers support streamed and combined (archive-like) gz-encoded content? Then probably minifying will not be neccessary.
Currently this is only readily obtainable by just concatenating the files. HTTP pipelining would negate most of the point of resource combining if it actually worked in practice, but it tends to break in hard-to-catch ways due to transparent proxies that don't support it correctly. Opera reportedly does pipelining with some sort of heuristic or fallback behavior so it works reliably. Firefox supports pipelining, but it's off by default because of the problems it causes:
https://bugzilla.mozilla.org/show_bug.cgi?id=264354
Another proposal in the making to allow this sort of combining more easily is Resource Packages, a Mozilla proposal:
http://people.mozilla.com/~jlebar/respkg/
This is supposed to make it into the next Firefox after 4.0 last I heard. Resource packages are easy to deploy (meaning no web server changes required), but they have to be maintained manually, and have other inherent limitations.
The medium-to-long-term development that's expected to address this problem is SPDY, a proposal by Google:
http://www.chromium.org/spdy/spdy-whitepaper
The major drawback is that it not only requires considerable server-side changes, it also doesn't work with HTTP proxies. In the end, it will probably be usable only over SSL, but that might not be such a big issue with DNSSEC finally becoming a reality -- the root zone has been signed, .com and .net will be within a year, and people are thinking about how to use DNSSEC to allow HTTPS without having to pay a CA for a certificate:
http://www.imperialviolet.org/2010/08/16/dnssectls.html
But SPDY has major advantages, basically being a rewrite of the HTTP wire format for performance, while preserving HTTP semantics (so applications will still be given the same headers, etc.).
So, yes, this problem is being worked on. :) None of it will obsolete minification, though, as Roan points out.
Also, it would be great if these high-level JS-libraries like jQuery actually were ported into DOM API level (native browser's implementation instead of extra JS layer).
This is not going to happen. jQuery is way too complicated to be a reasonable target for interoperable implementation. Furthermore, part of the goal of jQuery is to be a compatibility layer so that all browsers look the same even across many years of releases, and this isn't possible if it's native, so some extra layer will always be needed. Instead, implementers work on making popular libraries like jQuery work faster and better, including moving select features to a native implementation when that will improve performance a lot (e.g., querySelector()).
However, these questions are to FF/IE/Opera developers...
Don't forget Chrome and Safari. I'm not a web browser developer, but I work with web standards a lot, so I'm fairly informed on this sort of thing.
At 2010-09-04 05:59, Trevor Parscal wrote:
- Allows minification of JavaScript and CSS.
Will JS/CSS developers/testers be able to disable this in preferences?
- Allows deployment changes to all pages for all users within minutes,
without purging any HTML. ResourceLoader provides a short-expiry start-up script which then decides to continue loading more JavaScript or not, and if so has a complete manifest of all scripts and styles on the server and their most recent versions, Also, this startup script will be able to be inlined using ESI (see http://en.wikipedia.org/wiki/Edge_Side_Includes ) when using Squid or Varnish, reducing requests and improving performance even further.
So any change to MediaWiki:Common.js will refresh all script that are minified?
- Help writing new code! While wikibits.js is now also known as the
"mediawiki.legacy.wikibits" module, the functionality that it and basically all other existing MediaWiki JavaScript code provide is being deprecated, in favor of new modules which take advantage of jQuery and can be written using a lot less code while eliminating the current dependence on a large number of globally accessible variables and functions (see http://www.mediawiki.org/wiki/ResourceLoader/JavaScript_Deprecations )
Will jQuery be available for older skins too? If so won't it cause problems for mobile browsers? AFAIK mobile jQuery will not be ready for at least next few years.
I'm asking here because those that make gadgets (well me at least ;-)) still try to make them work on Vector and Monobook.
- Some patience and understanding... Please... While we are integrating
into trunk, things might break unexpectedly. We're diligently tracking down issues and resolving them as fast as we can, but help in this regard is much needed and really appreciated. But most of all, we're sorry if something gets screwed up, and we're trying our best to make this integration smooth.
- Enthusiasm!
Sorry for not being very enthusiastic ;-). I see this as solving some problems but creating new ones too. Not really complaining here, I think minification is really needed now to get Wikimedia sites loading faster.
Regards, Nux.
2010/9/6 Maciej Jaros egil@wp.pl:
At 2010-09-04 05:59, Trevor Parscal wrote:
- Allows minification of JavaScript and CSS.
Will JS/CSS developers/testers be able to disable this in preferences?
Like I said in my previous reply to Aryeh, you can use debug mode. This is a feature we probably should've mentioned in the OP.
- Allows deployment changes to all pages for all users within minutes,
without purging any HTML. ResourceLoader provides a short-expiry start-up script which then decides to continue loading more JavaScript or not, and if so has a complete manifest of all scripts and styles on the server and their most recent versions, Â Also, this startup script will be able to be inlined using ESI (see http://en.wikipedia.org/wiki/Edge_Side_Includes ) when using Squid or Varnish, reducing requests and improving performance even further.
So any change to MediaWiki:Common.js will refresh all script that are minified?
We currently serve site JS (Common.js and skinname.js combined; this combining was done before RL too) separately because it needs to run at the very end. This is because it assumes it runs in the global scope, so it can't be wrapped in a closure. We also can't concatenate unwrapped site JS to the end of wrapped modules, because that will result in the site JS being executed before e.g. wikibits, which will also break. The only reliable way at this time is to include site JS separately after the mediaWiki.loader.go(); call.
This means it's currently not combined with anything else, so invalidations of the site scripts won't invalidate anything else. Treating site JS like a normal module is only possible once site scripts have been ported to act like modules so they won't explode when wrapped in a closure. Depending on wikibits is fine as we already have dependency handling.
- Help writing new code! While wikibits.js is now also known as the
"mediawiki.legacy.wikibits" module, the functionality that it and basically all other existing MediaWiki JavaScript code provide is being deprecated, in favor of new modules which take  advantage of jQuery and can be written using a lot less code while eliminating the current dependence on a large number of globally accessible variables and functions (see http://www.mediawiki.org/wiki/ResourceLoader/JavaScript_Deprecations )
Will jQuery be available for older skins too? If so won't it cause problems for mobile browsers? AFAIK mobile jQuery will not be ready for at least next few years.
Yes, jQuery will be served on every page load. However, the (short) startup script that contains the module registration information and loads the jquery and mediawiki modules checks the browser version for compatibility before doing the latter. Currently the only browser it considers incompatible is IE <6, but this list should probably be extended to include other stone age browsers and mobile browsers. For the latter, we can even do the redirect to the mobile site in that place so we don't load a ton of JS before deciding to redirect people. OTOH, it might be nice to put a mobile redirect script in the <head> so the browser doesn't have to render the entire page before it hits the redirect script.
I'm asking here because those that make gadgets (well me at least ;-)) still try to make them work on Vector and Monobook.
That's one of the objectives here: to provide a common base library that everything in MW can build on, regardless of skin or whatever. To that end, we started serving jQuery on every page on Wikimedia wikis last week, and we already did so in trunk ($wgJQueryOnEveryPage) for a few months IIRC.
Sorry for not being very enthusiastic ;-). I see this as solving some problems but creating new ones too. Not really complaining here, I think minification is really needed now to get Wikimedia sites loading faster.
Which problems would this introduce? The ones you mentioned in this post have either already been solved or are trivially solvable.
Roan Kattouw (Catrope)
Roan Kattouw wrote:
For the latter, we can even do the redirect to the mobile site in that place so we don't load a ton of JS before deciding to redirect people. OTOH, it might be nice to put a mobile redirect script in the <head> so the browser doesn't have to render the entire page before it hits the redirect script.
I was under the impression the goal for the mobile redirection was to make it entirely server-side, not client-side. That is, the goal isn't to move the script to <head>, it's to remove the need for a script altogether. More info at https://bugzilla.wikimedia.org/show_bug.cgi?id=24859
MZMcBride
2010/9/6 MZMcBride z@mzmcbride.com:
I was under the impression the goal for the mobile redirection was to make it entirely server-side, not client-side. That is, the goal isn't to move the script to <head>, it's to remove the need for a script altogether. More info at https://bugzilla.wikimedia.org/show_bug.cgi?id=24859
Ultimately, yes. We discussed this briefly last week while giving Mark a rundown of the resource loader, and Mark said that server-side UA-based redirects are definitely feasible, but only after we move to Varnish for our text caching (we currently use Varnish on bits for JS/CSS caching and Squid for text and image caching). From what I understood and remember, the Varnish migration is not really a top priority right now and is expected to be completed in a year or so. In the meantime, we can make the mobile redirect suck slightly less.
Roan Kattouw (Catrope)
Roan Kattouw wrote:
Yes, jQuery will be served on every page load. However, the (short) startup script that contains the module registration information and loads the jquery and mediawiki modules checks the browser version for compatibility before doing the latter. Currently the only browser it considers incompatible is IE <6, but this list should probably be extended to include other stone age browsers and mobile browsers. For the latter, we can even do the redirect to the mobile site in that place so we don't load a ton of JS before deciding to redirect people. OTOH, it might be nice to put a mobile redirect script in the <head> so the browser doesn't have to render the entire page before it hits the redirect script.
Gadgets should be minifiable, too. Perhaps having an update add an standalone flag to the gadgets definitions, and minify everything without it. It would also be nice to be able to specify a filter there on which the is run (Special:Upload, namespace 2...)
2010/9/6 Platonides Platonides@gmail.com:
Gadgets should be minifiable, too.
Should be a matter of porting the Gadgets extension. Will need a bit of smartness because gadgets are wiki pages rather than files, but it's definitely doable.
Perhaps having an update add an standalone flag to the gadgets definitions, and minify everything without it.
You mean something like a permanent debug or compatibility mode for selected gadgets?
It would also be nice to be able to specify a filter there on which the is run (Special:Upload, namespace 2...)
That's actually something you can do with a custom loader script. This allows you to write the code calling mediaWiki.loader.register() yourself rather than having it generated by the resource loader (default), and to dynamically generate dependency information on the fly (by putting your dependency generation code in a closure that's only run when the module's dependency information is needed). At the point that script is run you don't have access to environment variables like the title and namespace yet, but the dependency registration closure does, so you can hack around it by adding an empty module that either does or doesn't depend on a second module with the actual code (eww, maybe we should add better support for this; typically this would be checked on the server side before adding the module or on the client side before requesting the module, though, but Gadgets can't do that easily).
Unfortunately, I don't think these loader scripts currently allow you to override some but not all parts of the registration call, it's either all or nothing. This is particularly annoying since the last modified timestamp of a module is hard to obtain on the client side. Filed this as https://bugzilla.wikimedia.org/show_bug.cgi?id=25085 .
Roan Kattouw (Catrope)
Roan Kattouw wrote:
2010/9/6 Platonides Platonides@gmail.com:
Gadgets should be minifiable, too.
Should be a matter of porting the Gadgets extension. Will need a bit of smartness because gadgets are wiki pages rather than files, but it's definitely doable.
Perhaps having an update add an standalone flag to the gadgets definitions, and minify everything without it.
You mean something like a permanent debug or compatibility mode for selected gadgets?
Yes. If Common.js has issues for minimifying, gadgets could as well. I first thought at it as "legacy", but there might be some reason for wanting it loaded separately. As far as not providing any flag, minifyies it, that shouldn't be a problem.
It would also be nice to be able to specify a filter there on which the is run (Special:Upload, namespace 2...)
That's actually something you can do with a custom loader script. This allows you to write the code calling mediaWiki.loader.register() yourself rather than having it generated by the resource loader (default), and to dynamically generate dependency information on the fly (by putting your dependency generation code in a closure that's only run when the module's dependency information is needed). At the point that script is run you don't have access to environment variables like the title and namespace yet, but the dependency registration closure does, so you can hack around it by adding an empty module that either does or doesn't depend on a second module with the actual code (eww, maybe we should add better support for this; typically this would be checked on the server side before adding the module or on the client side before requesting the module, though, but Gadgets can't do that easily).
Maybe adding a gadget module which in turns loads the others as needed? I'm not familiar with the resource loaded code to determine the best way to design it.
Unfortunately, I don't think these loader scripts currently allow you to override some but not all parts of the registration call, it's either all or nothing. This is particularly annoying since the last modified timestamp of a module is hard to obtain on the client side. Filed this as https://bugzilla.wikimedia.org/show_bug.cgi?id=25085 .
Roan Kattouw (Catrope)
And I don't understand what this last paragraph is about :) You are trying to reuse the same loader for all gadgets?
2010/9/7 Platonides Platonides@gmail.com:
Yes. If Common.js has issues for minimifying, gadgets could as well. I first thought at it as "legacy", but there might be some reason for wanting it loaded separately. As far as not providing any flag, minifyies it, that shouldn't be a problem.
It's likely that gadgets will have issues similar to Common.js's, yes, in which case it could be handy to still load them in legacy mode unless the gadgets definition page indicates it's RL-compatible. (That's another feature request: we should introduce that concept of legacy mode so we can combine scripts loaded in that mode rather than loading all of them separately.)
Maybe adding a gadget module which in turns loads the others as needed?
That could work, yes, but it'd mean the loader only finds out which gadgets it needs after the gadget module runs, which means it has to do an extra request back to the server to get them.
I'm not familiar with the resource loaded code to determine the best way to design it.
Basically the relevant facts are: * Module information is defined server-side and transfered to the client-side loader through either a standard mediaWiki.loader.register() call generated by the server or a custom registration script (called 'loader script' in the code) if defined * If server-side PHP code knows it needs a module, it can ask OutputPage to include it on a page. It does this by adding a call to mediaWiki.loader.load() * Near the bottom of the page (below everything but legacy-mode scripts, currently only site JS), mediaWiki.loader.go() is called. It consolidates all load() calls, resolves dependencies and obtains all required modules from the server in one request * Once these modules are loaded, their code is executed (in the correct order to satisfy dependencies) * On-demand loading after go() has happened can be done with mw.loader.using( 'modulename', function() { code using module } ); This will load the module and its dependencies, execute them, then execute the function provided to using().
This means that a gadget module that figures out which other modules to load could only use the on-demand mechanism: the other mechanisms are only available after the gadget module has been loaded. Using on-demand loading results in an additional request and should only be done when loading a relatively large portion of code that is only required upon a user action (e.g. jquery.ui.dialog when the user clicks one of the edit toolbar buttons associated with dialogs). Using on-demand loading for things that are immediately required on page load should be avoided if possible (and this usually is possible).
Unfortunately, I don't think these loader scripts currently allow you to override some but not all parts of the registration call, it's either all or nothing. This is particularly annoying since the last modified timestamp of a module is hard to obtain on the client side. Filed this as https://bugzilla.wikimedia.org/show_bug.cgi?id=25085 .
Roan Kattouw (Catrope)
And I don't understand what this last paragraph is about :) You are trying to reuse the same loader for all gadgets?
What I was saying is that when you use a custom registration script, that script is responsible for providing the loader with all the information it needs (module name, dependencies and last modified timestamp) without any help from the server (usually all of this information is defined on the server which then generates code to inform the loader). This is a problem, especially for the timestamp parameter, so I filed a bug requesting we make the information defined on the server side available to client-side custom loaders.
Roan Kattouw (Catrope)
Roan Kattouw wrote:
Maybe adding a gadget module which in turns loads the others as needed?
That could work, yes, but it'd mean the loader only finds out which gadgets it needs after the gadget module runs, which means it has to do an extra request back to the server to get them.
I see. It would have to be a hook into the resource loader.
2010/9/7 Platonides Platonides@gmail.com:
I see. It would have to be a hook into the resource loader.
You don't need a hook in the server-side PHP part of the resource loader, as determining which modules to load on that side is already supported. The Gadgets extension's PHP code could inspect variables like $wgTitle->getNamespace() and determine whether to load a certain gadget or not. This is easy as far as the resource loader goes, but it does mean the server has to make this decision based on information in the gadget's code or the gadget definition page. This is significantly less flexible than allowing a gadget to just provide a JS function that returns true or false, but the fact that the decision has to be made client-side makes it a bit trickier. It's still very much doable, although the way I proposed is a little bit hacky and we may want to have the client-side loader support this better.
Or did you mean a hook into the client-side loader?
Roan Kattouw (Catrope)
On 09/07/2010 12:19 AM, Roan Kattouw wrote:
2010/9/7 PlatonidesPlatonides@gmail.com:
I see. It would have to be a hook into the resource loader.
You don't need a hook in the server-side PHP part of the resource loader, as determining which modules to load on that side is already supported. The Gadgets extension's PHP code could inspect variables like $wgTitle->getNamespace() and determine whether to load a certain gadget or not.
This would of-course result in mangled cache for every page context that had a different set of page conditionals. Its better to do as you say bellow and have thin loader code check javascript conditionals and then fire off the loading of the gadget as needed.
This is easy as far as the resource loader goes, but it does mean the server has to make this decision based on information in the gadget's code or the gadget definition page. This is significantly less flexible than allowing a gadget to just provide a JS function that returns true or false, but the fact that the decision has to be made client-side makes it a bit trickier. It's still very much doable, although the way I proposed is a little bit hacky and we may want to have the client-side loader support this better.
Is this not what the mediaWiki.load.using() is for? Are wiki page names addressable as loadable modules? Ie can you request mediaWiki.load.using(['MediaWiki:MyGadgetDepenency.js', 'MediaWiki:MyGadget.js', 'MediaWiki:MyGadget.css' ] , function(){ ... MyGadget.doStuff() .. }
This was supported in the old resource loader via special WT: resource name pretext, but perhapse could be implemented more cleverly in the new resource loader. But would be nice to preserve the basic principal of being able to grab multiple wikipages in a single request, as to support more module gadget code.
--michael
2010/9/8 Michael Dale mdale@wikimedia.org:
On 09/07/2010 12:19 AM, Roan Kattouw wrote:
2010/9/7 PlatonidesPlatonides@gmail.com:
I see. It would have to be a hook into the resource loader.
You don't need a hook in the server-side PHP part of the resource loader, as determining which modules to load on that side is already supported. The Gadgets extension's PHP code could inspect variables like $wgTitle->getNamespace() and determine whether to load a certain gadget or not.
This would of-course result in mangled cache for every page context that had a different set of page conditionals. Its better to do as you say bellow and have thin loader code check javascript conditionals and then fire off the loading of the gadget as needed.
I see your argument how separating gadget loading into a separate request might be better so as to avoid cache mangling, but I hadn't really considered that and was looking for ways to tack gadget loading onto the request loading statically requested modules (through $wgOut), which is possible by a custom loader.
Is this not what the mediaWiki.load.using() is for?
Yes, that's what you'd use in a thin loader module that then loads other gadgets as needed, but it'd result in loading the requested modules in a separate request (which seems to be what you want).
Are wiki page names addressable as loadable modules? Ie can you request mediaWiki.load.using(['MediaWiki:MyGadgetDepenency.js', 'MediaWiki:MyGadget.js', 'MediaWiki:MyGadget.css' ] , function(){ ... MyGadget.doStuff() .. }
No, that's not supported.
This was supported in the old resource loader via special WT: resource name pretext, but perhapse could be implemented more cleverly in the new resource loader. But would be nice to preserve the basic principal of being able to grab multiple wikipages in a single request, as to support more module gadget code.
I don't believe we should necessarily support retrieval of arbitrary wiki pages this way, but that's not needed for Gadgets: there's a gadgets definition list listing all available gadgets, so Gadgets can simply register each gadget as a module (presumably named something like gadget-gadgetname).
Roan Kattouw (Catrope)
On 09/08/2010 06:28 AM, Roan Kattouw wrote:
I don't believe we should necessarily support retrieval of arbitrary wiki pages this way, but that's not needed for Gadgets: there's a gadgets definition list listing all available gadgets, so Gadgets can simply register each gadget as a module (presumably named something like gadget-gadgetname).
This is of course already supported, just not in 'grouped requests'. Open up your scripts tab on a fresh load of http://commons.wikimedia.org/wiki/Main_Page Like 24 or so of the 36 scripts requests on commons are 'arbitrary wiki pages' requested as javascript:
http://commons.wikimedia.org/w/index.php?title=MediaWiki:AjaxQuickDelete.js&...
Not gadgets in the php extensions sense. Ie MediaWiki:Common.js does a lot of loading and the gadget set is not defined in php on the server. The resource loader should minimally let you group MediaWiki namespace javascript and css.
--michael
2010/9/8 Michael Dale mdale@wikimedia.org:
This is of course already supported, just not in 'grouped requests'. Open up your scripts tab on a fresh load of http://commons.wikimedia.org/wiki/Main_Page Like 24 or so of the 36 scripts requests on commons are 'arbitrary wiki pages' requested as javascript:
http://commons.wikimedia.org/w/index.php?title=MediaWiki:AjaxQuickDelete.js&...
Yeah, these should be grouped.
Not gadgets in the php extensions sense. Ie MediaWiki:Common.js does a lot of loading
Yes, this is a good reason why we should support loading of arbitrary wiki pages.
and the gadget set is not defined in php on the server.
It's defined on a MediaWiki: page, which is accessed by the server to generate the Gadgets tab in Special:Preferences. There is sufficient server-side knowledge about gadgets to implement them as modules, although I guess we might as well save ourselves the trouble and load them as wiki pages,
Roan Kattouw (Catrope)
On 09/08/2010 11:25 AM, Roan Kattouw wrote:
It's defined on a MediaWiki: page, which is accessed by the server to generate the Gadgets tab in Special:Preferences. There is sufficient server-side knowledge about gadgets to implement them as modules, although I guess we might as well save ourselves the trouble and load them as wiki pages,
We should have an admin global enabled 'gadgets' enable system ( with support for turning it on per user group ie all users, admin users etc. Each gadget should define something like: MediaWiki:Gadget-loader-ImageAnnotator.js where it has the small bit that is presently stored in free text in MediaWiki:Common.js ie:
/**** ImageAnnotator ****** * Globally enabled per * http://commons.wikimedia.org/w/index.php?title=Commons:Village_pump&oldi... * * Maintainer: [[User:Lupo]] ****/
if (wgNamespaceNumber != -1 && wgAction && (wgAction == 'view' || wgAction == 'purge')) { // Not on Special pages, and only if viewing the page if (typeof (ImageAnnotator_disable) == 'undefined' || !ImageAnnotator_disable) { // Don't even import it if it's disabled. importScript ('MediaWiki:Gadget-ImageAnnotator.js'); } }
Should go into the "gadget loader file" and of course instead of importScript, some loader call that aggregates all the loader load calls for a given page ready time. It should ideally also support some sort of grouping strategy parameter. We should say something like packages that are larger than 30k or used on a single page should not be grouped. As to avoid mangled cache effects escalating into problematic scenarios. As we briefly discussed, I agree with Trevor that if the script is small and more or less widely used its fine to retransmit the same package in different contexts to avoid extra requests on first visit.
But it should be noted that separating requests can result in ~less~ requests. ie imagine grouping vs separate request where page 1 uses resource set A, B and page 2 uses resource set A, C then page 3 uses A,B,C you still end up doing 3 requests across the 3 page views, except with 'one request' strategy you resend A. The forth page that just uses B, C you can pull those from cache and do zero requests, or resend B, C if you always go with a 'single request'. Of course as you add more permutations like page 5 that uses just A just B or just C it can get ugly. Which is why we need to ~strongly recommend~ the less than 30K or rarely used javascript grouping rules somehow.
The old resource loader had the concept of 'buckets' I believe the present resource loader just has an option to 'not-group', which is fine since 'buckets' could be conceptualized as 'meta modules sets' that are 'not-grouped'. Not sure whats conceptually more clear. IMHO buckets is a bit more friendly to modular extension gadget development since any module can say its part of a given group without modifying a master or core manifest.
At any rate, we should make sure to promote either buckets or 'meta module' option, or it could result in painful excessive retransmission of grouped javascrpt code.
--michael
Hi! If my extension does not need jQuery and I don't like minification, why can't I still use OutputPage::addScript() in my code? Aren't too much number of extensions would become suddenly incompatible due of that change? I understand that jQuery and minification is a useful thing, however, why should it be strictly enforced? My script currently is for a special page only, I don't think it produces a traffic hit (even though, it probably will never get installed by big traffic sites, anyway). And also I like to do things myself. It does not break 1.17 in anyway. Dmitriy
2010/11/5 Dmitriy Sintsov questpc@rambler.ru:
Hi! If my extension does not need jQuery and I don't like minification, why can't I still use OutputPage::addScript() in my code?
You totally can. It's not recommended, and it'll be less performant, but you can use it and it'll work. Your script tag will end up near the bottom of the <body> though, so you can't use inline JS to call functions defined in that script.
Aren't too much number of extensions would become suddenly incompatible due of that change?
As long as they're not using inline JS, they won't break.
Roan Kattouw (Catrope)
* Roan Kattouw roan.kattouw@gmail.com [Fri, 5 Nov 2010 14:43:57 +0100]:
You totally can. It's not recommended, and it'll be less performant, but you can use it and it'll work. Your script tag will end up near the bottom of the <body> though, so you can't use inline JS to call functions defined in that script.
I am viewing generated HTML and don't see my script anywhere, neither in top nor bottom. It is a special page and I've used $wgOut->addScript() in "overloaded" SpecialPage::execute(). Works just fine in 1.15.x, while in relatively fresh trunk this $wgOut->addScript() is completely ignored - like it wasn't there. The "old" code is in repo Extension:WikiSync. But, $wgOut->addLink() in SpecialPage::execute() works just fine, css is being added, scripts are not! I've tried to switch to ResourceLoader, in case such class exists; however cannot get it to work.
$wgHooks['ResourceLoaderRegisterModules'][] = 'WikiSyncSetup::registerModules'; $wgHooks['MakeGlobalVariablesScript'][] = 'WikiSyncSetup::MakeGlobalVariablesScript'; ... I am trying MakeGlobalVariablesScript to call ResourceLoader::addModules() because when it was in SpecialPage::execute(), addModules() was performed before registerModules (which is probably wrong). I've also tried OutputPageParserOutput, but that is not being executed in SpecialPage (which is probably right, because some Special pages can live without parser at all).. ... static function registerModules( $resourceLoader ) { global $wgExtensionAssetsPath; $localpath = dirname( __FILE__ ); $remotepath = "$wgExtensionAssetsPath/WikiSync"; $resourceLoader->register( array( 'ext.wikisync' => new ResourceLoaderFileModule( array( 'scripts' => 'WikiSync.js', 'styles' => 'WikiSync.css', 'messages' => self::$jsMessages ), $localpath, $remotepath ) ) ); return true; }
static function MakeGlobalVariablesScript( &$vars ) { global $wgOut, $wgContLang; self::headScripts( $wgOut, $wgContLang->isRTL() ); return true; }
/* * include stylesheets and scripts; set javascript variables * @param $outputPage - an instance of OutputPage * @param $isRTL - whether the current language is RTL */ static function headScripts( &$outputPage, $isRTL ) { global $wgJsMimeType; if ( class_exists( 'ResourceLoader' ) ) { # $outputPage->addModules( 'jquery' ); $outputPage->addModules( 'ext.wikisync' ); return; } $outputPage->addLink( array( 'rel' => 'stylesheet', 'type' => 'text/css', 'href' => self::$ScriptPath . '/WikiSync.css?' . self::$version ) ); if ( $isRTL ) { $outputPage->addLink( array( 'rel' => 'stylesheet', 'type' => 'text/css', 'href' => self::$ScriptPath . '/WikiSync_rtl.css?' . self::$version ) ); } $outputPage->addScript( '<script type="' . $wgJsMimeType . '" src="' . self::$ScriptPath . '/WikiSync.js?' . self::$version . '"></script> <script type="' . $wgJsMimeType . '" src="' . self::$ScriptPath . '/WikiSync_Utils.js?' . self::$version . '"></script> <script type="' . $wgJsMimeType . '">WikiSyncUtils.addEvent(window,"load",WikiSync.onloadHandler);</script> <script type="' . $wgJsMimeType . '"> WikiSync.setLocalMessages( ' . self::getJsObject( 'wsLocalMessages', self::$jsMessages ) . ');</script>' . "\n" ); }
As long as they're not using inline JS, they won't break.
Unfortunately, I've used a bit of inline JS. How do I add window.onload? Inside "main flow" of WikiSync.js ? I'll try that however currently I cannot get registerModule() and addModules() to work. Probably it's something simple, sorry. Dmitriy
MakeGlobalVariablesScript does not do what you think it does, and is not an appropriate hook for doing anything but adding elements to the array argument for that hook. You should be adding modules in your SpecialPage::execute function.
As for your addScript() calls not working, I will need to look at your code, I assume it's checked in at extensions/WikiSyncSetup? Maybe you could find me on IRC and I could help you there - it will be quicker than this list.
- Trevor
On 11/5/10 10:20 AM, Dmitriy Sintsov wrote:
- Roan Kattouwroan.kattouw@gmail.com [Fri, 5 Nov 2010 14:43:57
+0100]:
You totally can. It's not recommended, and it'll be less performant, but you can use it and it'll work. Your script tag will end up near the bottom of the<body> though, so you can't use inline JS to call functions defined in that script.
I am viewing generated HTML and don't see my script anywhere, neither in top nor bottom. It is a special page and I've used $wgOut->addScript() in "overloaded" SpecialPage::execute(). Works just fine in 1.15.x, while in relatively fresh trunk this $wgOut->addScript() is completely ignored
- like it wasn't there. The "old" code is in repo Extension:WikiSync.
But, $wgOut->addLink() in SpecialPage::execute() works just fine, css is being added, scripts are not! I've tried to switch to ResourceLoader, in case such class exists; however cannot get it to work.
$wgHooks['ResourceLoaderRegisterModules'][] =
'WikiSyncSetup::registerModules'; $wgHooks['MakeGlobalVariablesScript'][] = 'WikiSyncSetup::MakeGlobalVariablesScript'; ... I am trying MakeGlobalVariablesScript to call ResourceLoader::addModules() because when it was in SpecialPage::execute(), addModules() was performed before registerModules (which is probably wrong). I've also tried OutputPageParserOutput, but that is not being executed in SpecialPage (which is probably right, because some Special pages can live without parser at all).. ... static function registerModules( $resourceLoader ) { global $wgExtensionAssetsPath; $localpath = dirname( __FILE__ ); $remotepath = "$wgExtensionAssetsPath/WikiSync"; $resourceLoader->register( array( 'ext.wikisync' => new ResourceLoaderFileModule( array( 'scripts' => 'WikiSync.js', 'styles' => 'WikiSync.css', 'messages' => self::$jsMessages ), $localpath, $remotepath ) ) ); return true; }
static function MakeGlobalVariablesScript(&$vars ) { global $wgOut, $wgContLang; self::headScripts( $wgOut, $wgContLang->isRTL() ); return true; }
/* * include stylesheets and scripts; set javascript variables * @param $outputPage - an instance of OutputPage * @param $isRTL - whether the current language is RTL */ static function headScripts(&$outputPage, $isRTL ) { global $wgJsMimeType; if ( class_exists( 'ResourceLoader' ) ) { # $outputPage->addModules( 'jquery' ); $outputPage->addModules( 'ext.wikisync' ); return; } $outputPage->addLink( array( 'rel' => 'stylesheet', 'type' => 'text/css', 'href' => self::$ScriptPath . '/WikiSync.css?' . self::$version ) ); if ( $isRTL ) { $outputPage->addLink( array( 'rel' => 'stylesheet', 'type' => 'text/css', 'href' => self::$ScriptPath . '/WikiSync_rtl.css?' . self::$version ) ); } $outputPage->addScript( '<script type="' . $wgJsMimeType . '" src="' . self::$ScriptPath . '/WikiSync.js?' . self::$version . '"></script> <script type="' . $wgJsMimeType . '" src="' . self::$ScriptPath . '/WikiSync_Utils.js?' . self::$version . '"></script> <script type="' . $wgJsMimeType . '">WikiSyncUtils.addEvent(window,"load",WikiSync.onloadHandler);</script> <script type="' . $wgJsMimeType . '"> WikiSync.setLocalMessages( ' . self::getJsObject( 'wsLocalMessages', self::$jsMessages ) . ');</script>' . "\n" ); }
As long as they're not using inline JS, they won't break.
Unfortunately, I've used a bit of inline JS. How do I add window.onload? Inside "main flow" of WikiSync.js ? I'll try that however currently I cannot get registerModule() and addModules() to work. Probably it's something simple, sorry. Dmitriy
Wikitech-l mailing list Wikitech-l@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/wikitech-l
* Trevor Parscal tparscal@wikimedia.org [Fri, 05 Nov 2010 10:49:37 -0700]:
MakeGlobalVariablesScript does not do what you think it does, and is
not
an appropriate hook for doing anything but adding elements to the
array
argument for that hook. You should be adding modules in your SpecialPage::execute function.
It was a desperate action. addModules didn't work in SpecialPage::execute() - my guess was that addModules() should not be called before registerModules(), but maybe I am wrong. http://www.mediawiki.org/wiki/Extension:WikiSync
As for your addScript() calls not working, I will need to look at your code, I assume it's checked in at extensions/WikiSyncSetup? Maybe you could find me on IRC and I could help you there - it will be quicker than this list.
Sorry I currently don't have the time for IRC. I haven't checked the code because trunk supposed to be working. Now I've checked it, although the ResourceLoader still does not work for me: http://svn.wikimedia.org/viewvc/mediawiki/trunk/extensions/WikiSync/ BTW, Sorry for taking your time. Dmitriy
Hi! I would like to thank Roan Kattouw for helping me to adapt my Extension:WikiSync to use ResourceLoader. Before asking, I've spend some hours trying to get it to work, unsuccessfully. One of key errors was not so easy to guess: it turned out that browsers violate "self-closing" xml tags sometimes (a tag without nested text node - with slash inside), and it was such case with iframe. I probably even have heard about this few years ago, but already forgot it. While in Monobook and addScripts() head inclusion that was not critical (the extension worked), with bottom-inclusion it's much more critical. (I've observed non-closed tags in some old extensions, sometimes). The real nastiness is, that my extension used arrays to represent html /xml and the entries are "auto-closed", so the tree should be valid. I wasn't even thinking of possibility of non-closed tags (invalid tree) in my case. Dmitriy
On Sun, Nov 7, 2010 at 2:34 PM, Dmitriy Sintsov questpc@rambler.ru wrote:
I would like to thank Roan Kattouw for helping me to adapt my Extension:WikiSync to use ResourceLoader. Before asking, I've spend some hours trying to get it to work, unsuccessfully. One of key errors was not so easy to guess: it turned out that browsers violate "self-closing" xml tags sometimes (a tag without nested text node - with slash inside), and it was such case with iframe.
This is why the /> syntax in text/html is stupid and harmful -- it's just ignored by all browsers, but people assume it works. <foo> and <foo /> parse exactly the same way in text/html and always have, the / is ignored entirely. Elements that can never contain anything (like <img>) don't need a closing tag or closing slash or anything, and other elements (including <iframe>) must be explicitly closed with a separate closing tag.
Of course, since HTML5 parsers are still much harder to dig up than XML parsers, we still should probably continue outputting well-formed XML, which means including these trailing slashes that are pointless for browsers. Just a random little rant here. :)
You can use OutputPage::addScript - who said you cant?
- Trevor
On 11/5/10 1:30 AM, Dmitriy Sintsov wrote:
Hi! If my extension does not need jQuery and I don't like minification, why can't I still use OutputPage::addScript() in my code? Aren't too much number of extensions would become suddenly incompatible due of that change? I understand that jQuery and minification is a useful thing, however, why should it be strictly enforced? My script currently is for a special page only, I don't think it produces a traffic hit (even though, it probably will never get installed by big traffic sites, anyway). And also I like to do things myself. It does not break 1.17 in anyway. Dmitriy
Wikitech-l mailing list Wikitech-l@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/wikitech-l
* Trevor Parscal tparscal@wikimedia.org [Fri, 05 Nov 2010 10:38:52 -0700]:
You can use OutputPage::addScript - who said you cant?
It was adding scripts in 1.15 when I performed a call to OutputPage::addScript() in SpecialPage::execute(), now it doesn't (the same code). I've decided to switch to ResourceLoader (when available), but currently cannot get registerModules() addModules() to work (in previous post). What is the proper place to put ResourceLoader::addModules() call to? Strange, in firebug and IE debugger in "Scripts" there is no WikiSync.js, no matter there is no errors in apache error_log. Cannot get it to work. Dmitriy
AT 2010-09-06 18:26, Roan Kattouw wrote:
2010/9/6 Maciej Jarosegil@wp.pl:
At 2010-09-04 05:59, Trevor Parscal wrote:
- Allows minification of JavaScript and CSS.
Will JS/CSS developers/testers be able to disable this in preferences?
Like I said in my previous reply to Aryeh, you can use debug mode. This is a feature we probably should've mentioned in the OP.
This is good, but an option set in preferences would be more efficient when debugging more then one page. But if it would read _GET or _COOKIE then it would be fine for me, too.
- Help writing new code! While wikibits.js is now also known as the
"mediawiki.legacy.wikibits" module, the functionality that it and basically all other existing MediaWiki JavaScript code provide is being deprecated, in favor of new modules which take advantage of jQuery and can be written using a lot less code while eliminating the current dependence on a large number of globally accessible variables and functions (see http://www.mediawiki.org/wiki/ResourceLoader/JavaScript_Deprecations )
Will jQuery be available for older skins too? If so won't it cause problems for mobile browsers? AFAIK mobile jQuery will not be ready for at least next few years.
Yes, jQuery will be served on every page load. However, the (short) startup script that contains the module registration information and loads the jquery and mediawiki modules checks the browser version for compatibility before doing the latter. Currently the only browser it considers incompatible is IE<6, but this list should probably be extended to include other stone age browsers and mobile browsers. For the latter, we can even do the redirect to the mobile site in that place so we don't load a ton of JS before deciding to redirect people. OTOH, it might be nice to put a mobile redirect script in the<head> so the browser doesn't have to render the entire page before it hits the redirect script.
That seems like a good idea. I've just found some data about jQuery tests: http://jquerymobile.com/gbs/ As seems I was a little over pessimistic about jQuery for mobile devices. None the less you can use the table on the page for redirections. I think everything below B should be redirected to mobile version. B might be left on monobook and A should work fine with any skin (or least surrvive).
I'm asking here because those that make gadgets (well me at least ;-)) still try to make them work on Vector and Monobook.
That's one of the objectives here: to provide a common base library that everything in MW can build on, regardless of skin or whatever. To that end, we started serving jQuery on every page on Wikimedia wikis last week, and we already did so in trunk ($wgJQueryOnEveryPage) for a few months IIRC.
Cool. Just announced it on pl.wiki news page.
Sorry for not being very enthusiastic ;-). I see this as solving some problems but creating new ones too. Not really complaining here, I think minification is really needed now to get Wikimedia sites loading faster.
Which problems would this introduce? The ones you mentioned in this post have either already been solved or are trivially solvable.
I fear mainly that there will be reproduction issues and I'm probably just a bit superstitious ;-). I'm also a bit worried how current various loading mechanism will accompany new ones.
Regards, Nux.
wikitech-l@lists.wikimedia.org