Loading Everything at Once - HTML, CSS & JavaScript
Some Sakai3 front-end developers had a dream:
For our widget loading mechanism we want to load the HTML / CSS and JavaScript in one request (without asking the user to use inline CSS or JavaScript)
It felt like quite a big challenge and I wondered if it would be possible from a front-end point of view or not. So I gave it a go.
What we need from the back-end
In Nakamura (the Sakai3 back-end) we are using Apache Sling in combination with Apache Jackrabbit. Which means that when we go to a URL like twitter.2.json we get information back about the structure of it’s contents:
If we remove all the “jcr:” properties on those nodes, it makes it even more clear:
We basically get the hierarchical folder structure back for the twitter widget. If we change default GET servlet for sling or if we make a URL to something like twitter.content.json, it would be possible to get something like this back:
And that, would be genuinely awesome. This would mean that our widget could be loaded into one request! Except for the images – but those could get base64 encoded…
About the example
Before I send a request to the back-end to have this feature enabled, I want to make sure that we could actually make it work in cross-browser, fast and easy to use way.
Basically a Sakai3 page process looks like this:
- Load a Sakai3 page with all it’s resources (HTML / CSS / JavaScript / Images)
- When this page is loaded, load all the widgets you embedded on that page.
The Sakai3 widget process goes a bit deeper:
- For each widget type, send one GET request to it’s path. (e.g. devwidgets/twitter.3.json)
- Run over all the properties in that file and divide it into 3 sections: HTML / CSS and JavaScript.
- Save those 3 sections in separate objects / arrays in the JavaScript memory.
- Remove the original <link> and <script> tags from the widget HTML.
- Add the widget HTML to the container on the Sakai3 page.
- Load the CSS and JavaScript dynamically without doing an extra request.
So instead of doing a request to an HTML file, a CSS file and a JavaScript file, we would just make one request to a JSON file.
vs.
Too be honest I got everything working quite fast (+/- 1,5 hour) but it took a bit longer to make everything cross-browser. Especially the last part, loading the JavaScript and CSS dynamically.
I knew jQuery just recently added the $.getScript but that added an extra Ajax call which I wanted to avoid in the first place. After lurking through the jQuery API and source code, I found out that the $.globalEval function did exactly what I wanted for the JavaScript part.
Maybe I didn’t look well enough, but I actually couldn’t find any native jQuery method that would load the CSS dynamically. So I wrote something that is heavily based on a post by Stoyan Stephanov:
All the code that I wrote so far is pretty much WIP and in non-development ready state. For instance at the moment I load all the CSS/JavaScript files I get back from the JSON where I should only use the ones defined in the HTML. That and some other little things still need to be fixed. But those are minor things though and I definitely think I have an awesome proof of concept.