May 2010

cross-browser Greasemonkey scripts

I love customizing web apps and browser behavior. I want my web my way! So bookmarklets, Greasemonkey scripts, and browser add-ons are some of my favorite things to work on. When searching for the right implementation I approach the problem in that same order:

  • bookmarklets - If I can accomplish my goals with a bookmarklet, I stop there. This means it works cross-browser without installing a plugin.
  • Greasemonkey scripts – If I want my custom behavior to happen automatically, I step up to Greasemonkey. Besides automatically launching my script, there are some other extras that come with Greasemonkey such as cross-site XHR and menu manipulation. Checkout the Greasemonkey API for a full list of functions. But API support, and support for Greasemonkey itself, varies by browser (we’ll get to that in a minute).
  • Browser add-ons – Browser add-ons have the most power, access, and UI control. But they only work on a single browser. (At least until someone ports Jetpack to more browsers.) The implementation stack varies by browser (lowers likelihood of reusing code). Installation can be cumbersome for users, and hosting is harder for developers. Updates are more automated, which is nice.

Greasemonkey covers a nice middle ground. Easy to develop and more features. Up until recently, though, I thought of Greasemonkey scripts as being only for Firefox. That’s no longer the case.

Greasemonkey was created by Aaron Boodman for Firefox back in 2005. He works on Chrome now, so it was awesome when Aaron announced that Greasemonkey scripts are supported in Chrome. When I started researching it this week, I was surprised to find out that Opera supports Greasemonkey scripts (aka, “user scripts” and “user JavaScript”) starting back with Opera 8. So Firefox supports Greasemonkey scripts through the original Greasemonkey add-on. Chrome and Opera have built-in support for Greasemonkey scripts.

Safari and Internet Explorer don’t have built-in support for Greasemonkey scripts. And they also don’t have (what I would call) solid add-on support for Greasemonkey scripts. I read that in Safari you can use SIMBL and Greasekit to make Greasemonkey scripts work. In IE, Trixie is suggested. In this post I’m going to focus on Firefox, Chrome, and Opera, but I’d appreciate comments about people’s experiences in Safari and IE with these or other plugins that give Greasemonkey support.

my example: TwitterHistory.user.js

I mostly read Twitter in Firefox on my laptop. One feature I’ve wanted forever is an indicator of the last tweet I’ve read, so I can quickly see how much new stuff there is. Ditto for mentions. So I wrote a Greasemonkey script that implemented these features: twitterhistory.user.js. Now my Twitter looks like this:

Tweets that I’ve already read are grayed out, and there’s a thick gray bar dividing the read from the unread. The key features needed are:

  • remember the newest-viewed-tweet - All tweets have an ascending number in their id, so all I need to do is save the id of the first tweet in the list.
  • gray out the tweets – The next time the user comes to the page, since I know the number of the newest-viewed-tweet I can iterate over all the visible tweets and gray out the ones with a lower number.
  • add a handler to various navigation links – A tricky part is figuring out when to remember the newest-viewed-tweet, and when to gray out the visible tweets. Doing this at page transition is obvious – gray out the already read tweets when the page loads, and save the newest-viewed-tweet when the page unloads. But Twitter is very Ajaxified. For example, clicking the “more” link at the bottom adds more tweets that might need to be grayed out. And clicking the “Home” and “@souders” navigation links causes the list of tweets to change, which means saving the newest tweet number and graying out the new list needs to happen. To achieve this I add an onclick handler to those links.

Getting the Code to Work

Let’s look at how these features get implemented as a Greasemonkey script that works across Firefox, Chrome, and Opera.

Firefox

The Greasemonkey add-on for Firefox provides an API that includes GM_setValue and GM_getValue. These work great to save and retrieve the ID of the newest-viewed-tweet. Graying out tweets was a simple matter of iterating over the items in a list and comparing each id to the newest-viewed-tweet value. Adding the handlers was tricky. In order for these callbacks to persist from the Greasemonkey script to the main page’s event loop, I had to use the unsafeWindow variable from Greasemonkey. Without this, the handlers don’t work, as demonstrated in my Greasemonkey Test Page. This took less than an hour to code up.

Chrome

I had never built a Greasemonkey script for Chrome before, so I had some learning to do. First off, there’s no Greasemonkey API in Chrome. Therefore, unsafeWindow doesn’t exist, but it turns out using window works just fine (as shown in the Greasemonkey Test Page). So I defined a proxy variable that refers to unsafeWindow if it exists, otherwise window. One stumble I had here was trying to detect programmatically if GM_setValue and GM_getValue are defined. It turns out they are defined in Chrome! But they don’t do anything:

function() {
    console.log("%s is not supported.", api);
}

Since GM_setValue and GM_getValue don’t work, I fallback on localStorage (see Greasemonkey API emulation for Chrome). If localStorage doesn’t exist, I use cookies (a la PPK). Two browsers down. One to go.

Opera

The main trick with Opera was figuring out how to install the scripts. I talk about that more under Installation. Once I figured that out, there was only one issue to resolve and it had nothing to do with Greasemonkey. In the case of Opera, I need to use onunload instead of onbeforeunload.

Installation

Installing Greasemonkey scripts is easiest in Chrome. You just enter the script’s URL (for example, http://stevesouders.com/twitterhistory.user.js) and it works the next time you visit the page. The UI for managing scripts is available under wrench | Extensions or chrome://extensions/.

Firefox is second easiest. You first install the Greasemonkey add-on, then just navigate to the script’s URL. Managing scripts is done via Tools | Greasemonkey | Manage User Scripts.

Opera was slightly harder to figure out. You go to Opera menu | Settings | Preferences | Advanced | Content | JavaScript options and enter the directory where you want the scripts to be saved. Then you manually download the scripts and save them there. It’s straightforward, but kinda clunky and buried. But it works!

Development

I learned some time saving lessons while developing my Greasemonkey script across these browsers.

Create a landing page for your script - The URL of Greasemonkey scripts aren’t kept in location history for Firefox and Chrome, so you’re constantly typing or pasting it. It’s much easier to have a landing page that’s always open where you just click a link to re-install the script, for example my TwitterHistory landing page. This works best if your script isn’t cacheable…

Make your Greasemonkey script UNcacheable – As I make changes to the script I want to re-install it as easily as possible. Having to clear my cache each time is a pain. I can skip that step by adding a “Cache-Control: no-cache, must-revalidate” response header. Now when I click on the link in my landing page to re-install my Greasemonkey script, I get all the updates in Firefox. For Chrome, I still need one more step…

Uninstall in Chrome – Even with a landing page and a Greasemonkey script that’s not cacheable, re-installing doesn’t pick up the changes in Chrome. First you have to go to chrome://extensions/ or Tools | Extensions and click the Uninstall link for your script. So I have two tabs open all the time in Chrome – my landing page and chrome://extensions/. After I save my script changes on my server, I uninstall the script, and then re-install it from my landing page.

JavaScript errors show up in Chrome, but not Firebug – I’m a big Firebug fan, but was disappointed to see that errors in my Greasemonkey script didn’t show up in Firebug’s Console. You do see JavaScript errors in Chrome’s console (accessed via page | Developer | JavaScript console).

Now you can tryout my TwitterHistory Greasemonkey script in Firefox, Chrome, and Opera. Visit Greasespot to read more about Greasemonkey. Add comments below for other tips that you’ve found to make Greasemonkey scripts work across browsers.

Uncategorized

Comments (3)

Permalink

AutoHead – my first Browserscope user test

In the comments from my last blog post (appendChild vs insertBefore) someone asked which browsers do and don’t automatically create a HEAD element. This is important when you’re deciding how to dynamically add scripts to your web page. I used this question as the motivation for creating my first Browserscope user test. Here’s the story behind this new feature in Browserscope and the answer to the automatically create HEAD question. (You can run the AutoHead test to skip ahead and see the results.)

Level, Meta-level, Meta-meta-level

Level1: When Chrome was launched in 2008 I started a project called UA Profiler to analyze the performance characteristics of browsers. The key concept was to crowdsource gathering the data – publish the test framework and encourage the web community to run the tests on their browser of choice. There are numerous benefits to this approach:

  • a wider variety of browsers are tested (more than I could possibly install in a test lab)
  • results for new browsers happen immediately (often before the browser is officially released)
  • tests are performed under real world conditions

Level 2: I teamed up with Lindsey Simon to take UA Profiler to the next level. The result was the launch of Browserscope. In addition to making this a functioning open source project, the framework was opened up to include multiple test categories. In addition to performance (renamed “Network“), other test categories were added: Security, Acid3, Selectors API, and Rich Text.

Level 3: A few weeks ago Lindsey took Browserscope to the next level with the addition of the User Tests feature. Now, anyone can add a test to Browserscope. In this early alpha version of the feature, users create one or more test pages on their own server, register the test with Browserscope, and embed a JavaScript snippet at the end of their test to send the results back to Browserscope for storing. The benefit for the test creator is that Browserscope stores all the data, parses the User-Agent strings for proper categorization, and provides a widget for viewing the results.

Even though Lindsey is careful to call this an alpha, it went very smoothly for me. Once I had my test page, it took less than 15 minutes to integrate with Browserscope and start gathering results. So let’s take a look at my test…

the test – AutoHead

In my appendChild vs insertBefore blog post I talk about why this code generates bugs:

document.getElementsByTagName['head'][0].appendChild(...)

The context was using this pattern in 3rd party code snippets – where you don’t have any control of the main page. It turns out that some web pages out in the wild wild web don’t use the HEAD tag. Luckily, most browsers automatically create a HEAD element if one isn’t specified in the page. Unfortunately, not all browsers do this.

In the comments on that blog post Andy asked, “What browsers are we talking about here?”

How can I possibly attempt to answer that question? It would require running a test on many different versions of many different browsers, including mobile devices. I’m not equipped with a setup to do that.

Then the light bulb lit up. light bulb I can do this with a Browserscope User Test!

Creating the test was easy. My HTML page doesn’t have a HEAD tag. I put a script at the bottom that checks if the page contains a head element:

bHead = document.getElementsByTagName('head').length;

I have to store the result in a specific variable that Browserscope looks for:

var _bTestResults = {
'autohead': bHead
};

This data structure is slurped up by Browserscope via this snippet (as shown on the User Tests Howto page):

(function() {
var _bTestKey = '<YOUR-TEST-ID-GOES-HERE>';
var _bScript = document.createElement('script');
_bScript.src = 'http://www.browserscope.org/user/beacon/'
               + _bTestKey;
_bScript.setAttribute('async', 'true');
var scripts = document.getElementsByTagName('script');
var lastScript = scripts[scripts.length - 1];
lastScript.parentNode.insertBefore(_bScript, lastScript);
})();

Voila! You’re done. Well, almost done. You still have to promote your test.

Promoting your test

With this small amount of work I’m now ready to ask the web community to help me gather results. For me personally, I accomplish this by writing this blog post asking for help:

Help me out by running the AutoHead test. Thanks!

I’ve embedded the Browserscope results snippet in the iframe below, so you can see results as they come in. So far iPhone and Safari 3.2 are the only browsers that don’t automatically create the HEAD element.

If you want to avoid bugs when dynamically adding scripts, you might want to use one of the more solid patterns mentioned in my appendChild vs insertBefore blog post. If you want to gather data on some browser test that interests you, read the Browserscope User Test Howto and go for it. If you have problems, contact the Browserscope mailing list. If you have success, contact me and I’ll tweet your test to drive more traffic to it. This is still in alpha, but I’m very excited about the possibilities. I can’t wait to see the kinds of tests you come up with.

Update: After just one day, thanks to all of you who ran the test, I’ve collected 400 measurements on 20 different browsers and 60 unique versions. The results show that the following browsers do NOT automatically create a HEAD element: Android 1.6, Chrome 5.0.307 (strange), iPhone 3.1.3, Nokia 90, Opera 8.50, Opera 9.27, and Safari 3.2.1. This adds up to over 1% of your users, so it’s important to keep this in mind when adding scripts dynamically.

I also had some comments I wanted to pass on about my Browserscope user test. In hindsight, I wish I had chosen a better “test_key” name for the _bTestResults object. I didn’t realize this would appear as the column header in my results table. Rather than “autohead” I would have done “Automatically Creates HEAD”. Also, rather than return 0 or 1, I wish I had returned “no” and “yes”. Finally, I wish there was a way to embed the results table widget besides using an iframe. I’ll file bugs requesting better documentation for these items.

Tools
Web Development
browsers

Comments (15)

Permalink

appendChild vs insertBefore

I’ve looked at a bunch of third party JavaScript snippets as part of my P3PC series. As I analyzed each of these snippets, I looked to see if scripts were being loaded dynamically. After all, this is a key ingredient for making third party content fast. It turns out nobody does dynamic loading the same way. I’d like to walk through some of the variations I found. It’s a story that touches on some of the most elegant and awful code out there, and is a commentary on the complexities of dealing with the DOM.

In early 2008 I started gathering techniques for loading scripts without blocking. I called the most popular technique the Script DOM Element approach. It’s pretty straightforward:

var domscript = document.createElement('script');
domscript.src = 'main.js';
document.getElementsByTagName('head')[0].appendChild(domscript);
Souders, May 2008

I worked with the Google Analytics team on their async snippet. The first version that came out in December 2009 also used appendChild, but instead of trying to find the HEAD element, they used a different technique for finding the parent. It turns out that not all web pages have a HEAD tag, and not all browsers will create one when it’s missing.

var ga = document.createElement('script');
ga.src = ('https:' == document.location.protocol ?
    'https://ssl' : 'http://www') +
    '.google-analytics.com/ga.js';
ga.setAttribute('async', 'true');
document.documentElement.firstChild.appendChild(ga);
Google Analytics, Dec 2009

Google Analytics is used on an incredibly diverse set of web pages, so there was lots of feedback that identified issues with using documentElement.firstChild. In February 2010 they updated the snippet with this pattern:

var ga = document.createElement('script');
ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ?
    'https://ssl' : 'http://www') +
    '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(ga, s);
Google Analytics, Feb 2010

I think this is elegant. If we’re dynamically loading scripts, we’re doing that with JavaScript, so there must be at least one SCRIPT element in the page. The Google Analytics async snippet has just come out of beta, so this pattern must be pretty rock solid.

I wanted to see how other folks were loading dynamic scripts, so I took a look at YUI Loader. It has an insertBefore variable that is used for stylesheets, so for scripts it does appendChild to the HEAD element:

if (q.insertBefore) {
  var s = _get(q.insertBefore, id);
  if (s) {
    s.parentNode.insertBefore(n, s);
  }
} else {
  h.appendChild(n);
}
YUI Loader 2.6.0, 2008

jQuery supports dynamic resource loading. Their code is very clean and elegant, and informative, too. In two pithy comments are pointers to bugs #2709 and #4378 which explain the issues with IE6 and appendChild.

head = document.getElementsByTagName ("head")[0] ||
    document.documentElement;
// Use insertBefore instead of appendChild to circumvent an IE6 bug.
// This arises when a base node is used (#2709 and #4378).
head.insertBefore(script, head.firstChild);
jQuery

All of these implementations come from leading development teams, but what’s happening in other parts of the Web? Here’s a code snippet I came across while doing my P3PC Collective Media blog post:

var f=document.getElementsByTagName("script");
var b=f[f.length-1];
if(b==null){ return; }
var i=document.createElement("script");
i.language="javascript";
i.setAttribute("type","text/javascript");
var j="";
j+="document.write('');";
var g=document.createTextNode(j);
b.parentNode.insertBefore(i,b);
appendChild(i,j);

function appendChild(a,b){
  if(null==a.canHaveChildren||a.canHaveChildren){
    a.appendChild(document.createTextNode(b));
  }
  else{ a.text=b;}
}
Collective Media, Apr 2010

Collective Media starts out in a similar way by creating a SCRIPT element. Similar to Google Analytics, it gets a list of SCRIPT elements already in the page, and chooses the last one in the list. Then insertBefore is used to insert the new dynamic SCRIPT element into the document.

Normally, this is when the script would start downloading (asynchronously), but in this case the src hasn’t been set. Instead, the script’s URL has been put inside a string of JavaScript code that does a document.write of a SCRIPT HTML tag. (If you weren’t nervous before, you should be now.) (And there’s more.) Collective Media creates a global function called, of all things, appendChild. The dynamic SCRIPT element and string of document.write code are passed to this custom version of appendChild, which injects the string of code into the SCRIPT element, causing it to be executed. The end result, after all this work, is an external script that gets downloaded in a way that blocks the page. It’s not even asynchronous!

I’d love to see Collective Media clean up their code. They’re so close to making it asynchronous and improving the page load time of anyone who includes their ads. But really, doesn’t this entire blog post seem surreal? To be discussing this level of detail and optimization for something as simple as adding a script element dynamically is a testimony to the complexity and idiosyncrasies of the DOM.

In threads and discussions about adding simpler behavior to the browser, a common response I hear from browser developers is, “But site developers can do that now. We don’t have to add a new way of doing it.” Here we can see what happens without that simpler behavior. Hundreds, maybe even thousands of person hours are spent reinventing the wheel for some common task. And some dev teams end up down a bad path. That’s why I’ve proposed some clarifications to the ASYNC and DEFER attributes for scripts, and a new POSTONLOAD attribute.

I’m hopeful that HTML5 will include some simplifications for working with the DOM, especially when it comes to improving performance. Until then, if you’re loading scripts dynamically, I recommend using the latest Google Analytics pattern or the jQuery pattern. They’re the most bulletproof. And with the kinds of third party content I’ve seen out there, we need all the bulletproofing we can get.

JavaScript
P3PC
Performance
Web Development

Comments (35)

Permalink

WPO – Web Performance Optimization

Everybody loves web performance

When I started evangelizing high performance web sites back in 2004, I felt like a lone voice in the woods. Fast forward six years to Fred Wilson speaking at the Future of Web Apps. Fred is a (the) top tech VC from NYC with investments in companies such as Twitter, del.icio.us, Etsy, and FeedBurner. He spoke about the 10 Golden Principles of Successful Web Apps. Guess what was #1 on his list?

First and foremost, we believe that speed is more than a feature. Speed is the most important feature. If your application is slow, people won’t use it. [...]

We think that the application has to be fast, and if it’s not, you can see what happens. We have every single one of our portfolio company services on Pingdom, and we take a look at that every week. When we see some of our portfolio company’s applications getting bogged down, we also note that they don’t grow as quickly. There is real empirical evidence that substantiates the fact that speed is more than a feature. It’s a requirement.

What started as a list of performance tips coded up in a browser plug-in has evolved to the point where a “leading voice of the venture capital finance community in the nation’s largest city” is citing speed as the #1 principle for successful web apps.

Impact of performance on the bottom line

This is confirmation that what we set as the theme for Velocity 2009 – “the impact of performance on the bottom line” – was timely and impactful. I suggested that theme because after years of evangelizing web performance to the tech community I realized we needed to reach other parts of the organization (managements, sales, marketing, etc.) to get support for the work needed to make web sites fast. Here are some of the now well known performance success stories that came from Velocity 2009 and afterward.

The major search engines measured how much web site slowdowns hurt their business metrics:

On the faster side, companies from a variety of vertical markets had praise for the benefits gained from improving performance:

Google, in their ongoing effort to make the Web faster, blogged last month that “we’ve decided to take site speed into account in our search rankings.” This is yet another way in which improving web performance will have a positive impact on the bottom line.

Web Performance Optimization – an emerging industry

This convergence of awareness, even urgency, on the business side and growing expertise in the tech community around web performance marks the beginning of a new industry that I’m calling “WPO” – Web Performance Optimization. WPO is similar to SEO in that optimizing web performance drives more traffic to your web site. But WPO doesn’t stop there. As evidenced by the success stories mentioned earlier, WPO also improves the user experience, increases revenue, and reduces operating costs.

Having just announced this new industry, let me be the first to give my predictions on what we’ll see in the near future. Here’s my top ten list done in Letterman fashion:

  1. Fast by default - To make it easier for developers, we’ll see performance best practices get built in to CMSs, templating languages (PHP, Python, etc.), clouds (AWS, Google App Engine), JavaScript libraries, and most importantly in major conduits of the Web – browsers, servers, and proxies. A lot of this is already happening, such as jQuery’s focus on performance and performance optimizations in Rails.
  2. Visibility into the browser – In order to make web pages faster, developers need the ability to find which parts are slow. This requires visibility into the time it takes for JavaScript execution, applying CSS, repainting, DOM manipulation, and more. We’re seeing early forays into this area with tools like Speed Tracer and dynaTrace Ajax Edition.
  3. Consolidation – Projects around web performance tools, metrics, and services have been disjoint efforts. That’s going to change. We’ll see tools that combine JavaScript debugging, JavaScript profiling, DOM inspection, network utilization, and more – all in one tool. Performance metrics will be aggregated in one dashboard, rather than having to visit multiple separate services. Consolidation will also happen at the company level, where smaller performance-related companies are acquired by larger consulting and services companies.
  4. TCP, HTTP – The network on which the Web works needs to be optimized. SPDY is one proposal. I also think we need to try to get more support for pipelining. Any improvements made to the underlying network will trickle down to every site and user on the Web.
  5. Standards – We’re going to see standards established in the areas of measuring performance, benchmarks, and testing. The Web Timing Spec is one example that exists today.
  6. Industry Organizations – Within the WPO industry we’ll see the growth of professional organizations, training, certification, standards bodies, and cooperatives. An example of a cooperative that came through my inbox today was a proposal for web publishers to share information about slow ads.
  7. Data – Monitoring performance and finding new performance opportunities requires analyzing data. I predict we’ll see public repositories of performance-related data made available. My favorite example that I’d love to see is an Internet Performance Archive, similar to the existing Internet Archive except that the IPA’s wayback machine would show the performance characteristics of a web site over time.
  8. green – Finally we’ll see studies conducted that quantify how improving web performance reduces power consumption and ultimately shrinks the Web’s carbon footprint.
  9. mobile – Mobile performance is at square one. We need to gather metrics, find the major performance pain points and their root causes, discover solutions, create tools, evangelize the newly discovered best practices, and collect new success stories.
  10. speed as a differentiator – Going forward, many of the decisions made around the Web will be based on performance. Customer device purchases, vendor selection, web site reviews, and user loyalty will all include performance as a major consideration.

There’s a lot of work to be done. It’s all going to be interesting and will greatly improve the Web that we use everyday. If you have the interest and time, contact me. There are tons of open source projects that need to be started. I look forward to working with you on making a faster web.


[This blog post is based on my presentation from Web 2.0 Expo. The slides from that talk are available as Powerpoint and on Slideshare.]

Performance
Velocity

Comments (13)

Permalink

HAR to Page Speed

Here’s the story behind this nifty tool I cranked out this weekend: HAR to Page Speed

HTTP Archive Specification

About a year ago I was on the weekly Firebug Working Group call when Jan (“Honza”) Odvarko said he was going to work on an export feature for Net Panel. I love HttpWatch and had used its export feature many times, but always wished there was an industry standard for saving HTTP waterfall chart information. In the hope of achieving this goal, I introduced Honza and Simon Perkins (creator of HttpWatch) and suggested that if they developed an open format it would likely evolve into an industry standard.

A few months later they published the HTTP Archive specification and had integrated it into their products. My contribution? In addition to planting the idea with Honza and Simon, I chose the three character file extension: .HAR. Support for HAR is growing. In addition to being part of Firebug (via Honza’s NetExport add-on) and HttpWatch, it’s also in ShowSlow, DebugBar, Http Archive Rule Runner, and a few other tools and sites out there. (I hear it’s coming to Fiddler soon.)

The importance of an industry standard HTTP archive format is huge. Adoption of HAR allows companies and data gathering institutions (such as the Internet Archive) to record the web page experience and pull it up later for further review. It provides a way to exchange information across tools. And it provides an open standard for sharing web loading information between individuals – developer to developer as well as customer to customer support.

Page Speed SDK

In their last few releases the Page Speed team has mentioned porting their performance analysis logic from JavaScript to C++. The resulting library is called “native library” – not too jazzy. But last week they released the Page Speed SDK. The documentation is slim, but I noticed a commandline tool called har_to_pagespeed.

Hmmm, that sounds interesting.

I downloaded the SDK. It built fine on my Dreamhost shared server. Then I wrapped it with a file upload PHP page and created HAR to Page Speed.

You start by uploading a HAR file. If you don’t have any or simply want a quick test drive, you can use one of the examples. But it’s easy to create your own HAR files using Firebug and NetExport. The latter adds the “Export” item to Firebug’s Net Panel.

Now comes the fun part. After uploading a HAR file you get the output from Page Speed. (Note that this is a subset of rules. Some rules still need to be ported.)

I also threw in a rendering of the waterfall chart based on Honza’s HarViewer:

Compellingness

My HAR to Page Speed page is handy. If you’re generating HAR files in something other than Firefox, you now have a way to get a Page Speed analysis. If you’ve got an archive of HAR files, you can analyze them with Page Speed at any time in the future.

But the big excitement I get from this page is to see these pieces coming together, especially in the area of performance analysis. Another industry initiative I’ve been advocating is a common performance analysis standard. Right now we have multiple performance analysis tools: Page Speed, YSlow, AOL Pagetest, MSFast, VRTA, and neXpert to name a few. There’s some commonality across these tools, but the differences are what’s noticeable. Web developers really need to run multiple tools if they want their web site to be evaluated against the most important performance best practices.

With the adoption of HAR and Page Speed SDK, we’re moving to having a record of the page load experience that can be saved and shared, and performance analysis that is consistent regardless of what browser and development environment you work in. We’re not quite there. We need more tools to adopt HAR import/export. And we need more rules to be added to the Page Speed SDK. But I can see the handwriting on the wall – and it’s spelling F-A-S-T.

I’ll be talking about these and other movements in the performance industry this Wednesday at Web 2.0 Expo SF.

Uncategorized

Comments (11)

Permalink