10k Tips for a Lighter Page Load

JP de Vries
Published in
5 min readAug 31, 2016


Oh. You were expecting 10,000 tips weren’t you? You won’t find that many tips today. At least not here. But you will find some tips for keeping the initial weight of your progressively enhanced web experience under 10,240 bytes (10kB).

Perhaps you’ve heard of this year’s 10K Apart Competition. Or maybe you are just looking for some tips on how to optimize and measure performance byte–by–byte. Either way, let’s get started.

Start with HTML

Starting with HTML–first is crucial to creating lightweight progressively enhanced experiences. It is also the center of an accessible experience. JavaScript is great, but not all users receive JavaScript. Think of JavaScript like glass. It is incredibly useful but heavy and fragile. Challenge yourself to initially work within the limitations of synchronous design patterns of HTML for a lighter and more accessible experience. Constraints are a designer’s coach. You might not be fond of them, but they foster creativity and genius. Could that WYSIWYG graphics editor be enhanced from a standard HTML form? Could that fancy asynchronous markdown editor be enhanced from a good old fashion <textarea>? Spend some time working within the constraints of HTML and rest assured, you’ll be amazed with the solutions you discover.

Zip it Up

GZIP is pretty much magic. It drastically reduces the weight of assets like HTML, CSS, and JavaScript by sending them compressed to the client. For example, a 65kB HTML document can weigh as little as 5kB once GZIP’ed. If you have to choose between minifying your CSS and JavaScript or delivering them unminified and compressing choose the later. The difference in weight between a minified compressed file and an unminified compressed file is fairly negligible. An unminifed compressed file will always weigh less than a minified uncompressed file. So zip it before you ship it.

Be Lazy About It

I’m going to quote Wikipedia. Because I’m lazy.

Lazy loading is a design pattern commonly used in computer programming to defer initialization of an object until the point at which it is needed. — Wikipedia

Sometimes we consider loading an asset only once the entire HTML document has loaded “lazy–loading”. But unless that asset is needed immediately it isn’t lazy–loaded. Say you allow users to choose from a set of different themes. Perhaps one of which is a high–contrast mode. You could lazy load the stylesheet(s) for these themes by only loading them once their associated theme has been chosen.

Lose the Font

We love web fonts but they are heavy. Not serving a web font will keep your page weight down and your Google PageSpeed score up. So don’t use them (initially).

Choose the Font

Designers like web fonts. Users like web fonts. I like web fonts. You like web fonts. We all like web fonts. So let’s add web fonts optionally and progressively. As demonstrated on markup.tips, a simple web component can be used to give users the option to opt–in to the web font of their choice. Use localStorage to remember their choice so the next time they return, be it next week or next year, the site will be delivered in accordance with their preferences. This is also an accessibility consideration as it gives users the ability to opt into fonts like OpenDyslexic.

Allow users to chose the typeface of their choice

Silence Your Sass

Sass is a CSS preprocessor. Over shadowed by the many other amazing things Sass allows you to do is the ability to use silent classes to group commonly used declarations together. Doing so will reduce the number of lines, and thus the weight, of your stylesheets. Discover more on using silent classes with Sass in this post.

Go Vanilla

With modern browsers gaining more and more market share you might not need jQuery. While the VanillaJS code you write may be less concise than jQuery syntax, freeing yourself of the weight of the jQuery library itself will keep the weight of your enhancement layer down.

Don’t Load Scripts that Won’t Work

So you’ve optimized your scripts. Sweet. But what features are required in those scripts? Are you loading scripts in browsers that won’t understand them? If you are using modern JavaScript you are probably making use of document.addEventListener and document.querySelector. In other words, you are supporting IE9 and newer. Before you load those scripts do a little feature detection.

Users may be stuck on an old browser for circumstances outside of their control. They could be using corporate machines they aren’t capable of updating or be in a country where modern operating systems and browsers are less accessible. Be considerate of these circumstances by only shipping usable bytes.

Sloppy Scripts?

Bare with me on this. You may be accustomed to writing well crafted JavaScript. Once you start measuring your scripts byte–for–byte you’ll notice that some of your well crafted coe is adding weight. In most cases this is well worth it. That class definition adds a little weight, but it also makes your codebase more extensible and legible. Using require() allows you to encapsulate and modularize your codebase but each required script is enclosed in some code that allows it to be included. Keep this in mind as you write your scripts and measure your weight incrementally. If you get too close to your bandwidth budget you may want to consider if these modern practices are worth the bytes they cost. Procedural code is sloppy but it also may weight less.

Picture This

The HTML5 <picture> tag offers art direction and bandwidth considerations. You can dictate which image should be displayed based on things like viewport size, pixel density, or even supported image formats. For example, WebP provides superior lossless and lossy compression, but not all browsers support it. You can use the <picture> tag to deliver elements that load less bytes if superior formats are supported. Additionally you can only load high resolution images for screens capable of benefiting from high resolution images.

Save Data

Google has introduced a brilliant new header that allows users, or their devices, to opt into saving data. The implementation is simple. If the client sets the save-data header to on you acknowledge that on the server–side and deliver a more efficient experience. Maybe you drop the web fonts and JavaScript enhancements. The save data header is an excellent complement to progressive enhancement because if you start with HTML first you can drop the JavaScript enhancement layer without losing base functionality. No harm no foul. If the user opts to save-data perhaps you optimize for leveraging the browser cache rather than optimizing initial page load times by more effectively leveraging the browser cache. Responsive Design isn’t just about responding to viewport sizes. Responding to user preferences like the save-data header also makes for a more accessible and usable experience.

We’ve covered quite a few tips today. It’s probably time we let you get back to work on your next progressive and light weight addition to the web.