Canonical Voices

Posts tagged with 'yui'

Michael

I had a few hours recently to try updating my Open Goal Tracker javascript client prototype to use jQuery Mobile for the UI… and wow – it is so nice, as a developer with an idea, not having to think about certain UI issues (such as a touch interface, or just basic widget design). I can see now how ugly my previous play-prototype looked. Here’s a brief demo of the jQueryMobile version (sorry for the mumbling):

 

That’s using jQuery Mobile 1.01 for the UI and YUI 3.5.0PR2 for the MVC client-side framework, although I’m tempted to move over to backbone.js (which is what the YUI application framework is based on, it seems). Backbone.js has beautifully annotated source and a book – Developing backbone applications - which so far seems like very worthwhile reading material.

The prototype can be played with at http://opengoaltracker.org/prototype_fun/


Filed under: javascript, jquery, open-goal-tracker, yui

Read more
mitechie

Just a heads up, this week’s CoffeeHouseCoders (CHC) Detroit-ish will be a bit different. One of the goals of moving the location to the new Caribou was that we get access to the meeting room. This opens up the opportunity for us to have some group discussion and such around various topics. We’re going to give that a shot this week with a group viewing of YUI Theater video viewings and JavaScript discussion.

Most of us do at least some JavaScript in our work and projects so I think it’s relevant and should be fun to geek out before the holidays start up. I’ll have a little projector and speaker and with the new videos from YUIConf 2011 going up, it’ll be nice to set aside some time to catch up on some of the recorded presentations. Take a peek and set aside one or two "must watch" videos for Wed night! Not all of the videos are YUI specific, so it should be useful for all of us doing JavaScript.


Read more
Michael

I’ve been playing around wit h YUI’s new application framework over the past few weeks, basically building on the ToDo list example app, extending it for a basic interface for the Open Goal Tracker project. Here’s a 2 min demo:

I’m loving the MVC separation in the client code, separation of templates, ability to use real links for navigating within the client (which will also work when copy-n-pasted to hit the server) etc.

If anyone is interested, you can play with the code yourself:

$ bzr branch lp:~michael.nelson/open-goal-tracker/html5-client-play
$ cd html5-client-play
$ fab test

which will setup the dev environment and run the django tests… followed by

$ fab runserver

To play with the demo html5 client: http://localhost:8000/static/index.html
To run the javascript unit tests: http://localhost:8000/static/app/tests/test_models.html

or find out more about the purpose of the app with the first 2 mins of this video from a year ago outlining where i hope to go with the application: http://www.youtube.com/watch?v=OT7P-u-86sM (when time permits :) ).


Filed under: javascript, yui

Read more
Sidnei

Ever since I got my copy of Steve Souders’ Even Faster Web Sites I’ve became obsessed with speed. During my day job I’m constantly looking for things that can be improved to make the user experience smoother, specially for first-time visitors. I’m fairly happy with what we’ve achieved in the last year, though there are always things to be improved.

Today I’m going to share with you one of the tricks that we’ve discovered almost by accident and that can help with making your website faster, if YUI is your Javascript framework of choice.

We’ve started using YUI in Landscape around March of 2009, by rewriting all of our ExtJS-based scripts (which weren’t that many) to use YUI. Since our application requires HTTPS due to potentially sensitive information, we had to self-host YUI, to avoid mixed-content warnings. Initially we had little experience with it, so we went with the easiest option available: loading the YUI seed file and letting everything else be loaded on-demand by the YUI Loader, without a combo handler (more on that later).

Soon enough we noticed that it wasn’t such a great idea. First-time access was terrible, with load times over 30 seconds in some cases, due to the combination of HTTPS connection overhead, no static resource caching and large number of requests to fetch all the resources. It was worse than that even, because most browsers either don’t cache HTTPS content by default, or only cache it on memory, unless you set the proper caching headers. To give you an idea of what it looked like, here’s what a trivial page using the ‘overlay’ module looks like in terms of loading.

No combo loading at all

No combo loading at all

It was pretty clear that this kind of performance would not be acceptable, so I started looking for options to reduce the number of requests. It was around that time that I heard about Steve Souders work on web performance, through a long time friend from the Plone community that happened to be working at Google and shared a link to Souders’ blog post on ‘@import’.

Turns out that the YUI Loader supports using a combo handler for reducing the number of requests, when loading modules on demand. What this ‘combo handler’ does is basically take a GET request with a bunch of filenames as parameters and return a single response with the respective files concatenated. Here’s an example using the combo server from YUI’s CDN.

Combo loading with a single 'Y.use()'

Combo loading with a single 'Y.use()'

The problem was that we couldn’t use YUI’s combo server on the CDN because it doesn’t support HTTPS, which was requirement for us.

In November of 2009, at UDS-Lucid in Dallas, we had our first YUI-only cross-team sprint, totalling about 20 people from Launchpad, Landscape, ISD and Ubuntu One. The main goals were to spread knowledge on YUI and improve support for IE on our shared codebase (lazr-js), but I managed to sneak in two things for the Landscape team: implementing a Python-based combo loader (served by Twisted, but it’s just a plain WSGI app) and extracting YUI module metadata, so that we could make it easier to load extension modules on-demand, the code for which ended up as part of the lazr-js project.

At this point however we realized that there’s a significant issue with using the combo loader on an application as diverse as Launchpad or Landscape: depending on how you group your ‘Y.use()’ calls, the combo URL generated by the YUI Loader can vary significantly, which means that re-use from the browser cache is less than optimal. Here’s an example of loading both the ‘anim-color’ module and the ‘overlay’ module within a page. Compare it to the previous example and notice how the parameters passed to the combo are completely different, since the second request (to load the ‘overlay’ module) only requests modules which haven’t been loaded by the first request (to load the ‘anim-color’ module).

Combo loader can be a caching problem

Combo loader can be a caching problem

In a hurry to get the situation solved ASAP, and taking a clue from our fellow developers on the Launchpad team, we went with a simpler alternative: manually combining all of YUI, including the seed file, and loading all of that in a ‘script’ tag in the document ‘head’. It turns out that the situation improved quite dramatically, but there was still more to be done. Although the number of requests was much smaller, the total page size was actually larger, since we were loading a lot of stuff that wasn’t even being used. Worse, since we were putting that ‘script’ tag in the ‘head’, it was blocking the whole page from loading until the script was finished downloading, which I after following Souders’ blog for a while I realized wasn’t such a great idea either. Here’s an example of what that looked like.

Combined modules in the head

Combined modules in the head

At this point we had a significant codebase of YUI-based modules, and so did the Launchpad team, but we had gone from solely relying on the YUI Loader to not using it at all (by just loading all the code in one big honking file).

Once we got the module metadata extraction figured out though, I resumed working on improving the first-view load time, by reducing the number of modules manually combined to the bare minimum shared by all of our pages. Also, by having a single file with the common modules being loaded on all the pages, we can be sure that it is highly cacheable. And then we let the YUI Loader kick in and load the missing modules on less-used pages, which was a really nice improvement in page weight and reducing the time to the ‘onload’ event.

At this point Souders started talking about asynchronous loading of scripts and the ‘defer’ attribute, and I got my copy of Even Faster Web Sites. I started pondering if there was something that could be done to defer the loading of the combined modules while still letting the YUI Loader do it’s job.

The problem lies in the fact that YUI asynchronously loads modules that are not on the page yet, calling a callback function (the last argument to ‘Y.use()’) once all the scripts containing the required modules have finished loading. If all the modules are already on the page, it just calls the callback right away. So by just tacking a ‘defer’ attribute on the ‘script’ tag for the combined modules there would be a race condition between the loader checking if the modules were loaded and the script with the combined modules being loaded.

Then, it struck me. If the last argument to ‘Y.use()’ is just a callback function, could we queue those functions to be called at a later time and load the combined modules ourselves, before letting the YUI loader proceed? After a little back and forth with Dav Glass and some pseudocode exchange, I got an implementation of this idea(which I’m calling the ‘Prefetch YUI Loader Hack‘). And thus we managed to move the loading of all the combined modules from a ‘script’ in the ‘head’ to use asynchronous script loading, shortening even further our time to the ‘onload’ event. Here’s an example of what it looks like.

Prefetch with a single request

Prefetch with a single request

But wait, there’s more! Souders then started talking about parallel loading, tickling my speed bug again. After thinking for a while about the problem, enlightenment came again: when an YUI module is loaded, it is not executed right away, but added to an internal registry of modules. What that means is that regardless of what other modules it depends on, they can all be loaded independently from each other! That means you can break up a manually combined file into N smaller files and have them be loaded in up to N parallel connections (where N varies by browser and by browser version) and when they are all done you can let the YUI Loader kick in. Here’s an example with two parallel downloads plus an extra module not prefetched.

Prefetch, with parallel download

Prefetch, with parallel download

So that’s where things stand now. There are still optimizations that can be done in Landscape, like using the combo loader to reduce the number of requests on less common pages, or even using fixed URLs to the combo loader with the prefetch hack, to simplify the build process. We also need to start using Caridy’s Event Binder module, since now the pages load so fast that the users start clicking around before the event handlers are in place (ha!).

I am also pushing to get those kinds of tips documented and passed around Canonical, through a project codenamed Dare2BFast, which has the goal of coming up with a set of Web Performance Guidelines that all Canonical web sites should follow, both on the frontend and backend. Stay tuned!

Read more