Foswiki on GitHub is open for business! Next release meeting: Monday September 1, 1300Z

Feature Proposal: Lazy Load Javascript and Css

Motivation

As I use javascript popup dialogs more, I find myself needing to get javascript loaded dynamically - some dialogs need charting that isn't present in the loaded topic, or (the currently obvious one - strikeone.js for popup task creation)

it would give us a more dynamic js REQUIRE implementation than we currently have - where the js knows its loaded, so doesn't need to re-load, can load implied dependencies, obey ordering, and generally walk and chew gum at the same time.

additionally, there seems to be a meme about the speed / non-blocking download aspects of doing things this way (the html5 async attr may address this, but not the other possible advantages)

I wold also like to have the ability to trigger an even when the async things are ready smile

Description and Documentation

there are a few blogs about the development of solutions:

implementations :

Examples

I really would like to just add

REQUIRE{strikeone} to something and know that it'll happen irrespective of normal topic view, or delayed load.

or if using a jqDialog css param - to not require anything at all - it'll just know... (yeah, that might be dreaming but meh.)

so presumably there will need to be a REQUIRE_MANIFEST that lists the js, html, css, dependencies, whatever that should be loaded - like JQREQUIRE, but generalised.

Impact

WhatDoesItAffect: %WHATDOESITAFFECT%

Implementation

-- Contributors: SvenDowideit - 18 Apr 2012

Discussion

Yes we need this for javascript. Not sure about css. At least optimizing css is easier.

Just for clarification: the main difference will be that instead crafting script tags into the html header on the server side, we will add them on the client side after the DOM has been loaded. The browser will then have to decide which scripts to load and in which order.

Question: shall we

  • (a) write our own lazy async loader or
  • (b) use an existing one like RequireJS?

Things to watch out for:

FUBC (flash of unbehaviored content): there might be some js that manipulates the DOM massively as soon as it gets loaded. this might result in flickering or more rerendering than what we have now, or at least easier perceived by the user. Best examples are twisties and tinymce.

With regards to tinymce: there is a rather delicate javascript init process in the way tinymce is loaded into the page right now, i.e. it massively blocks page loading times by executing even before the complete DOM is loaded. Not sure it is compatible with things like RequireJS.

We still generate inline scripts and styles per page. Makes things a bit tricky wrt execution order. From what I see now, only LabJS can deal with this. Please prove me wrong studying the other loaders.

What about users adding javascript to the topic text? Which provisions will they have to follow to play nicely with the code loaded by Foswiki? It might need some macros to interact with the javascript loader.

RequireJS comes with a "module" concept of its own. This doesn't match well the way we plug things into foswiki atm.

HeadJS comes with lots of html5 "cruft" that is better done using Modernizr, imho.

LabJS seems to be equivalent to HeadJS w/o the html5 stuff.

LabJS seems to demand the least overhead organizing javascript files on the backend. It just does what it should do: load the js files.

There's a clear migration path towards making use of LabJS.

Before:
<script src="framework.js"></script>
<script src="plugin.framework.js"></script>
<script src="myplugin.framework.js"></script>
<script>
   myplugin.init();
</script>
<script>
   framework.init();
   framework.doSomething();
</script>

After:
<script>
   $LAB
   .script("framework.js").wait()
   .script("plugin.framework.js")
   .script("myplugin.framework.js")
   .wait(function(){
      myplugin.init();
      framework.init();
      framework.doSomething();
   });
</script>

-- MichaelDaum - 18 Apr 2012

yeah - that was my impression about LabJS and the others :/

-- SvenDowideit - 18 Apr 2012

Another twist to the problem is that content might be loaded async'ly, e.g. using JQueryLoader or using InfiniteScrollContrib. This markup then adds js and css requirements incrementally. For now the only way to deal with this is either to load all js and css before any async markup, or to inline css and js. The latter approach is not available when generating markup client side using JQueryTmpl while reading json from the backend, as is the case in SolrPlugin.

-- MichaelDaum - 15 Jan 2013

In the past I've just used jQuery.getScript() - I realize this comment is perhaps unhelpful smile

-- PaulHarvey - 29 Jan 2013

This here looks like it was made for us: https://github.com/ded/script.js

I ask myself: in how far does lazy loading javascript and css harm SPDY Push?

Loading times on mobile devices are an issue to consider as well, as network round trips on mobile connections are very expensive.

-- MichaelDaum - 25 Feb 2014
 
Topic revision: r6 - 25 Feb 2014, MichaelDaum
 
The copyright of the content on this website is held by the contributing authors, except where stated elsewhere. see CopyrightStatement. Creative Commons License