October 30, 2012 11:29 am | 1 Comment
Today I got an email asking this question about
I’ve noticed that on all browsers (where timing is supported), the timing stops once the readyState of the document = ‘complete’. Seems normal, but in many cases, I’ve seen web pages that load additional “stuff” via aysnc loading (mostly mktg tags) and the timing object doesn’t seem to reflect this additional load time. Is this by design?
It’s a good question so I wanted to post my response for others who might be wondering the same thing.
An increasing number of websites load resources after the window.onload event. In fact, 8 of the world’s top 10 websites have post-onload activity: Google, Facebook, YouTube, Yahoo, Windows Live, Twitter, Tencent, and Amazon.
It makes sense that you’d want to capture this activity as part of any performance metrics, so why isn’t it already part of
window.performance.timing? Remember we’re dealing with a W3C specification – the Navigation Timing specification to be exact. As with many specs, what seems intuitively simple is more difficult to capture in exact language. Looking at this processing model graph we see that the questioner is right – Navigation Timing stops at the window.onload event. We might think of extending the spec to have an “end of network activity” event that would include these post-onload requests.
Defining “end of network activity” is the tricky part. In the case of many sites, such as the 8 sites listed previously, the post-onload activity is a few HTTP requests. This is more straightforward. But what about sites that do a polling XHR every 5 seconds? Or sites that use Comet (hanging GET) or websockets? Their network activity never ends, so the Navigation Timing metrics would never complete.
There’s also a tension between wanting to capture this later activity but also wanting sites to send back information as quickly as possible. Many users (5-15% in my experience) quickly click through to the next page. For these users it’s important to fire the metrics beacon (AKA tag) before they leave the page. The two key questions for this issue become:
- How can post-onload activity be measured?
- When should the timing metrics be beaconed back?
It’s possible that Navigation Timing could be extended to have an “end of network activity” value. For sites that have infinite network activity the specification could have language that set this value in the absence of network activity for N (2?) seconds or after a maximum of M (10?) seconds after window.onload. I encourage people in favor of this idea to send email to firstname.lastname@example.org (with [NavigationTiming] at the start of the subject line).
With regard to when the timing metrics should be beaconed back, it’s important to send a beacon as quickly as possible to get information before the user does a quick click through. Therefore, I recommend sending the Nav Timing data in a beacon as part of window.onload. (See sample code in A Practical Guide to the Navigation Timing API.) For sites that want to measure post-onload activity, I recommend sending a second beacon with this additional information. Sending two beacons should have a minimal performance impact for the user, network, and backend server. If the delta in the number of first vs second beacons is within a tolerable range, then the website owner could choose to send only the latter beacon containing all the performance information.
October 11, 2012 8:11 pm | 10 Comments
- Using Ajax reduces network traffic to just a few JSON requests.
- Better caching means many of the web app’s resources are stored locally and don’t require any HTTP requests.
These web performance optimizations aren’t mutually exclusive – you should do them all! But I (and perhaps you) wonder which has the biggest impact. So I decided to run a test to measure these different factors. I wanted to see the benefits on real websites, so that pointed me to WebPagetest where I could easily do several tests across the Alexa Top 1000 websites. Since there’s no setting to “Ajaxify” a website, I decided instead to focus on time spent on the network. I settled on doing these four tests:
- Baseline – Run the Alexa Top 1000 through WebPagetest using IE9 and a simulated DSL connection speed (1.5 Mbps down, 384 Kbps up, 50ms RTT). Each URL is loaded three times and the median (based on page load time) is the final result. We only look at the “first view” (empty cache) page load.
- Fast Network – Same as Baseline except use a simulated FIOS connection: 20 Mbps down, 5 Mbps up, 4ms RTT.
- Primed Cache – Same as Baseline except only look at “repeat view”. This test looks at the best case scenario for the benefits of caching given the caching headers in place today. Since not everything is cacheable, some network traffic still occurs.
Which test is going to produce the fastest page load times? Stop for a minute and write down your guess. I thought about it before I started and it turned out I was wrong.
This chart shows the median and 95th percentile window.onload time for each test. The Baseline median onload time is 7.65 seconds (95th is 24.88). Each of the optimizations make the pages load significantly faster. Here’s how they compare:
- Primed Cache is the fastest test at 3.46 seconds (95th is 12.00).
- Fast Network is second fastest at 4.13 seconds (95th is 13.28).
What tools are missing?
Here are the responses gathered from the attendees:
Favorite Performance Tool:
- Chrome Dev Tools
- Speed Tracer
- Performance Analyzer from Site Confidence (pay)
- SPOF-O-Matic, 3PO for YSlow
- PageSpeed, YSlow
- dynaTrace Ajax Edition and SpeedoftheWeb
- HTTP Archive
- Critical Path Explorer – part of PageSpeed Insights
- mobile remote debugging: Weinre, jsconsole.com, Opera Dragonfly, Chrome for Android
- Apache Bench (ab)
- Show Slow
- Tilt, DOM Monster
- Mobileperf Bookmarklet
- Boomerang, Episodes
- wget, telnet
- Shunra NetworkCatcher Express
- Packet Flight
- Fiddler, Charles
- CSS Lint, JSLint
- When analyzing a website need a tool that calculates the average delta between last-modified date and today and compare that to the expiration time. The goal is to indicate to the web developer if the expiration window is commensurate with the resource change rate. This could be part of PageSpeed, YSlow, and HTTP Archive, for example.
- Automated tool that determines if a site is using a blocking snippet when an async snippet is available. For example, PageSpeed does this but only for Google Analytics.
- Tools that diagnose the root cause for rendering being delayed.
- Easier visibility into DNS TTLs, e.g., built into Chrome Dev Tools and WebPagetest.
- Backend tool that crawls file directories and optimizes images. Candidate tools: Yeoman, Wesley.
- Nav Timing in (mobile) Safari.
- Better tools for detecting and diagnosing memory leaks.
- Tools to visualize and modify Web Storage (localStorage, app cache, etc.).
- Tools to visualize and clear DNS cache.
- A version of JSLint focused on performance suggestions.
- A tool that can diff two HAR files.
- in-browser devtools letting you drill into each resource fetched or cached, listing the full set of reasons (down to the combination of http headers at play in the current and, as applicable, a prior request) for why that resource was or wasn’t loaded from the cache, when it would get evicted from cache and why: https://bugs.webkit.org/show_bug.cgi?id=83986
This was stream of consciousness from the audience. It’s not an exhaustive list. Do you have a favorite web performance tool that’s not listed? Or a performance analysis need without a tool to help? If so, add a comment below. And consider organizing WebPerfDays in your area. Aaron, Stephen, and I would be happy to help.
September 24, 2012 12:25 pm | 4 Comments
I want to re-run the real user cache experiment that Tenni Theurer and I ran back in 2007. I’m designing the experiment now and will share that design in this blog when it’s well-baked. One change is I’d like to use an external script as the cached response that is tested. Another change is I want the experiment to be a snippet that any website can embed. That allows me to crowdsource results from websites with a wider range of session behaviors, user profiles, browsers, etc.
var newscript = document.createElement("script");
newscript.async = true;
newscript.src = document.location.protocol + "//NOTstevesouders.com/testscript.js";
var s0 = document.getElementsByTagName('script');
But I wondered: Does loading an external script this way affect caching behavior?
I’ve been using this pattern for years and know that caching headers for dynamically-loaded scripts are respected in all the major desktop & mobile browsers, but what about other browsers? To answer this question I created a Browserscope user test last week. The Caching Async Scripts test page loads a script dynamically. The script has a far future expiration date so on the next page it should be read from cache. This is tested by measuring the script’s load time – normally it takes 6 seconds to load so if it’s far less than that it must have been read from cache.
I tweeted the test’s URL asking people to run the test. Thanks to everyone who ran it! The crowdsourced Browserscope results show data for over sixty browsers including Blackberry, Epiphany, and PlayStation. Happily, and surprisingly, it shows that every browser honors caching headers for scripts loaded dynamically. That’s great news in general, and with regard to re-running the cache experiment means that I can feel comfortable using this pattern to load the cached script while avoiding frontend SPOF.
September 12, 2012 8:06 am | 9 Comments
In Clearing Browser Data I mentioned Internet Explorer’s “Preserve Favorites website data” option. It first appeared in Internet Explorer 8′s Delete Browsing History dialog: