On Dienstag, 18. März 2008, DanTMan wrote:
Erm... never, EVER! try to write a long e-mail on a Wii... Especially when occasionally your Wi-Fi disconnects which ends up killing everything you've written.
Never, ever write 4 screen pages of text if you need a quick answer ;-)
For the record: (you may know that already, I did not follow the thread; all apologies)
* SMW has code that uses several hooks to include JavaScript upon request (during parsing or page creation), such that requested JavaScript ends up in the header of wiki pages (page cache) as well as in the header of special pages (no cache, direct HTML output). The function is smwfRequireHeadItem() in our SMW_GlobalFunctions.php. We found this very handy, since you can reuse JavaScript-dependent code in various contexts without caring.
* SMW uses the Timeline-Scripts (quite large and slow, hence used only on-demand). These scripts have an own internal loading mechanism for including required JavaScript (i.e. the JavaScript itself does extra inclusions).
* We found that loading many small JavaScripts slows down page display, since many files need to be fetched. If too many extensions use own JavaScripts, it might be good to have some MediaWiki-side service that merges requested files to ship them in one request. Even combining them manually into one file might help.
-- Markus
Well onto the topic...
I've notice that the number of extensions using JS Libraries has increased recently. Notably Semantic MediaWiki/Semantic Forms, and SocialProfile. Additionally I was contracted to create a new mp3 playing extension because all the current ones break the lines (The requester wants to be able to let the music play inline, basically beside a normal link to an audio file, instead of needing a plugin or something on their computer, or a big player that takes up unneeded space)... So I found the mp3inline http://pjoe.net/software/mp3inline/ Wordpress plugin, and intend to adapt some of it into a MediaWiki extension which will automatically let audio links be playable inline with an icon located cleanly beside the link. Of course, the note on this topic is that the player uses Scriptaculous which is another JS Library which would be put into MW.
Various extensions use different methods of including the libraries they need. Mostly just requiring the user to find a way to put it in. However SocialProfile includes a YUI extension which can be used. This extension however is basically just a short bit that includes a single script which is basically a minified part of the basic required YUI code, and an unminified version of the animation package (Why they used the minified version for one half, and the full version of another part is beyond me though)...
The biggest issue with any of these that I see... Is load time. For all of them you need to add a bunch of script tags to the page for them to work, and suddenly you drastically increase the number of HTTP calls for stuff on your site.
Since things are growing, I was thinking it would be a good idea to add some stuff to core to allow extensions to add use of JS libraries in an intuitive way. I started an allinone.php extension awhile ago (inspired by Wikia's allinone.js idea) and was thinking I should probably rewrite it and make something good for core. The idea is to have a single script in the page which contains all of the needed JS Libraries... And even wikibits.js inside it... All of them minified to compact space... Of course, if you need to debug any errors or anything, simply reload the page with &allinone=0 and the system automatically includes the separate non-minified files in individual script tags for debugging. Perhaps even a no-allinone preference for those doing heavy debugging in areas where they have a post request they can't add &allinone=0 to.
Additionally, the system would have a understanding of the structure of a js library. Basically, a sort of definition module would be created for each library that people may use (YUI, jQuery, Scriptaculous, Prototype, etc...) which would outline things like the different parts of the system (Core file, individual parts of the system like ui or other things only needed sometimes, separation of full/minified files (perhaps a notion of debug like what YUI has), and files like YUI's utilities.js or yahoo-dom-event.js which are minified versions of a grouping of various parts of the library.)
And using calls like, say... Making the thing handling this called "JSLibs" just for this example... JSLibs::addUse( 'YUI', 'animation' ); which would note that YUI's animation bit is required for use in the page. And so it'll automatically know that the 'yahoo' bit is also needed, additionally if various other things like the dom, event, etc... bits are needed it'll automatically use one of the combined files instead of individual ones.
Of course, there is a little bit of optimization by use that things using the libs need to do... Primarily this is because some things are needed at some times, and not at others... But if you don't define good times that it should be included, then the number of varying types of allinone groups you have increases and you end up with more stuff for the browser to cache and more requests to the server.
So basically:
- Skins... For the JS Libraries that they require, they should include
the libraries all the time when inside of that skin. (There'll be code to let Skins define what they need inside of the definition of where to put the stuff)
- Site scripts... When JS Libraries are wanted for site scripting, the
stuff should be included using calls inside of LocalSettings.php and included all the time.
- Extensions... It depends on what kind of extension...
** For low use things inside articles, like perhaps a TagCloud which is likely only to be used on a few major pages, this should be only included when needed (ie: The thing needing it is parsed into existence) ** For special page stuff, and things meant for only edit pages and the like the libraries should always be included while on these pages, but not in general while reading articles. ** For high use things, like SMW's attributes, factboxes, and such... The libraries should be included 100% of the time... Of course, if you really want you can put in some exclusions for when on special pages... But these are used a high amount of times, and can add up the number of variations easily.
If you don't understand what I'm meaning... It occurs when multiple extensions of different types are used... For example... Say we had a low use tag cloud, and something like SMW which included dynamic stuff every time an attribute was used... If the tag cloud loaded only when needed, and SMW included only when an attribute was used... then we'd have the variations:
- One for when tag cloud, and SMW attributes are used (main pages mostly)
- One for when tag cloud isn't used, but SMW attributes are used (most
article pages)
- One for when tag cloud is used, but SMW attributes are not (extremely
rare case)
- And one for when the tag cloud isn't used, and SMW attribues are not
(another rare case) Those last two shouldn't exist... They only exist because one extension didn't define when stuff should be included right. If the example SMW had loaded it's libraries 100% of the time when on articles because of the high use of it... Then there would only be two variations, one for with tag cloud, and one for when it's not...
Another issue, is minification... Not everything comes with a minified counterpart... I was hoping to make this something which could be done automatically. However, I found out that most of the minification programs that seam to be good, run in other languages like Java, rather than having PHP ports. So perhaps a toolserver service would be nice, one allowing extension authors to submit a page of code in a form to the toolserver, and have it return them a minified version using the best program for the job, that way people developing scripts and stuff for use can distribute the extension with pre-minified code, rather than requiring the people using the extension to download something to minify the code on their own. ^_^ And yes, of course we'd have a minified version of wikibits.js... We include it 100% of the time, why waste bytes on the comments and whitespace? Especially when using a non-minified/minified split allows us to put nice literate documentation inside of the code, while still making end use of something extremely compact.