Radio link and Nav Timing

April 2, 2012 9:33 pm | 12 Comments

In Making a mobile connection I describe how after just a few seconds of inactivity your mobile phone demotes the radio link to your carrier network. It typically takes 1-2 seconds to re-establish the radio link to full bandwidth capacity. This is a huge delay!

A few days ago I was discussing desktop vs. mobile page load times with some web performance wonks. These times were gathered from real users via the W3C Nav Timing API. We started chatting about why the mobile times were worse – slower connection speeds, less cache space, etc. – and it hit me that taking 2 seconds to re-establish the radio link might account for much of what makes mobile sites slower, especially in RUM (Real User Monitoring) vs. synthetic testing. And I wondered:

Does Nav Timing include the time to establish a radio link?
If so, where is it accounted for?

After some initial testing it looks like the answers are:

Yes.
It depends.

I started by creating a Nav Timing test page that shows the values from Nav Timing. If you load the page you’ll see something like this. (Please look at page source to see how I calculate these conceptual time values.)

total time = 239 ms
dns = 119 ms
connect = 16 ms
ttfb = 61 ms
HTML = 0 ms
frontend = 42 ms

NOTE: Nav timing is available in Android 4. I’m not aware of any other mobile platform that has it, so you’ll need an Android 4 device to run these tests. You should close all/most currently running apps on your mobile device as they might be keeping the radio link alive in the background. On Android 4 this is done under Settings | Apps | Running. I had to stop Google Services.

You can determine if the radio link promotion delay occurs based on whether any of the times are greater than 2 seconds. Here’s a key:

no 2 second times
If all of the times are less than 2 seconds then the radio link was already active. You can create this result by loading the page multiple times in quick succession. All the times should be pretty fast because you have a radio link, the DNS resolution is cached, and you have a persistent connection to the web server.
dns > 2 seconds
If you wait 10-20 seconds (and closed all background apps) the radio link gets demoted. At this point clicking on one of the buttons to open the test page on another domain will force a DNS lookup. Normally the DNS lookup should take a few hundred milliseconds, but if the radio link needs to be promoted the DNS time jumps to 2000+ milliseconds. This page is hosted on three different domains. If you use all three pages thus caching all three DNS resolutions, the only way I know of to clear the DNS cache is to power cycle the phone.
connect > 2 seconds
If you allow the radio link to be demoted by waiting 10-20 seconds and reload the page (or click the button for the same page) you might see the connect time is greater than 2 seconds. This happens when the DNS is cached but there’s no persistent connection to the server. This is harder to reproduce – it depends on the browser’s policy for closing persistent connections.
ttfb > 2 seconds
If the radio link is demoted, the DNS is cached, and there’s a persistent connection to the server you’ll see the time-to-first-byte (ttfb) is greater than 2 seconds. This is what happens most frequently when you load the same page multiple times with a 10-20 second gap in-between.

It’s important that developers focusing on performance be aware of the impact of radio link promotion on nav timing for mobile traffic so you don’t waste time solving the wrong problem: If you’re gathering RUM data via nav timing and see slow DNS times, you might think about investing in your DNS infrastructure – even though those slow DNS times might be caused by radio link promotion. Similarly, if you see long connection times it might not make sense to investigate how your servers manage persistent connections. And slow time-to-first-byte values may or may not indicate a backend app layer performance problem.

My website doesn’t generate enough mobile traffic to verify this theory, but I believe that websites with enough mobile nav timing data will see bimodal distributions of their timing data for dns, connection, and ttfb where the modes are ~2 seconds apart. If anyone has enough data (you know who you are) please take a look and comment below. It might be possible to develop heuristics that help us determine when radio link delays are having an impact. I’d love to get some stats on the percentage of page views that incur this delay.

12 Responses to Radio link and Nav Timing

  1. I have access to sites with millions of mobile visitors, but I only have Google Analytics on them. And unfortunately there’s no speed measurement for any of them…

  2. Nice article Steve.

    Windows Mobile also supports Navigation Timing. I think they were also the first one to support it.

  3. Very nice! Once all mobile browsers support Nav Timing, we can actually deduct more interesting correlations for mobile users.

    On that note: do you have any idea if/when iOS will become available? I can’t find anything about it, nor does http://caniuse.com/nav-timing know.

  4. Got a question about the way you calculate times, the frontend time should be between domLoading and loadEventStart since domLoading can and usually happens before responseEnd. On chromium it’s known that the difference between responseEnd and domLoading can be negative. Or is there a particular reason you did it this way?

    Navigation timing started as a Microsoft thing indeed.

    Nice to know about this 2 second threshold.

  5. @Andre: GA does provide mobile speed measurements. I see them for “Android Browser”. It’s just that the sample size is too small. Look under Content -> Site Speed -> Overview and there’s a list of browsers at the bottom.

    @Wim: I don’t know when mobile Safari will support Nav Timing. The code is there – they just haven’t turned it on.

    @theodoreb: You’re probably right that domLoading would be the better “start” time for the concept of “frontend”. I can imagine that if a server did document flushing the responseEnd could be later than when the DOM started loading.

  6. wow we only get a handful of android probes, counting 261 a day.

    Of them,

    1 has connect duration of 2 seconds+
    1 has connect started of 2 seconds+
    None have high dns time

    A whole bunch are missing timings

    hoping more mobile browsers start reporting back this data.

  7. Firefox for Android supports nav timings. If I can snag a copy of Chrome beta for Android, I’ll try that too. It’s the only mobile browser besides ICS that I’ve found that supports it for my testing.

  8. @Donald: I forgot that we recently added a test to Browserscope to check for Nav Timing. So far I see positive results for Android 4, Chrome Mobile, Fennec 12 (Firefox mobile), and IE Mobile 9. There are a lot of gaps in the overall mobile results so please point your mobile device to the Browserscope Network tests and give it a whirl.

  9. Can these we used with an iframe?

  10. I think the two second delay is really only applicable to UMTS and maybe HSPA (and also depends on carrier and implementation).
    Wifi, LTE, and even GPRS have a different radio state machine with much smaller promotion delays. Beware mixing results using different radios, because that will definitely skew the average.

  11. hi, i tested navigation timing api on my device(android ics),i found that the “domainlookupstart” and “domainlookupend” are the same always(connectstart is same with connectend too). maybe it was retrieved from cache or local resources. but i tried it so many times, the same result. so confuse now.

  12. rambo: I believe those values will always be the same unless the DNS resolution is NOT cached. Since there’s no way to clear your DNS cache on the phone other than power cycle (AFAIK) you’ll need a very precisely executed test to determine if this is behaving correctly. If you want, you can post your test procedure as well as other standard info (device & os info, URLs, etc). The main point is being absolutely certain the DNS resolution is not cached.