RFC: On-demand JavaScript & CSS

29 views
Skip to first unread message

Sam Minnee

unread,
Sep 15, 2008, 1:15:54 AM9/15/08
to SilverStripe Development
One of the performance issues with the CMS is that it has to pre-load
every JS file that you might need to one day news. This also creates
a coupling problem, because CMSMain needs to know about the JS
requirements of every page type in existence.

A solution to this problem is on-demand javascript (and CSS). That
is, Ajax responses should be able to determine when additional
JavaScript files are needed and load them without reloading the page.
For the purposes of this thread, I'm going to ignore CSS, but the
solutions can easily be applied to JS as CSS.

== Proposal one ==

1) Ajax requests would be made as normal
2) Requirement::javascript() calls get made on the server
3) The Ajax response has a number of X-Include-JS headers attached to
it:

X-Include-JS: sapphire/javascript/TableListField.js
X-Include-JS sapphire/javascript/ComplexTableField.js

4) We create a jQuery plugin that traps all ajax requests and checks
for X-Include-JS headers, and if they exist, includes those javascript
files that aren't already included.
5) The success handlers are called once any necessary scripts have
been loaded.

== Proposal two ==

1) Ajax requests would have a number of X-JavaScript-Loaded attached
to them
2) Requirement::javascript() calls get made on the server
3) The Ajax response has a number of X-Include-JS headers attached to
it. X-JavaScript-Loaded would be used to filter out any includes that
have already been included

4) and 5) are the same as above

At this stage I think that we should go with Proposal one, because
it's simpler, but I would like to hear ideas on this.

This jQuery plugin looks like a good one to use:
http://plugins.jquery.com/files/issues/jquery.ondemand.js_.txt

* It generates <script> tags rather than using ajax, which are cached
on more browsers
* It can include CSS and JS
* It will queue up requests and you can attach finished-loading
handlers to each of them

Michael Gall

unread,
Sep 15, 2008, 1:20:40 AM9/15/08
to silverst...@googlegroups.com
I like the sounds of proposal 1.
--
Checkout my new website: http://myachinghead.net
http://wakeless.net

Ingo Schommer

unread,
Sep 15, 2008, 6:38:36 AM9/15/08
to silverst...@googlegroups.com
The client should manage its own state, so another vote for proposal #1.

Some discussion on jquery mailinglist: http://www.nabble.com/On-Demand-Javascript--tc6152492.html

There's also a quite mature implementation with YUI loader
that we should at least compare against:
The jquery plugin doesn't seem to be widespread at all,
at which point my alarms go off ;)

As any inline Javascript is executed once loaded in a script-tag,
we have to be careful to synchronously load all resources - 
seems like the jquery plugin has queue management already.
Same story for CSS, as load order determines specificity
of similiar rules.

Does anybody know if the same security and caching contexts
apply for dynamically loaded scripts across browsers?

I think this goes together nicely with reducing the actual number
of requests we have to do by combining javascript files in the CMS
(the underlying API has already been created in Requirements.php).
Is there a maximum size of HTTP headers that we'd have to watch out for?

If we implement this widespread, we also need to have a look
at GUI loading indicators - perhaps an ajax request typically used to take <1sec,
so the developer didn't bother with an indicator. Now we might look at
loading 50k of Javascript before anything is executed - a lot higher delay,
the typical user might think the GUI is broken without loading indicators.
Baseline is, always indicate ajax loading in some graphical way
(which we can help with by providing a good API baselayer and
standard GUI places to put loaders).

Loosely related idea:
We could also use the same approach to define
depedencies on the clientside, e.g. ModelAdmin.js
could contain a require('jsparty/jquery/plugins/jquery.tabs.js') call.
We would then extend the document.ready behaviour
to listen for dynamically generated script tags before firing.
Dependency informatoin is currently handled implicitly on the
serverside by grouping calls to Requirements.php.



-------
Ingo Schommer | Senior Developer
SilverStripe

Skype: chillu23

Reply all
Reply to author
Forward
0 new messages