John Resig: Drop-in JavaScript Performance
I wrote a post on the Google Code Blog about John Resig’s tech talk “Drop-in JavaScript Performance.” The video and slides are now available.
In this talk, John starts off highlighting why performance will improve in the next generation of browsers, thanks to advances in JavaScript engines and new features such as process per tab and parallel script loading. He digs deeper into JavaScript performance, touching on shaping, tracing, just-in-time compilation, and the various benchmarks (SunSpider, Dromaeo, and V8 benchmark). John plugs my UA Profiler, with its tests for simultaneous connections, parallel script loading, and link prefetching. He wraps up with a collection of many other advanced features in the areas of communiction, DOM, styling, data, and measurements.
User Agents in the morning
Every working day, a script runs at 7am that opens ~20 websites in my browser. I open them at 7am so that they’re ready for me when I sit down with my coffee. I’m the performance guy – I can’t stand waiting for a page to load. Among the sites that I read everyday are blogs (Ajaxian, O’Reilly Radar, Google Reader for the rest), news sites (MarketWatch, CNET Tech News, InternetNews, TheStreet.com), and stuff for fun and life (Dilbert, Woot, The Big Picture, Netflix).
The last site is a page related to UA Profiler. It lists all the new user agents that have been tested in the last day. These are unique user agents – they’ve never been seen by UA Profiler before. When I first launched UA Profiler, there were about 50 each day. Now, it’s down to about 20 per day. But I’ve skipped over the main point.
Why do I review these new user agents every morning?
When I started UA Profiler, I assumed I would be able to find a library to accurately parse the HTTP User-Agent string into its components. I need this in order to categorize the test results. Was the test done with Safari or iPhone? Internet Explorer or Maxthon? NetNewsWire or OmniWeb? My search produced some candidates, but none of them had the level of accuracy I wanted, unable to properly classify edge case browsers, mobile devices, and new browsers (like Chrome and Android).
So, I rolled my own.
I find that it’s very accurate – more accurate than anything else I could find. Another good site out there is UserAgentString.com, but even they misclassify some well known browsers such as iPhone, Shiretoko, and Lunascape. When I do my daily checks I find that every 200-400 new user agents requires me to tweak my code. And I’ve written some good admin tools to do this check – it only takes 5 minutes to complete. And the code tweaks, when necessary, take less than 15 minutes.
It’s great that this helps UA Profiler, but I’d really like to share this with the web community. The first step was adding a new Parse User-Agent page to UA profiler. You can paste any User-Agent string and see how my code classifies it. I also show the results from UserAgentString.com for comparison. The next steps, if there’s interest and I can find the time, would be to make this available as a web service and make the code available, too. What do people think?
- Do other people share this need for better User Agent parsing?
- Do you know of something good that’s out there that I missed?
- Do you see gaps or mistakes in UA Profiler’s parsing?
For now, I’ll keep classifying user agents as I finish the last drops of my (first) coffee in the morning.
CS193H video preview
My class at Stanford, CS193H High Performance Web Sites, was videotaped. Stanford does this so that people enrolled through the Stanford Center for Professional Development, who work fulltime, can watch the class at offhours. SCPD also makes some of the class videos available to the public. I’m currently talking with SCPD about releasing my videos, but in the meantime they’ve released the video of my first class. This lecture covers the logistics of the class (syllabus, mailing list, etc.). I’ve released all the slides from the class. You can find links to the slides in the class schedule. Anyone going through the slides should watch this intro video to get a flavor for how the class was conducted.
If you would be interested in watching the videos from this class, please add a comment below. The more interest there is, the more likely SCPD will be to make the videos available.
Update: The videos are now available! Thanks for all the positive feedback. You can watch the first three lectures for free. The entire 25 lectures have a tuition of $600. The videos are offered as XCS193H on SCPD.
Coupling asynchronous scripts
This post is based on a chapter from Even Faster Web Sites, the follow-up to High Performance Web Sites. Posts in this series include: chapters and contributing authors, Splitting the Initial Payload, Loading Scripts Without Blocking, Coupling Asynchronous Scripts, Positioning Inline Scripts, Sharding Dominant Domains, Flushing the Document Early, Using Iframes Sparingly, and Simplifying CSS Selectors.
Much of my recent work has been around loading external scripts asynchronously. When scripts are loaded the normal way (<script src="...">
) they block all other downloads in the page and any elements below the script are blocked from rendering. This can be seen in the Put Scripts at the Bottom example. Loading scripts asynchronously avoids this blocking behavior resulting in a faster loading page.
One issue with async script loading is dealing with inline scripts that use symbols defined in the external script. If the external script is loading asynchronously without thought to the inlined code, race conditions may result in undefined symbol errors. It’s necessary to ensure that the async external script and the inline script are coupled in such a way that the inlined code isn’t executed until after the async script finishes loading.
There are a few ways to couple async scripts with inline scripts.
- window’s onload – The inlined code can be tied to the window’s onload event. This is pretty simple to implement, but the inlined code won’t execute as early as it could.
- script’s onreadystatechange – The inlined code can be tied to the script’s onreadystatechange and onload events. (You need to implement both to cover all popular browsers.) This code is lengthier and more complex, but ensures that the inlined code is called as soon as the script finishes loading.
- hardcoded callback – The external script can be modified to explicitly kickoff the inlined script through a callback function. This is fine if the external script and inline script are being developed by the same team, but doesn’t provide the flexibility needed to couple 3rd party scripts with inlined code.
In this blog post I talk about two parallel (no pun intended) issues: how async scripts make the page load faster, and how async scripts and inline scripts can be coupled using a variation of John Resig’s Degrading Script Tags pattern. I illustrate these through a recent project I completed to make the UA Profiler results sortable. I did this using Stuart Langridge’s sorttable script. It took me ~5 minutes to add his script to my page and make the results table sortable. With a little more work I was able to speed up the page by more than 30% by using the techniques of async script loading and coupling async scripts.
Normal Script Tags
I initially added Stuart Langridge’s sorttable script to UA Profiler in the typical way (<script src="...">
), as seen in the Normal Script Tag implementation. The HTTP waterfall chart is shown in Figure 1.
Figure 1: Normal Script Tags HTTP waterfall chart
The table sorting worked, but I wasn’t happy with how it made the page slower. In Figure 1 we see how my version of the script (called “sorttable-async.js”) blocks the only other HTTP request in the page (“arrow-right-20×9.gif”), which makes the page load more slowly. These waterfall charts were captured using Firebug 1.3 beta. This new version of Firebug draws a vertical red line where the onload event occurs. (The vertical blue line is the domcontentloaded event.) For this Normal Script Tag version, onload fires at 487 ms.
Asynchronous Script Loading
The “sorttable-async.js” script isn’t necessary for the initial rendering of the page – sorting columns is only possible after the table has been rendered. This situation (external scripts that aren’t used for initial rendering) is a prime candidate for asynchronous script loading. The Asynchronous Script Loading implementation loads the script asynchronously using the Script DOM Element approach:
var script = document.createElement('script'); script.src = "sorttable-async.js"; script.text = "sorttable.init()"; // this is explained in the next section document.getElementsByTagName('head')[0].appendChild(script);
The HTTP waterfall chart for this Asynchronous Script Loading implementation is shown in Figure 2. Notice how using an asynchronous loading technique avoids the blocking behavior – “sorttable-async.js” and “arrow-right-20×9.gif” are loaded in parallel. This pulls in the onload time to 429 ms.
Figure 2: Asynchronous Script Loading HTTP waterfall chart
John Resig’s Degrading Script Tags Pattern
The Asynchronous Script Loading implementation makes the page load faster, but there is still one area for improvement. The default sorttable implementation bootstraps itself by attaching “sorttable.init()” to the onload handler. A performance improvement would be to call “sorttable.init()” in an inline script to bootstrap the code as soon as the external script was done loading. In this case, the “API” I’m using is just one function, but I wanted to try a pattern that would be flexible enough to support a more complex situation where the module couldn’t assume what API was going to be used.
I previously listed various ways that an inline script can be coupled with an asynchronously loaded external script: window’s onload, script’s onreadystatechange, and hardcoded callback. Instead, I used a technique derived from John Resig’s Degrading Script Tags pattern. John describes how to couple an inline script with an external script, like this:
<script src="jquery.js"> jQuery("p").addClass("pretty"); </script>
The way his implementation works is that the inlined code is only executed after the external script is done loading. There are several benefits to coupling inline and external scripts this way:
- simpler – one script tag instead of two
- clearer – the inlined code’s dependency on the external script is more obvious
- safer – if the external script fails to load, the inlined code is not executed, avoiding undefined symbol errors
It’s also a great pattern to use when the external script is loaded asynchronously. To use this technique, I had to change both the inlined code and the external script. For the inlined code, I added the third line shown above that sets the script.text
property. To complete the coupling, I added this code to the end of “sorttable-async.js”:
var scripts = document.getElementsByTagName("script"); var cntr = scripts.length; while ( cntr ) { Â Â Â var curScript = scripts[cntr-1]; Â Â Â if ( -1 != curScript.src.indexOf('sorttable-async.js') ) { Â Â Â Â Â Â Â eval( curScript.innerHTML ); Â Â Â Â Â Â Â break; Â Â Â } Â Â Â cntr--; }
This code iterates over all scripts in the page until it finds the script block that loaded itself (in this case, the script with src
containing “sorttable-async.js”). It then evals the code that was added to the script (in this case, “sorttable.init()”) and thus bootstraps itself. (A side note: although the line of code was added using the script’s text property, here it’s referenced using the innerHTML property. This is necessary to make it work across browsers.) With this optimization, the external script loads without blocking other resources, and the inlined code is executed as soon as possible.
Lazy Loading
The load time of the page can be improved even more by lazyloading this script (loading it dynamically as part of the onload handler). The code behind this Lazyload version just wraps the previous code within the onload handler:
window.onload = function() { Â Â Â var script = document.createElement('script'); Â Â Â script.src = "sorttable-async.js"; Â Â Â script.text = "sorttable.init()"; Â Â Â document.getElementsByTagName('head')[0].appendChild(script); }
This situation absolutely requires this script coupling technique. The previous bootstrapping code that called “sorttable.init()” in the onload handler won’t be called here because the onload event has already passed. The benefit of lazyloading the code is that the onload time occurs even sooner, as shown in Figure 3. The onload event, indicated by the vertical red line, occurs at ~320 ms.
Figure 3: Lazyloading HTTP waterfall chart
Conclusion
Loading scripts asynchronously and lazyloading scripts improve page load times by avoiding the blocking behavior that scripts typically cause. This is shown in the different versions of adding sorttable to UA Profiler:
- Normal Script Tags – 487 ms
- Asynchronous Script Loading – 429 ms
- Lazyloading – ~320 ms
The times above indicate when the onload event occurred. For other web apps, improving when the asynchronously loaded functionality is attached might be a higher priority. In that case, the Asynchronous Script Loading version is slightly better (~400 ms versus 417 ms). In both cases, being able to couple inline scripts with the external script is a necessity. The technique shown here is a way to do that while also improving page load times.
(sharing) OLPC XO
For Christmas, I bought a XO laptop through the One Laptop Per Child program for two of my girls to share. (The irony of getting a One Laptop Per Child XO for the two of them to share just hit me ;-) My oldest daughter has her own MacBook, so I wanted a low priced alternative that my two younger girls could call their own. And the charitable aspect of OLPC was a motivator, especially at this time of year. The way it works is you pay for two laptops; one comes to you and the other goes to a child in a developing country. Since my employer, Google, does charitable matching, my purchase resulted in two laptops being donated.
It was incredibly easy. I purchased the XO on Amazon for $399. Our XO arrived in plenty of time for Christmas. I received a receipt from OLPC for my $200 tax deduction. And I submitted the matching gift form at work. Google is a big supporter of OLPC, so that organization was already in the matching system making it even easier to complete the process.
We’ve been using it for a day, and so far the girls and I love it. They really like having their own laptop. They’re familiar with web browsers, so were able to get immediate benefit. Today we’ll start exploring the other applications. I like that the XO is built for the tough treatment kids can deliver. It was easy to get setup. And my girls immediately commented that it was much easier to use than our other computers.
The first thing I did was run it through the UA Profiler test suite to see how performant the browser is. OLPC’s browser scored 7/11, the same as IE8 and Firefox 2. Not bad. The OLPC browser is based on XULRunner, and therefore uses the the Gecko rendering engine as does Firefox. I was surprised that mine was the first OLPC test in the UA Profiler results. OLPC’s browser is missing parallel script loading, and only opens 2 connections per server.
I’m looking forward to learning more about the XO. I’m pleased with their Support Wiki. It had the exact info I needed to install the latest Flash player. I’m downloading various manuals now, and can’t wait to explore the other applications. I have to keep reminding myself: this was a gift for them. Maybe I can use it after they’re asleep.
UA Profiler improvements
UA Profiler is the tool I released 3 months ago that tracks the performance traits of various browsers. It’s a community-driven project – as more people use it, the data has more coverage and accuracy. So far, 7000 people have run 10,000 tests across 150 different browser versions (2500 unique User Agents). Over the past week (since my Stanford class ended), I’ve been adding some requested improvements.
- drilldown
-
Previously, I had one label for a browser. For example, Firefox 3.0 and 3.1 results were all lumped under “Firefox 3”. This week I added the ability to drilldown to see more detailed data. The results can be viewed in five ways:
- Top Browsers – The most popular browsers as well as major new versions on the horizon.
- Browser Families – The full list of unique browser names: Android, Avant, Camino, Chrome, etc.
- Major Versions – Grouped by first version number: Firefox 2, Firefox 3, IE 6, IE7, etc.
- Minor Versions – Grouped by first and second version numbers: Firefox 3.0, Firefox 3.1, Chrome 0.2, Chrome 0.3, etc.
- All Versions – At most I save three levels of version numbers. Here you can see Firefox 3.0.1, Firefox 3.0.2, Firefox 3.0.3, etc.
- hiding sparse data
- The result tables grew lengthy due to unusual User Agent strings with atypical version numbers. These might be the result of nightly builds or manual tweaking of the User Agent. Now, I only show browsers tested by at least two different people a total of four or more times. If you want to see all browsers, regardless of the amount of testing, check “show sparse results” at the top.
- individual tests
- Several people asked to see the individual test results, that is, each test that was run for a certain browser. There were several motivations: Was there much variation for test X? What were the exact User Agent strings that were matched to this browser? When were the tests done (because that problem was fixed on such-and-such a date)? When looking at a results table, clicking on the Browser name will open a new table that shows the results for each test under that browser.
- sort
- Once I sat down to do it, it took me ~5 minutes to make the results table sortable using Stuart Langridge’s sorttable. Now you can sort to your heart’s content. (This weekend I’ll write a post about how I made his code work when loaded asynchronously using a variation of John Resig’s Degrading Script Tags pattern.)
UA Profiler has been quite successful, gathering a consistent amount of testing each day. I especially enjoy seeing people running nightly builds against it. It’s fun to look at the individual tests and get some visibility into how a browser’s code base evolves. For example, looking at the details for Chrome 1.0, we see that Chrome 1.0.154 failed the “Parallel Scripts” test, but Chrome 1.0.155 passed. Looking at the User Agent strings we see that Chrome 1.0.154 was built using WebKit 525, whereas Chrome 1.0.155 upgraded to WebKit 528. The upgrade in WebKit version was the key to attaining this important performance trait.
I also know of at least one case of a browser regression that the development team fixed because it was flagged by UA Profiler. This is an amazing side effect of tracking these performance traits – actually helping browser teams improve the performance of their browsers, the browsers that you and I use every day. My next task is to improve the tests in UA Profiler. I’ll work on that. Your job is to keep running your favorite browser (and mobile web device!) through the UA Profiler test suite to highlight what’s being done right, and what more is needed to make our web experience fast by default.
State of Performance 2008
My Stanford class, CS193H High Performance Web Sites, ended last week. The last lecture was called “State of Performance”. This was my review of what happened in 2008 with regard to web performance, and my predictions and hopes for what we’ll see in 2009. You can see the slides (ppt, GDoc), but I wanted to capture the content here with more text. Let’s start with a look back at 2008.
2008
- Year of the Browser
- This was the year of the browser. Browser vendors have put users first, competing to make the web experience faster with each release. JavaScript got the most attention. WebKit released a new interpreter called Squirrelfish. Mozilla came out with Tracemonkey – Spidermonkey with Trace Trees added for Just-In-Time (JIT) compilation. Google released Chrome with the new V8 JavaScript engine. And new benchmarks have emerged to put these new JavaScript engines through the paces: Sunspider, V8 Benchmark, and Dromaeo.
In addition to JavaScript improvements, browser performance was boosted in terms of how web pages are loaded. IE8 Beta came out with parallel script loading, where the browser continues parsing the HTML document while downloading external scripts, rather than blocking all progress like most other browsers. WebKit, starting with version 526, has a similar feature, as does Chrome 0.5 and the most recent Firefox nightlies (Minefield 3.1). On a similar note, IE8 and Firefox 3 both increased the number of connections opened per server from 2 to 6. (Safari and Opera were already ahead with 4 connections per server.) (See my original blog posts for more information: IE8 speeds things up, Roundup on Parallel Connections, UA Profiler and Google Chrome, and Firefox 3.1: raising the bar.)
- Velocity
- Velocity 2008, the first conference focused on web performance and operations, launched June 23-24. Jesse Robbins and I served as co-chairs. This conference, organized by O’Reilly, was densely packed – both in terms of content and people (it sold out!). Speakers included John Allspaw (Flickr), Luiz Barroso (Google), Artur Bergman (Wikia), Paul Colton (Aptana), Stoyan Stefanov (Yahoo!), Mandi Walls (AOL), and representatives from the IE and Firefox teams. Velocity 2009 is slated for June 22-24 in San Jose and we’re currently accepting speaker proposals.
- Jiffy
- Improving web performance starts with measuring performance. Measurements can come from a test lab using tools like Selenium and Watir. To get measurements from geographically dispersed locations, scripted tests are possible through services like Keynote, Gomez, Webmetrics, and Pingdom. But the best data comes from measuring real user traffic. The basic idea is to measure page load times using JavaScript in the page and beacon back the results. Many web companies have rolled their own versions of this instrumentation. It isn’t that complex to build from scratch, but there are a few gotchas and it’s inefficient for everyone to reinvent the wheel. That’s where Jiffy comes in. Scott Ruthfield and folks from Whitepages.com released Jiffy at Velocity 2008. It’s Open Source and easy to use. If you don’t currently have real user load time instrumentation, take a look at Jiffy.
- JavaScript: The Good Parts
- Moving forward, the key to fast web pages is going to be the quality and performance of JavaScript. JavaScript luminary Doug Crockford helps lights the way with his book JavaScript: The Good Parts, published by O’Reilly. More is needed! We need books and guidelines for performance best practices and design patterns focused on JavaScript. But Doug’s book is a foundation on which to build.
- smush.it
- My former colleagues from the Yahoo! Exceptional Performance team, Stoyan Stefanov and Nicole Sullivan, launched smush.it. In addition to a great name and beautiful web site, smush.it packs some powerful functionality. It analyzes the images on a web page and calculates potential savings from various optimizations. Not only that, it creates the optimized versions for download. Try it now!
- Google Ajax Libraries API
- JavaScript frameworks are powerful and widely used. Dion Almaer and the folks at Google saw an opportunity to help the development community by launching the Ajax Libraries API. This service hosts popular frameworks including jQuery, Prototype, script.aculo.us, MooTools, Dojo, and YUI. Web sites using any of these frameworks can reference the copy hosted on Google’s worldwide server network and gain the benefit of faster downloads and cross-site caching. (Original blog post: Google AJAX Libraries API.)
- UA Profiler
- Okay, I’ll get a plug for my own work in here. UA Profiler looks at browser characteristics that make pages load faster, such as downloading scripts without blocking, max number of open connections, and support for “data:†URLs. The tests run automatically – all you have to do is navigate to the test page from any browser with JavaScript support. The results are available to everyone, regardless of whether you’ve run the tests. I’ve been pleased with the interest in UA Profiler. In some situations it has identified browser regressions that developers have caught and fixed.
2009
Here’s what I think and hope we’ll see in 2009 for web performance.
- Visibility into the Browser
- Packet sniffers (like HTTPWatch, Fiddler, and WireShark) and tools like YSlow allow developers to investigate many of the “old school” performance issues: compression, Expires headers, redirects, etc. In order to optimize Web 2.0 apps, developers need to see the impact of JavaScript and CSS as the page loads, and gather stats on CPU load and memory consumption. Eric Lawrence and Christian Stockwell’s slides from Velocity 2008 give a hint of what’s possible. Now we need developer tools that show this information.
- Think “Web 2.0”
- Web 2.0 pages are often developed with a Web 1.0 mentality. In Web 1.0, the amount of CSS, JavaScript, and DOM elements on your page was more tolerable because it would be cleared away with the user’s next action. That’s not the case in Web 2.0. Web 2.0 apps can persist for minutes or even hours. If there are a lot of CSS selectors that have to be parsed with each repaint -Â that pain is felt again and again. If we include the JavaScript for all possible user actions, the size of JavaScript bloats and increases memory consumption and garbage collection. Dynamically adding elements to the DOM slows down our CSS (more selector matching) and JavaScript (think getElementsByTagName). As developers, we need to develop a new way of thinking about the shape and behavior of our web apps in a way that addresses the long page persistence that comes with Web 2.0.
- Speed as a Feature
- In my second month at Google I was ecstatic to see the announcement that landing page load time was being incorporated into the quality score used by Adwords. I think we’ll see more and more that the speed of web pages will become more important to users, more important to aggregators and vendors, and subsequently more important to web publishers.
- Performance Standards
- As the industry becomes more focused on web performance, a need for industry standards is going to arise. Many companies, tools, and services measure “response time”, but it’s unclear that they’re all measuring the same thing. Benchmarks exist for the browser JavaScript engines, but benchmarks are needed for other aspects of browser performance, like CSS and DOM. And current benchmarks are fairly theoretical and extreme. In addition, test suites are needed that gather measurements under more real world conditions. Standard libraries for measuring performance are needed, a la Jiffy, as well as standard formats for saving and exchanging performance data.
- JavaScript Help
- With the emergence of Web 2.0, JavaScript is the future. The Catch-22 is that JavaScript is one of the biggest performance problems in a web page. Help is needed so JavaScript-heavy web pages can still be fast. One specific tool that’s needed is something that takes a monolithic JavaScript payload and splits into smaller modules, with the necessary logic to know what is needed when. Doloto is a project from Microsoft Research that tackles this problem, but it’s not available publicly. Razor Optimizer attacks this problem and is a good first step, but it needs to be less intrusive to incorporate this functionality.
Browsers also need to make it easier for developers to load JavaScript with less of a performance impact. I’d like to see two new attributes for the SCRIPT tag: DEFER and POSTONLOAD. DEFER isn’t really “new” – IE has had the DEFER attribute since IE 5.5. DEFER is part of the HTML 4.0 specification, and it has been added to Firefox 3.1. One problem is you can’t use DEFER with scripts that utilize document.write, and yet this is critical for mitigating the performance impact of ads. Opera has shown that it’s possible to have deferred scripts still support document.write. This is the model that all browsers should follow for implementing DEFER. The POSTONLOAD attribute would tell the browser to load this script after all other resources have finished downloading, allowing the user to see other critical content more quickly. Developers can work around these issues with more code, but we’ll see wider adoption and more fast pages if browsers can help do the heavy lifting.
- Focus on Other Platforms
- Most of my work has focused on the desktop browser. Certainly, more best practices and tools are needed for the mobile space. But to stay ahead of where the web is going we need to analyze the user experience in other settings including automobile, airplane, mass transit, and 3rd world. Otherwise, we’ll be playing catchup after those environments take off.
- Fast by Default
- I enjoy Tom Hanks’ line in A League of Their Own when Geena Davis (“Dottie”) says playing ball got too hard: “It’s supposed to be hard. If it wasn’t hard, everyone would do it. The hard… is what makes it great.” I enjoy a challenge and tackling a hard problem. But doggone it, it’s just too hard to build a high performance web site. The bar shouldn’t be this high. Apache needs to turn off ETags by default. WordPress needs to cache comments better. Browsers need to cache SSL responses when the HTTP headers say to. Squid needs to support HTTP/1.1. The world’s web developers shouldn’t have to write code that anticipates and fixes all of these issues.
Good examples of where we can go are Runtime Page Optimizer and Strangeloop appliances. RPO is an IIS module (and soon Apache) that automatically fixes web pages as they leave the server to minify and combine JavaScript and stylesheets, enable CSS spriting, inline CSS images, and load scripts asynchronously. (Original blog post: Runtime Page Optimizer.) The web appliance from Strangeloop does similar realtime fixes to improve caching and reduce payload size. Imagine combining these tools with smush.it and Doloto to automatically improve the performance of web pages. Companies like Yahoo! and Google might need more customized solutions, but for the other 99% of developers out there, it needs to be easier to make pages fast by default.
This is a long post, but I still had to leave out a lot of performance highlights from 2008 and predictions for what lies ahead. I look forward to hearing your comments.
CS193H: final exam
This past quarter I’ve been teaching CS193H: High Performance Web Sites at Stanford. Last week was the final exam and tonight I finished submitting the grades. (The average grade was 88.) This was a great experience. Stanford is an inspirational place to be. The students are very smart – one of the undergraduates in my class is already working with a VC up on Sandhill Road. As I’ve found before, I learn a lot when I teach. This was especially true given the questions from these students. I’ve never taught an entire quarter before. Teaching three classes per week while developing a new curriculum took a lot of time. I’m thankful to Google for giving me time to do this.
The material from the class is posted on the class web site. Slides from all of my lectures, including material from my next book, can be found there. There are also slides from my amazing guest lecturers:
- Joseph Smarr (Plaxo) – Performance Challenges for the Open Web
- Lindsey Simon (Google) – Front End Kung Fu (no slides; this was more of an action movie/lecture)
- Bill Scott (Netflix) – High Performance Web Pages – Real World Examples: Netflix Case Study
- Doug Crockford (Yahoo!) – Ajax Performance
- Robert Johnson (Facebook) – Fast Data at Massive Scale – lessons learned at Facebook
I’ve posted the midterm and final exams, along with the ans–wers. The slides and tests provide a thorough coverage of web performance. The average grade on the final was 94. Give it a whirl and let me know how you do.
CACM article: High Performance Web Sites
Last summer I attended the ACM Awards Banquet. (I talked about this in my blog post about how Women are Geeks (too!).) Out of that came a request for me to write an article on web performance. The article is called “High Performance Web Sites”. [gasp!] It’s a review of the rules from my first book, plus a preview of the first three rules from my next book. The article came out last week in two of the ACM’s magazines: Communications of the ACM and Queue.
Communications of the ACM (CACM) is their flagship publication. It’s been around for more than 50 years with an audience of 85,000 readers. It’s a hardcopy magazine, so the link above is a preview copy of my article. There are other versions including HTML and PDF.
Queue is ACM’s online magazine focusing on software development. The issue of Queue containing my article is about Scalable Web Services. Other articles include:
- Building Scalable Web Services by Tom Killalea, VP of Technology at Amazon.com
- Eventually Consistent by Werner Vogels, CTO of Amazon.com
- Improving Performance on the Internet by Tom Leighton co-founder of Akamai Technologies
(I didn’t realize I was going to be in with such heavy company.) I’m happy with this article – it’s short, but provides a good overview of my performance best practices and has a bit of evangelism at the close. Give it a read and recommend it to any colleagues who are entering the performance arena.
Velocity 2009: Call for Participation
Velocity 2009 is officially open! This is the conference that Jesse Robbins and I co-chair. Velocity 2009 is scheduled for June 22-24 at the Fairmont in San Jose. Checkout the new site. Most importantly, submit your speaking proposals on the Call for Participation page. We’ve provided some suggested topics. My favorites:
- How to tie web performance and operations to the bottom line
- Profiling JavaScript, CSS, and the network
- Managing web services – flaming disasters you survived and lessons learned
- The intersection between performance and design
- Ads, ads, ads – the performance killer?
Last year’s event sold out with popular sessions that included:
- members from the IE and Firefox teams talking about browser performance tradeoffs
- demos of web development tools: Firebug, Fiddler, AOL PageTest, and HTTPWatch
- case studies from top web apps including Wikipedia, Hotmail, Netflix, Live Search
- performance optimizations for Ajax and images
- open source product launches including Jiffy and EUCALYPTUS
Velocity 2009 is going to be even bigger and better. This year’s conference includes an extra day focused on workshops where experts will get into the details of their best practices for performance and operations. More time, more talks, more experts, more people, more takeaways to apply when you get back home. I can’t wait. See you there!