WEB PERFORMANCE : Beyond just minification

I have taken a lot from the online society, and its time I contribute something for others.

It was inevitable: In the era of smartphones, every organization want its product to be accessible on all devices that are used without sacrificing any important feature. With every addition of new feature comes a little more cost in terms of web resources (ie: could be fonts, js, css or image and the list goes on…) but user’s data/speed remains what it is . No doubt, there are already several great blogs related to web performance still I believe you can take away something from this. This post would be more concise rather than a story.

Apart from various performance related articles covering (minification, uglification etc) , there are few points from my learning, I would like to contribute:


I). Power of Preload and Preconnect :

It is best to preload your most vital resources such as JavaScript, CSS and font files. Don’t misunderstand it with browser preloading in which only resources declared in HTML are preloaded. Preload only those resources which are needed for current navigation only because browser will start loading these resources with highest priority and among the same type (script, style, images) of resources browser will sets priority Itself.

Example :

<link rel="preload" href="https://keycdn.com/blog/css/styles.css" as="style">
<link rel="preload" href="/exampleFile.js" as="script">

Preconnect allows the browser setup early connections before an HTTP request is actually sent to the server. This includes DNS lookups, TLS negotiations, TCP handshakes. This in turn eliminates roundtrip latency and saves time for users.

More on preload and browser fallback support could be found here.

II). Power of async and defer :

Most of you would be already aware of these words but rarely I see people using it intentionally . As per some top notch web bloggers a browser spends as much time in compilation and execution of large scripts as it does to load them. Doesn’t that sound strange !

We make our scripts async so that it loads asynchronously without being parsing blocking but as soon loading completes it starts compilation and execution of the same and parsing blocks . So its when defer comes into picture to suspend that execution till page gets fully parsed.

So using the power of these would definitely make your page render faster. Here is example of scripts using async and defer .

<script async src="//<your_cdnpath>/scripts/file1.js"></script>
<script async defer src="//<your_cdnpath>/scripts/file2.js"></script>

to see async and defer impacts , please check out here .

III). know your most/less/least important modules :

As modular/components based approach not only saves lot of development effort and re-usability of components, It also open the door to deal with web performance related issues in several ways.

Being a smart developer, you should be able to differentiate modules based on usability importance and business/seo point of views . Make a clear list of modules based on priority for each page and load their (low priority ones) related resources js/css after page on load .

If you are ready to go extra mile then analyze usability of features and based on minimum use make those modules on demand . ie: Giving an image for a map and as soon as user start interaction start the module on demand , not only benefits you on performance number but also to the users in terms of their data usages.

IV). Critical-css vs Inline css :

Before you follow the trend and jump directly for critical-css , take a pause and see which one is beneficial for you and your users . It should not be the case that user downloads same chunk of style as part of DOM and again duplicate separate css just for the sake of additional 1–2kb css left during critical-css. If difference is minimalist then its always good to keep css as inline-css over critical-css and if still needed you can separate css which is of low priority ie: lazy module’s css etc from the css which is to be inlined.

Need more explanation ? checkout on inline-css .

V). Non-render blocking css :

There would be times when you would not like to delay your css but also don’t want to make it render blocking as the part using it is not in first fold.

Simplest way would be to add style dynamically as soon as your render completes . To achieve it you can create a function and call it as last script in the body just before </html> . Though function can handle the waiting part via some listener or set-interval . Example:

<script>
/* loadCSS: loads a CSS file asynchronously.*/
function loadCSS(href, before, id, media, delay) {
"use strict";
delay = delay ? delay : 0;
var ss = window.document.createElement("link");
var ref = before || window.document.getElementsByTagName("script")[0];
var sheets = window.document.styleSheets;
ss.rel = "stylesheet";
ss.href = href;
ss.media = "only x";
ss.id = id;
function ready(cb) {
if (window.document.body) {
return cb()
}
setTimeout(function() {
ready(cb)
})
}
ready(function() {
ref.parentNode.insertBefore(ss, ref);
});
var onloadcssdefined = function(cb) {
var resolvedHref = ss.href;
var i = sheets.length;
while (i--) {
if (sheets[i].href === resolvedHref) {
return cb()
}
}
setTimeout(function() {
onloadcssdefined(cb)
})
};
function loadCB() {
if (ss.addEventListener) {
ss.removeEventListener("load", loadCB)
}
ss.media = "all"
}
if (ss.addEventListener) {
ss.addEventListener("load", loadCB)
}else{
onloadcssdefined(loadCB);
}
return ss;
}
</script>
<script> loadCSS("/styles/css/vendor.hash.css"); </script>

A short read on dynamically loading css could be found here too .

VI). How smart image loading can improve on rendering and onload time :

Every time I tried to find the reason of low performance, images were the cause most of the times. Images not only increases load time but also blocks users to see the actual page content. Being render blocking, images at times makes users to leave the page earlier .

Try to use a standard dummy image throughout the site until actual images replace those . There should be a genuine reason why any image is render blocking or would add some milliseconds/seconds to your page load time .

To overcome this problem we can go with some smarter way to load images . This should not be handled at page level instead at application level so that on every page load it is handled automatically. One example is below :

<img data-src=”/image.png” />

we can keep data-src (or data-*) for all images and replace all data-src with src with data-src’s values .

if (document.readyState.toLowerCase() === ‘complete’) {
loadAllImages();
} else {
$(window).load(loadAllImages);
}
// where loadAllImages is a function replace all data-src with src

loadAllImages can be made parametric function based on our requirement.

Note: background-images can also increase page load time so we can create a separate logic to add some class which would add background and add class to the eligible elements after onload to add background images.

if (document.readyState.toLowerCase() === ‘complete’) {
$moduleEl.find(‘[data-onloadimage]’).addClass(‘onloadimage’);
} else {
$(window).load(function(){
$moduleEl.find(‘[data-onloadimage]’).addClass(‘onloadimage’);
});
}

VII). 3rd Party plugin vs user specific resources priority :

You should set clear priority among page specific resources vs 3rd party resources (ie: tracking libraries, push notification libraries, etc) . There is very thin line between your business and user experience perspective , you should not try to break this one for other one .

There are times when you use libraries but consume very few lines out of it, so do a detailed analysis and load only the part that is needed for us .

In most of the cases, all such libraries should be initiated only after page load triggers .

VIII). Cross check - all resources are compressed and images are minified :

Last but not the least, which goes without saying you should always cross check if all the resources are compressed, minified and there is no room left for it.

Sometime calling bigger size images than the required could leave bad marks on the performance numbers .

/* without dimension, size is: ~88kb */
https://content.makaan.com/16/3567480/274/5510470.jpeg
/* with dimension, size is: ~22kb */
https://content.makaan.com/16/3567480/274/5510470.jpeg?width=360&height=270

Probably that goes unsaid, once file size is reduces drastically , it will load faster.

I’ll surely try to give more insights on coding part in followup articles .

Thank you for reading, please leave comments if something needs more clarity or email me on mohd.skb001@gmail.com .

Sleep well, read more and party harder !!