Web Performance Optimization, Part 10: The Evolution of Client Side Caching
While we've touched upon client side caching in our series on Web performance, we haven't discussed how client caching has grown more rich and useful over the years. In the initial days of the Web and the HTTP/1.0 protocol, caching was mostly limited to a handful of headers, including Expires, If-Modified-Since, and Pragma: no-cache. Since then, client caching has evolved to embrace greater granularity. Some new technologies even permit the deployment of offline-aware, browser-based applications.
The most common and oldest type of client-side caching on the client is browser request caching. Built into the HTTP protocol standard, browser request caching allows the server to control how often the browser requests new copies of files from the server. We discussed the major aspects of browser request caching in part 1 of our series. Over time, Webmasters have taken to using different headers to improve caching on their site, including:
Pragma: no-cache. This old directive is used mostly by HTTP/1.0 servers, and instructs a client that a specific response's contents should never be cached. It is used for highly dynamic content that is apt to change from request to request.
Expires. Supported since HTTP/1.0, this header specifies an explicit expiration date for cached content. It can be superseded by the value of the Cache-Control header. For example, if Cache-Control: no-cache is sent in a response, this will take precedence over any value of the Expires header.
If-Modified-Since: Since the HTTP/1.0 protocol, clients have been able to use this header to request that the server only send data if the resource has been changed since the specified date. If there have been no changed, the server returns an HTTP 304 Not Modified response.
Last-Modified. This HTTP/1.0 and 1.1 header designates when the resource was most recently changed. Browsers usually supply this value as the value of the If-Modified-Since header.
Cache-Control. This core directive, introduced in the HTTP/1.1 standard, specifies whether a response's contents can be cached, and if so, for how long. The header "Cache-Control: no-cache" obsoletes the "Pragma: no-cache" header of the HTTP/1.0 protocol.
ETag. The ETag ("entity tag") header is a hash value that is specific to a given version of a resource. It can be used by the client in conjunction with the If-Match, If-None-Match, and If-Range headers to decide whether it should generate a new request for the latest version of a resource. The format of entity tags themselves is defined in section 3.11 of RFC2616.
Note that this header and the Last-Modified header are exclusive; servers should set one or the other. The ETag header is new with the HTTP/1.1 protocol standard.
For modern applications, the good folks at Google recommend setting one of either Cache-Control or Expires, and one of either Last-Modified or ETag.
With the advent of JavaScript and AJAX, more Web applications are downloading data dynamically. JavaScript developers can use the XmlHttpRequest object to fetch data in XML (or other) format, and display it in real time without forcing a refresh of the entire page. This presents opportunities for finer-grained caching based on the nature of the data displayed within the page.
AJAX applications can still use all of the browser request caching mechanisms discussed above. The resource requested by the XmlHttpRequest object will be stored in the browser's file cache just as other HTTP objects are. A given AJAX application can go further and make refresh calls to the XmlHttpRequest object using programmatic rules. In his article "An AJAX Caching Strategy", Bruce Perry shows how he uses a custom CacheDecider object that he wrote in JavaScript to determine when to update an AJAX display of oil, gasoline, and propane prices.
Developers creating HTML5 applications can create fully offline-aware applications using the HTML5 ApplicationCache interface. The Application Cache uses a cache manifest file to specify which files in an HTML5 application can be used offline, and which files require a network connection. The manifest may also specify a list of fallback files for network resources when the user is offline. For example, instead of fetching the file /get-data.php when disconnected, the manifest can instruct the browser to display the file /offline.html instead. This manifest is referenced in the HTML element of an HTML5 app:
<html manifest="manifest.appcache">
...
</html>
Web performance optimization is very important, and today's Web application development team can boost site performance and improve its site's load testing scores by selecting from a variety of client side caching techniques. An effective client side caching strategy can reduce load times by several factors. The most recent innovations in client side caching, such as the HTML5 Application Cache, enable an application to run (though perhaps in a more limited form) even without a network connection present.
Why Business Executives Place a High Priority on Web Performance in 2012
Happy New Year! I mean that literally...it is a happy new year for web performance geeks like you and me.
Did you ever read The Hobbit? There was a clever exchange between Gandalf and Bilbo where the meaning of "Good Morning" was discussed. Are you wishing me to have a good morning or are you saying it's a good morning whether I want it or not?
Well, 2012 is going to be a great year for the web performance and load testing industry. I wish that you have a happy new year, AND it will be a happy web performance new year whether you want it or not.
LoadStorm begins 2012 with an upbeat outlook because the last few months of 2011 showed over a 400% increase in load testing volume.
The actual number of load tests being executed by our customers were maybe only double the number in 2010, but the scale of tests was much bigger. It is also interesting to note that many more online retailers were running tests of 25,000+ concurrent users. We had many calls with traditional brick and mortar companies that were putting significant investment into their web store capabilities - including speed and scalability.
Anecdotally, we can share with you that it was a good investment because some of those customers told us that their online sales had risen as much as tenfold (10x) over the previous year! That's great news for all of us web performance engineers.
Not only does it seem clear to us that web stores are getting high priority for e-commerce, but it is also clear that web performance has gotten much more attention from the C-suite. Several of our customers mentioned their load testing projects were being driven from executives worried about site crashing under heavy traffic. That's outstanding! Finally, the stories of Web site performance failures is getting the attention it deserves. I guess it was tough to ignore all the headlines blasting companies like Target when their site crashed in 2011.
Operations and marketing leaders are starting to understand the correlation between web performance tuning and profitability. Web sites are not just online brochures, nor are they just a secondary revenue channel. The message that is coming through loud and clear is that faster sites make more money.
In more than one project-related conference call with companies running load tests of 50,000-100,000 concurrent users, there was a VP of Marketing being very active in driving her/his team regarding the results he/she was expecting. It was refreshing (somewhat shocking) to hear a 60 year old traditional advertising agency veteran telling everyone on the call that "sub-second response time is imperative to success!" I loved it. The web coders...not so much because they had lots of optimization ahead of them.
The trends are exciting. The attention and high priority placed on web performance is logical because the stakes are so high. More money is flowing every year from buyers to web stores.
People were spending well this holiday season and Cyber Monday 2011 experienced double-digit growth over 2010. Some key activity metrics from IBM's Benchmark December holiday report :
- Department stores online sales were up 18 percent over December 2010.
- Total online sales were up 7.5 percent over 2010.
- Mobile device buyer traffic jumped from 5.6% of all sessions to 14.6 %. That's 160% higher than last year.
- Sales from mobile devices doubled, reaching 11% versus 5.5% in December 2010.
- Christmas Day 2011 online shopping grew by 16.4% over 2010 - people kept on shopping.
Money is the lifeblood of business. ROI drives business decisions. Better Web performance results in higher sales.
Web performance engineers rejoice! We are now more important than ever to the CEO. Job security, promotions, raises, and lots of other goodness will follow swiftly!
Web Performance Optimization, Part 9: Optimizing HTML
In our past installments on Web performance optimization, we've seen how caching, server configuration, and the use of Content Delivery Networks (CDNs) can increase a Web site's responsiveness and improve Web performance metrics. Most of the techniques we've reviewed have focused on configuring the Web server or optimizing server applications. Unfortunately, a Web page that downloads quickly but is slow to parse or execute on the client will appear just as slow to a user as if the Web server were on its last megabyte of memory. In this article, we'll discuss some ways that Web page content can be streamlined for an optimal client-side experience.
Streamline JavaScript Includes
JavaScript abounds on the Web. From jQuery to Dojo, the Web is full of JavaScript libraries that can easily be dropped into a Web application. And any site whose developers are actively adding features is going to accrue its own storehouse of .js files. Unless a site's JavaScript is carefully managed, its Web pages could end up making a dozen or more separate requests for scripts. As we've already discussed in our article on
web performance optimization non-caching strategies, the more requests your site makes, the slower it will load.
Tip of the hat to TechAttitude.com for the graphic showing how Web page sizes and number of objects have grown tremendously over the past 16 years. In the interesting article they state, "...the average size of a web page has increased by more than five times since 2003" and "the use of mulitmedia is increasing by 100% each year".
Follow these guidelines to manage and reduce the burden of JavaScript on your Web pages.
- Use Minify to combine script files. As discussed previously, Minify will compile all of your disparate JavaScript files safely into a single .js file. This can collapse the number of HTTP requests made by a page from a half-dozen or more down to one single request.
- Remove unnecessary or expensive includes. JavaScript files whose functionality is no longer used should be stripped out. Site owners should also consider removing functionality that causes a script to load and execute multiple times on a page (e.g., a social media script that forces a script fetch for every individual post in a blog scroll).
- Consider a JavaScript compressor. If your site is loaded with client-side code, it may be worthwhile to use one of the many freely available JavaScript compressors on the market to shrink down your files. JavaScript Compressors remove extraneous whitespace, strip out comments, and shorten variable names. This means that JavaScript files not only faster to download, but faster to interpret and execute. A good JavaScript compressor is ShrinkSafe, which is also built into the dojo JavaScript toolkit.
Performance Tune Your JavaScript
Of course, optimizing JavaScript includes won't help much if the code you use is inefficient. Poorly written or maintained JavaScript can harm browser performance in a number of ways. Consider:
- Closures. Closures are the most common cause of memory leaks in JS. A closure is a powerful mechanism that allows functions to be treated as first-class objects by retaining their execution context. Often, hard to spot circular references between a closure and one of its scoped variables causes the closure to remain in memory indefinitely. While the performance impact may be negligible at first, it builds quickly over time, until the user's browser is running so poorly that she has no choice but to restart it.
- Circular references. Two objects that hold references to one another will never be garbage collected by the JavaScript run-time engine, resulting in even more leaked memory.
- DOM interactions. JavaScript is at its slowest when interacting with the Document Object Model (DOM).
Developers can surmount these problems using certain tools and techniques:
- Performance test JavaScript code. Performance testing can be as simple as using timestamps to measure the execution time of a particular segment of code. Developers who require a more detailed analysis of their code may opt to use a performance testing package such as jsPerf or jsLitmus.
- Avoid using expando properties. Another common source of memory leaks. As Gregory Baker and Erik Arvidsson note in their article on JavaScript performance, "You can use expando properties without introducing memory leaks, but it is pretty easy to introduce one by accident."
- Avoid closures whenever possible. The IE team has provided an in-depth explanation of why developers should avoid closures except when absolutely necessary.
The book Speed Up Your Site: Web Site Optimization goes into even greater detail on subjects such as minimizing DOM interaction, selecting efficient algorithms, and improving loop execution.
Another in-depth resource that I recommend you explore is JavaScript Performance Rocks! by Amy Hoy & Thomas Fuchs. It's a bundle of PDF books, demos, and a DOM Monster profiling tool for $39.
Remove Unnecessary or Expensive HTML
Finally, developers can squeeze even more performance out of their downloads and page rendering by cleaning up extraneous markup in HTML documents. This includes, but is not limited to:
- Reducing the use of DOM elements, such as unnecessary DIV and SPAN elements. These are expensive to create and maintain, and can cause memory bloat over the long term.
- Remove unnecessary IFRAME elements.
- Remove any IMG or IFRAME tags with a blank src attribute. These cause an additional request to be sent to the server.
- Remove extraneous comments. They increase download time, and are stripped out by the parser anyway.
- Keep META tags and META content to a minimum. Other than the Description tag, most of the META elements no longer have any value for SEO.
Conclusion
The greatest factors in Web site performance are the number of requests between the client and the server and the speed of the individual requests. It is best to address these issues first through caching, tuning the Web application (database interactions), and Web server configuration before tackling HTML optimization. Development teams and Web site operators who have already addressed these issues can then optimize their client-side code to ensure that their pages load and execute efficiently once they are delivered to the client.
Web Performance Optimization, Part 8: Content Delivery Networks
So far in our series on Web Performance Optimization, we've focused on how to reduce the number of requests between client and server through caching, and how to make requests more efficient by managing server resources. Another strategy in Web optimization is intelligent distribution of resources across the Internet, which can greatly reduce request latency by locating redundant copies of Web content on multiple servers spread across the Internet. In this installment of our series, we focus on content delivery networks (CDN), a technology that increases throughput by bringing content closer to the people requesting it.
In the simplest Web site configuration, a single Web server services requests from multiple clients. While this is often good enough for the simplest, lowest traffic Web sites, complex Web sites that need to scale to thousands or millions of visitors require more processing power. This is why many sites have resorted to using Web server farms, which are clusters of multiple Web servers offering redundant copies of a site's content. Web farms use load balancing software to monitor the amount of load on any one server. They can also use this information to route requests to the server with the least load at a given point in time.
A CDN is a type of Web farm or server cluster, except that instead of using a single farm or cluster, the servers are spread out over the Internet in multiple geographical locations. These are called edge servers, because they are located at the extremes, or edges, of the Internet, instead of all being located off of a central Internet backbone link. The goal of a CDN is to decrease the time it takes to deliver content to a specific user based on that user's location.
Let's say, for example, that a company based in New York receives a request for Web content from a user in Seattle, WA. In a traditional setup, the Seattle computer's request would have to find the most efficient route on the Internet to New York, usually via a busy backbone link. In a CDN configuration, the CDN could tell the Seattle client that its nearest edge server is on a subnet in Portland, Oregon. By obtaining the content from a server closer on the network, the client greatly reduces request latency.
CDNs can be used for a wide range of content. The majority of a Web page request is spent downloading dependencies such as images, CSS scripts, and JavaScript files. Placing this relatively static content on a CDN can provide a significant performance boost. Companies that serve streaming content, such as audio and video, can utilize CDNs to deliver high-definition video streams and high bitrate audio with better image quality and fewer pauses to buffer content.
The boosts achieved from using a CDN can be significant. In 2010, the CDN performance tracking site CloudClimate.com not only compared the performance of 24 CDN and cloud computing companies against one another, but also compared the performance of cloud-based Web sites both using a CDN and not using a CDN. The results were astounding: for every cloud-based provider tested, CloudClimate.com found that adding a CDN into the mix provided a speed boost of up to 50%.
Another company that noticed the performance benefits of CDNs is Yahoo!. The company claims that when it started using a CDN in 2007, it achieved a 20% or greater boost in end-user response times.
CDNs differ in how they cache content and deliver it to users. Following are some of the most common types of CDN.
- Push. In a push CDN, a central server replicates its contents to the edge servers, so that every edge server has the latest copy of the content on the origin server.
- Origin Pull. An origin pull CDN server caches the latest copy of a static file from the origin server, and serves this cached copy to subsequent users. The caching Web server relies upon the caching mechanisms defined by the HTTP/1.1 protocol, which we covered in a previous article.
- Application. While most CDNs deploy static content, an increasing number are branching out to offer distributed application services, replicating server-side applications written in languages such as PHP and .NET to edge servers. EdgeCast Networks launched its own application CDN service in April of last year, claiming that the companies that tested the service in beta experienced performance gains ranging from 40 to 250 percent.
- Peer-to-Peer. A peer-to-peer CDN shares cached content amongst users of the same site. For example, User 1 downloads the first minute of a video from a popular Web site. When User 2 and User 3 request the same content, the CDN instructs them to download it from User 1, thus reducing the overall load on the origin server. This CDN model is most typically used for audio and video content.
The Costs of Using a CDN
One of the benefits of using a CDN these days is that there are so many providers. This means that development teams need not squander resources development their own CDN solutions. Furthermore, the abundant competition has also pushed prices to all-time lows. Most CDN companies offer their services on a metered basis, and charge only pennies per gigabyte of data served to users. Other CDN providers charge flat fees, such as $40 or $60 for the first terabyte - enough bandwidth to serve many small sites for a full year.
CDNs have an excellent cost/benefit ratio, as they expand Web server capacity by 20-50% or more at low cost to the Web site operator. Whether you run a small site with thousands of users a day or a massive site that serves millions, you can achieve significant performance testing improvements by offloading all of your static content to a CDN.
Web Performance Optimization Part 7: WordPress Tuning
In recent years, the good folks at WordPress have made it easier to use their free software not just as a blog, but as the hub of a rich content management system (CMS), complete with static content and custom data types. Given that, it's no surprise that Webmasters and businesses around the world are increasingly basing entire sites around the platform. (And did we mention the "free" thing?)
While WordPress runs decently out of the box, site operators who employ a few tweaks and follow a few rules of thumb will achieve much better performance in the long run. In this article, we look at the best practices that will keep your WordPress site humming efficiently.
WordPress plugins are great. With a few clicks, ordinary users can add complex functionality to WordPress that otherwise might have taken hundreds or thousands of hours of programming.
But plugins also present a performance danger. Each plugin in the WordPress plugins directory must be loaded every time a new request is made. Even if the plugin is disabled, it will still load. This performance "gotcha" particularly affects sites on shared virtual hosting systems (e.g., Dreamhost, HostGator). Performance degradation can be dramatic on shared hosts; in some situations, user requests may never finish completing.
The number of plugins that will cause a site to slow down will vary based on a variety of factors. The author has been told by representatives of HostGator that they encourage customers to limit the number of installed plugins on their virtual hosting service to seven. Webmasters should select the WordPress plugins they employ carefully, and use a load testing service to measure the performance impact of any new plugins that they add to their system.
Which WordPress plugins should you keep? The best plugins are those that:
- provide critical functionality that isn't available in the core WordPress product; and
- cannot be implemented by making changes to your WordPress template.
For example, while a social media plugin may be a fast way to add a Facebook "like" button to every post, it's also something that a savvy WordPress user can work into their current template. By contrast, an anti-spam plugin such as Akismet provides behind-the-scenes processing that goes above and beyond a simple template change.
Speaking of necessary plugins, let's talk about caching. As discussed in previous articles, there are many different types of caching, including client-side file caching, application caching, data caching, and PHP opcode caching. WordPress does not provide any native controls to control these various aspects of caching. Fortunately, a number of plugins exist to fill the gap.
Currently, the best plugin for all-around caching on WordPress is W3 Total Cache. W3TC can be used to configure many of the caching options we've discussed in previous articles, such as:
- Critical client-side cache control headers, such as the Expires, Cache-Control, and ETag headers
- Server-side caching of compiled WordPress pages
- Caching of database objects
- Applying Minify to Javascript files to reduce the number of scripting files downloaded
Verify the Performance of Individual Plugins
While a plugin may be convenient, that doesn't mean it's been coded correctly. A "cool" plugin that generates expensive or redundant calls against the WordPress database can drag your site's performance into the mud. (Some plugins, as as the YARPP related posts plugin, are known CPU hogs.) Try disabling plugins selectively, and use a load testing tool to measure whether there is a noticeable benefit to the performance of your site.
An inefficient WordPress template can drag down the performance of your WP-powered site. Switch your blog to a standard theme, and see how it performs (especially under heavy loads generated through load testing) compared to your site's main theme. If it's significantly slower, your theme may benefit from one or more of the following enhancements:
- Consolidate redundant and expensive database calls.
- Consider removing code that generates calls to other Web sites. On the server, this includes things such as RSS feed plugins. On the client, it may be code such as social media scripts that display the number of likes or shares for a given article.
- Remove Javascript files that are no longer being used.
- Offload static files such as Javascript and CSS to a separate server, as described on the WordPress.org Web site.
Optimize Apache
WordPress can only be as efficient as the Web server that hosts it. If you run WordPress off of a non-shared Apache server, review and apply our Apache performance tips.
While WordPress reduces much of the complexity involved in running a Web site, it can complicate performance. The platform's very ease of use can lure users into deploying template changes and using plugins that can cause slow response times, especially under high load. Fortunately, most of these performance traps can be avoided by minimizing plugins, deploying a caching solution, optimizing WordPress code, and load testing on a regular basis.