Performance Research, Part 6: Less is More — Serving Files Faster by Combining Them

By Tenni TheurerJuly 21st, 2008

This article is the sixth in a series of YUIBlog articles describing experiments conducted to learn more about optimizing web page performance (Part 1, Part 2, Part 3, Part 4, Part 5).

In Performance Research Part 1, we discussed how reducing the number of HTTP requests has the biggest impact on improving the response time and is often the easiest performance improvement to make. One technique without having to simplify the page design is to combine multiple scripts into a single script, and similarly combine multiple stylesheets into a single stylesheet.

Combining multiple files reduces the extra bytes from HTTP headers as well as potential transfer latency caused by TCP slow starts, packet losses, etc.

Figure 1 shows a graphical view of how time is spent loading a page with six separate scripts. Notice that for every file, the browser makes a separate HTTP request to retrieve the file. The gaps between the scripts indicate the time the browser takes to parse and render each script. Figure 2 shows the how time is spent loading a page with the same six scripts combined into a single script.

Figure 1. Loading a page with six separate scripts

Figure 1. Loading a page with six separate scripts

Figure 2. Loading a page with one combined script

Figure 1. Loading a page with one combined script

Combining JavaScript and CSS files as part of the development process can be burdensome. It usually makes sense during development to organize the code into logical modules as separate files. Typically, combining those separate files before product release is either a manual process or part of a build process. Every time one of the individual files is changed, the larger file needs to be re-combined and re-pushed. The cost of this across an organization as large as Yahoo! is significant.

Serve Files Faster using Combo Handler

Combo Handler, built in collaboration by Yahoo!’s Exceptional Performance team and the groups that support our CDN, is one solution to combine multiple files into a single, larger file.

Combo Handler provides a way to allow developers to maintain the logical organization of their code in separate files, while achieving the advantages of combining those into a single file as part of the final user experience. It alleviates the need for the time-consuming re-build and re-push processes. In addition, Combo Handler integrates seamlessly into a content delivery network, taking full advantage of the benefits of a CDN while reducing the drawbacks of dynamically combining separate files.

We’ve been using this service across many Yahoo! properties for some time now to help improve end users’ response times. Thanks to the YUI team, it is now available to all of you that are using the Yahoo!-hosted YUI JavaScript files. (Note: Combo-handling of CSS files is not supported at this time.) Head over to the YUI Configurator to generate combo-ready filepaths customized for your specific YUI implementation.

Combo Handler Best Practices

When using Combo Handler to combine files, pay special attention to the order in which the files are specified. Not only could there be file dependencies, browsers will only use the cached version of a file if the filename extracted from the URL is identical. For example, suppose the following smaller files (dom.js and event.js) are combined into a single larger file using Combo Handler:


http://yui.yahooapis.com/combo?event.js&dom.js


http://yui.yahooapis.com/combo?dom.js&event.js

In the example above, the browser will download and cache both files separately because the filenames are actually different.

Also, you may not always want to combine all files into one single file. Suppose you have one or more scripts that are shared across multiple pages in your site in addition to scripts that are only used on specific pages. By combining everything into one large file and using this file across your entire site, some pages will spend time downloading more than it really needs. Instead, take a look at different types of combinations. You might combine the scripts that are used in every page across your site into one script. Then for each page or group of pages, combine common scripts into another separate script.

Yahoo! HotJobs Combines and Reduces Response Time by 8%!

The Exceptional Performance team ran an experiment with Yahoo! HotJobs to determine the response time savings our users would benefit from by combining multiple files into a single file. Two real user test buckets were created for this experiment. In one bucket, users visited a page with six JavaScript files left uncombined. In the second bucket, users visited the same page with the six JavaScript files combined into one single file.

Combining six JavaScript files into one single JavaScript file improved performance by almost 8% on average for Yahoo! HotJobs’ users on broadband bandwidth speeds and 5% for users on lan. No design or feature changes required!

Keep in mind that the page we tested was already highly optimized for performance and had a YSlow “A” grade. The response time savings depend on a number of factors including number of files combined, browser caching patterns, etc. This experiment supported our previous research, which indicated that reducing HTTP requests is an effective way to improve response times for our end users.

Takeaways

Improve response times by combining multiple JavaScript and CSS files. Yahoo!’s Combo Handler Service is one solution that provides a way to make fewer HTTP requests for Yahoo!-hosted JavaScript files, and also leverages the benefits of a Content Delivery Network.

  • Combine scripts and stylesheets to reduce HTTP requests.
  • Look at different types of file combinations.
  • Avoid users from having to download more than they really need.
  • Pay special attention to the order in which files are combined.

15 Comments

  1. Keep in mind that the page we tested was already highly optimized for performance and had a YSlow “A” grade.

    This deserves emphasis; even on pages that have been built exceptionally well (from a high-level front-end perspective), a real improvement can be achieved by understanding the protocols that underlie the infrastructure.

    I’m very curious to know if the exceptional performance team has any data on the real-world impact of combining files that are offered over secure connections? I assume the improvement would be even greater given the longer handshake that is required to establish an HTTPS connection.

  2. So I’ve done some thinking and experimenting on this topic and wanted to bring up a point for discussion.

    Does it make sense to have only a script tag referencing the YUI Loader (or YUILoader, Dom, Event rollup) in your [XHTML] markup to allow the onDOMReady event to fire sooner and load the rest of your YUI files via the loader dynamically?

    My feeling is that using this combo filter thing has some drawbacks when the combo-”file” coming over the wire is huge; specifically on perceived performance and the time-lag before the onDOMReady event fires.

    Currently I’m taking the approach of only referencing the yuiloader-dom-event.js in my markup, and using the YUI Loader to load the additional YUI and non-YUI external JS files and resources.

    What are your thoughts on this?

  3. what about <?php include-ing all my .js files under a single tag?
    I understand that this makes the content block, but in all the page seems to load much faster.

  4. Java developers widshing to combine their script and CSS files might be interested in the open source project Jawr. Jawr offers script combination, minification, gzipping, expires headers set to the far future, and automatic changing of URLs when content is changed.
    It can be used with YUI, supporting a development mode in which you might for instance use uncompressed scripts for debugging and the logging console, all of which is disabled in production.

  5. This is good. Just a side question, aren’t client scripts are cached at browsers and this overhead is only for the first request?

    Suppose, I have a total of 25 script files that are referenced across my web application pages and are requested only once and cached.

    However, if I go for combo strategy, as my pages are referencing only a subset of them, and I combo them. Each of this combination will be cached at browser as different file, because for browser each combo is a different script file. Now think, how many combination will those 25 scripts will have? Isn’t the plain approach is better?

  6. Each of this combination will be cached at browser as different file, because for browser each combo is a different script file.

    I was also thinking the same thing. I know it used to be stated that one of the benefits of using the Yahoo CDN was that users might already have the YUI Library files caches from being on other website and using other application before using yours.

    Intra-site/app performance may take a hit at Patay is saying with different pages or screens requiring a different combination of resources.

    One possibility would be to load all the possible resources your site/app would ever need using the CDN combo service and referencing that combo file on every page/screen. << Seems that could lead to a large payload of stuff for a user on their first visit/pageview.

  7. Luke Chambers said:
    July 22, 2008 at 9:09 am

    The gaps between the scripts indicate the time the browser takes to parse and render each script.

    Isn’t the figure 1 slightly misleading in that the browser will block during parsing and rendering. Therefore, the real browser “response” will occur afterwards this completes. Presumably, the parse/render time of the combined script would be equal to the sum of the parse/render time for each individual script. Thus, the combined file would have a large “gap” after downloading until the parse/render completes.

    Also, how does downloading 1 file compare to the benefits of achieving parallelization of downloading 2?

  8. Tenni Theurer said:
    July 22, 2008 at 12:22 pm

    @αlexander: We didn’t run any experiments on secure pages yet, but that would be my assumption as well.

    @heatdphondotes: You should include all (or some combination) of scripts using one script tag as opposed to separate script tags. Also, consider different ways of combining files taking into consideration browser caching, shared versus unshared files across pages, scripts at the bottom performance rule, etc.

    @Patay/Eric: I addressed this concern under the Combo Handler Best Practices section: “By combining everything into one large file and using this file across your entire site, some pages will spend time downloading more than it really needs. Instead, take a look at different types of combinations.” Also, keep in mind that not all users will visit your site with a primed cache: Performance Research Part 2

    @Luke: I probably should have added an image component at the end of both figures to illustrate when the pages finish loading. You’re correct in that there would still be a gap between the combined script and image in figure 2 for the time the browser takes to parse and render. However, the overall response time is still typically faster when using a combined file versus six separate files.

  9. [...] Theurer of Yahoo! has a new performance post, this time focused on serving files faster by combining them: One performance technique without having to simplify the page design is to combine multiple [...]

  10. where is part 5, 4, 3, 2 and 1???

  11. An easy but powerful Java solution is pack:tag.

    This JSP taglib dynamicaly minifies, combines, gzippes, sets various headers, takes care of browser-caching issues (like changing the URL when the file has changed), recognizes changes in the files, and more for JavaScript and CSS.

    And it’s easy to use:

    Take a look into the guide.

    There are various supported compression algorithems that are available out-of-the-box, like YUI Compressor, JSMin, ..

  12. Tenni Theurer said:
    July 23, 2008 at 8:40 am

    @googler: Part 1, Part 2, Part 3, Part 4, Part 5

  13. @googler: the other parts are linked at the very top of this article

  14. I’ve implemented the combine js\css files.
    In addition the conbined files are minifed and stored on CDN.
    The impact was 1.5-2.5 secs for each page.
    I recomand using the AOL pagetest for IE(which is the more problamatic) and YSlow for FF.

  15. [...] As it might be expected, there are several techniques to optimize the delivery of web pages. The Exceptional Performance guide by Yahoo is a great resource for a multitude of optimizations practices, including specifically two techniques which I will address in this article – script minifcation and concatenation. [...]