Speeding Mobile Site Loading

After having used Lightning Touch to greatly speed up the interface for UCSF Mobile, it was time to improve load and render times.

What really set me down this path was discovering Mobitest. Their results will assign a decile for your site’s load time. Being unhealthily competitive, I of course wanted to see m.ucsf.edu in the top tier with the adorable “90th Percentile” indicator.

Mission accomplished.

I went down a load of dead ends in the process. Here’s what worked for me (and a few things that didn’t).

This list doesn’t include some things that I was already doing before I started focusing on the Mobitest results. So it does not mention minimizing JavaScript and CSS or optimizing PNGs. In short, this list is not comprehensive. I still think it’s a good list.

Use compression during transmission

This is one thing I will mention that I was doing already. The results are so dramatic that it seems impossible to leave out.

If you are using Apache, this basically means: Use mod_deflate.

Send your HTML, CSS, and JavaScript compressed.

One university has a mobile home page payload of 116 KB. Using compression, they could save over 62 KB. That would reduce their payload to around 53 KB. That’s a decrease of over 54%!

Kill redirects

The UCSF mobile site currently requires the browser to download 90 KB. Another university’s mobile site is slimmer, currently requiring an iPhone to download merely 69 KB. But while the network payload for that site is 23% smaller than UCSF’s, it redirects the browser on the initial page load. This ends up as an approximately 2 second penalty on the load time.

The result is a load time that is more than twice as long as UCSF’s.

If you are redirecting, take some measurements to be sure you aren’t paying a bigger penalty for it than you might imagine.

Load large assets sooner

UCSF Mobile has two images that are used in the CSS to provide a background. These two images total over 18 KB or about 20% of the data that is transmitted on the initial page load.

Using the Network pane in Chrome Dev Tools, I was able to determine that the retrieval of those resources was happening late enough to delay page rendering.

The browser had to start fetching the HTML document. Then it had to fetch the CSS. Then it had to apply the CSS and figure out that it needed to start downloading the images.

I took a shortcut by inserting this near the top of the HTML document:

<img style="display:none" alt="" src="/assets/img/background-decor.png">
<img style="display:none" alt="" src="/assets/img/watermark.png">

This causes the browser to start downloading the images but it will not display them. Then, after the browser has processed the CSS and needs to use the images for the background, it does not need to initiate a network connection to get the images.

Be vigilant against unused code

Modernizr is awesome. But be careful not to use more of it than you need or you will end up with a larger download. Perhaps more importantly, all of that payload needs to be parsed by the mobile device, hurting performance.

By using Modernizr’s great build tool, you can pick and choose just the parts you need.

I had done the picking and choosing some time ago. The site had changed enough that I had all sorts of cruft in my Modernizr build that I wasn’t using anymore. It turned out all I really needed was testing for localstorage and overflow-scrolling.

I suspect the tests associated with the writing of classes (that I wasn’t even using!) into the body tag was especially hurting my render time, but I’m not sure.

Regardless, reducing Modernizr to just what was needed measurably decreased the amount of time it took for an iPhone to render the UCSF Mobile home page.

Things I tried that didn’t help measurably

There were several other things I tried, many of which came from web performance sites. Many of the things I tried didn’t help much. A few of them actually hurt my page load time.

They may be good ideas in some situations, but they weren’t in mine.

So, always measure the effect of something so you know what’s actually important. Mobitest was great for that.

The big surprise for me was that using CSS background sprites instead of individual icon image assets actually hurt performance in my case.

I was also surprised that setting Keep-Alive for persistent connections didn’t help measurably. As with CSS spriting, that just might be my particular case only. Your mileage may vary.