views:

28

answers:

1

So if I'm using the YUI loader (on Yahoo's servers) to serve JavaScript, and I tell it to use combinations so several YUI Widgets can be downloaded by the browser in a single request, doesn't that make it much more difficult for the browser to cache the JavaScript?

Say I have a site with two pages, and the first one uses the YUI Calendar, Dialog, and Tree widgets, and the browser gets them all in one combined request from YUI's servers.

And the next page only uses the YUI Calendar and Dialog, but not Tree. Doesn't that mean it's technically a different request to Yahoo's servers now, with a different query string? Meaning those two widgets will be downloaded again, even though they were just used on the first page?

In that case, is it better to have one request to the combo server which will result in one single request of (in many situations) uncachable JavaScript? Or several requests for individual YUI components which can be cached?

(YSlow doesn't seem to mention anything about this question.)

+2  A: 

It is most likely better to use the combo service. On the first visit to your page, users would be penalized by the amount of http overhead and the processing overhead associated with receiving each file. Also, there's still the issue of browser limits on concurrent connections, so async or not, the un-combo handled files would result in far worse page load time. While you would benefit for those individually cached files on subsequent pages, in all likelihood, each page is going to have other module requests which would amount to more http requests (remember one different module could mean more than one module request after dependencies are accounted for). So it amounts to optimized network IO for first page, then larger payloads with minimal http overhead on subsequent pages vs very *un*optimized network IO for first page, then less content with more http overhead on subsequent pages.

If you have a site with many js-enabled pages or you otherwise attempt to mitigate the initial module loading issues, there may be justification in avoiding combo. But really, if it is a matter of shaving every last ms from the loading step, A) you may be missing more fruitful optimizations, and B) the only real way to answer your question is by profiling.

Another approach to address the situation you identify is to configure the YUI instance at construction with some custom rollup modules that represent common groupings of modules you use. This can be a pretty involved undertaking and would naturally introduce a maintenance step.

So in summary, there's probably less to worry about than you think, and allowing default behavior using combo is easy. Any definitive answer would be case by case, and based on profiling your app.

Luke
Also, for the specific use case where you use Calendar and Dialog on both pages, but only Tree on one, you can specify an initial use(..) that included Calendar and Dialog, then on the page that used Tree, call Y.use('treeview',...) later at run time.
Luke
I agree the only way to find out which is better is by profiling. I suspected that minimizing the HTTP requests and downloading more data is _generally_ better than making several HTTP requests which are likely to be cached.However, this leads to the next question: By this logic, if HTTP requests are more costly than uncachable data, wouldn't it be even better to have all your JavaScript included inline? Using a server-side scripting language would make that trivially easy, and though it would result in data which is less likely to be cached, it would also result in one less HTTP request.
Sean
Inline scripts block page rendering, but dynamically added scripts don't. Reducing the number and size of inline scripts allows the page to display faster. Reducing the number of scripts (dynamic or not) over all saves on http overhead and avoids the concurrent connection limits imposed by browsers.You could include an inline script that does nothing but add a <script> tag for the combo of the YUI seed + all requested modules, but you'll still need to wire up a "ready" mechanism to integrate with your implementation code.
Luke