loading...
Cover image for Improving Performance for Low-Bandwidth Users with save-data

Improving Performance for Low-Bandwidth Users with save-data

mike_hasarms profile image Mike Healy Updated on ・2 min read

Everyone likes a fast website, but some users have connections and data plans that make it especially critical. In some places bandwidth is expensive, and any bytes you don't need to serve can save your users money.

I recently learned about the 'save-data' HTTP header that clients may send to signify that they want a lower-bandwidth experience. The header alone doesn't do much, but it makes their preferences clear to you so you can make your own optimizations.

On mobile Chrome this setting is called 'Lite Mode'. Desktop users can install a browser extension to enable the header. Other browsers likely have their own way of enabling the setting.

Once you've detected this setting you might choose to style elements differently (for example dropping large background images), avoid decorative background video, or perhaps skip custom fonts that might delay rendering and add to the bandwidth costs.

The setting can be detected server-side by looking for a HTTP header (save-data=on) or client side in JS to set a flag for your CSS selectors.

//PHP example
function saveData() {
   return (isset($_SERVER["HTTP_SAVE_DATA"]) && strtolower($_SERVER["HTTP_SAVE_DATA"]) === 'on');
}

//JS example (courtesy of Nooshu)
//add save-data class name to document element for CSS selectors
if ("connection" in navigator) {
    if (navigator.connection.saveData === true) {
        document.documentElement.classList.add('save-data');
    }
}

With the detection in place you can omit non-essential elements to low-bandwidth users. For example, on my WordPress website I've skipped queuing Google custom fonts, and dropped my masthead background image.

// functions.php
if( !saveData() ) {
  wp_enqueue_style( 'fonts', 'https://fonts.googleapis.com/css?family=Open+Sans|Oswald:300,400,600');
}

/*
N.B. in WP it's good practice to prefix functions to avoid naming clashes.
I've skipped that for this example */

Here's my site on mobile Chrome with and without Lite Mode (aka sava-data).

Default version, and save-data

This was a pretty easy change to make for some quick performance gains for low-bandwidth users. The improvements could be even bigger for heavier sites, or if the header was considered during site development too.

(This post was originally published at mikehealy.com.au)

Posted on by:

mike_hasarms profile

Mike Healy

@mike_hasarms

Hey, I'm a contract web developer with a particular interest in Laravel & Vue web apps. Also working on my side project "HadCoffee".

Discussion

pic
Editor guide
 

What a great find, Mike! Thanks for sharing!
Have you run into issues with caching, yet?

 

Thank you.
I disabled server-side page caching on my site for this reason. If the markup you serve can depend on client side parameters, then it should not be cached.

The exception would be if you can control the way cache files are identified on the server and include a hash of the client side parameters that influence the output. Then users with save-data on would receive their own cached response.

 

I had thought that would be the case! Thank you for confirming.
Some WP-specific hosts have Redis or a similar PHP cache implemented so it is a consideration.

Still, VERY interesting tidbit to keep in my back pocket! Thank you for sharing!

If those hosts are using Redis to cache transients or DB queries there should be no problem. Only if rendered HTML is cached and sent to all users might it be an issue.

I had briefly considered forking or modifying the cache plugin I use to keep separate cache files depending on this setting, but didn't end up doing that. For cache plugin authors it wouldn't be too difficult though.