Photo by Chris Liverani on Unsplash There are plenty articles around, on how to setup a robust infrastructure, and even more articles on how to make it resilient and faster. But other than optimising the infrastructure & web-services, the individual webpages that are served to user must also be optimised to gain attention of your consumers. […]
There are plenty articles around, on how to setup a robust infrastructure, and even more articles on how to make it resilient and faster. But other than optimising the infrastructure & web-services, the individual webpages that are served to user must also be optimised to gain attention of your consumers. This heralds the need for a smooth “Content Delivery” & efficient “On-Page SEO”.
Following the premise, similar common optimisations were in place at my workplace at Makaan.com, but I found I could shave down a few extra seconds off the web-page & deliver more content (to Search-Engine Crawlers and Users).
Following is a summary of actions, optimisations and experiments that were performed to this effect.
A build automation tool like grunt, gulp or webpack is often used to create minified-uglified-hashed static resources, but the HTML document (or HTML template) slip in between.
Since the HTML document is an accumulation of all HTML, inline-CSS (style tags) and inline-JS (script tags) resources it may be tricky, but a gluttonous presence is common amongst all, The ‘white-space’.
The white-spaces from <script> & <style>tags can be eliminated by writing as less as possible in these tags & moving other content to an external file, which later can be minimised & uglified by utilising already available tasks under major build automation tools like grunt-usemin for grunt.
For the HTML templates or static HTML files, whitespace elimination between HTML-tags should be done either via regex-replacement or innate template optimisation.
In our case, we had many inline<script> tags containing relevant information in JSON-format. Therefore, We simply overrode our <script> tag in template-renderer to wrap contents said script-tags in JSON.stringify(JSON.parse()) & for other script tags, simply made a regex replacement replace(/[s]*[nr][s]*/gi,'') over the HTML document.
After setting up the HTML, its time we checked the external resources. Resources are requested by browser via 2 ways:
You may even go further ahead and add the next page resources under ‘prerender’ link-tag if your web-application is like a SPA (Single Page Application).
Payload Size of a TCP packet ~63Kb, which means that we can transfer 63Kb of data in a singe RTT (Round-Trip Time) before the network waits for next packet.Hence, it means that
Therefore, the experience can be improved by chunking the external resource files into independent modules of size of 40–50Kb. But this comes with a problem that multiple independent modules, all requested and executing in parallel (thanks to http/2), chokes the network and main thread of the browser.
To solve this, manual intervention is needed to segment resource requests/execution in 3 phases:
A colleague wrote an interesting article on employing advanced brotli compression algorithm to the static assets & serving them if client supports brotli-compression.
While images provide a more user-friendly and a visual medium to a web-page, they are often a load on the webpage either because of their count or their size.
A solution for smooth visual experience is to defer image loading on the webpage. To achieve this, we placed a dummy-image (usually a 1px jpg) in the src attribute of <img> tag and url of original image in the data-src attribute of the tag. Upon ‘domInteractive’ or ‘pageLoad’ event, we initiate a IntersectionObserver and start replacing the src of Image-tags with the value in data-src attribute as the images come in view.
To extend user-experience and gain SEO/Accessibility brownie-points, popular tools suggest
A colleague wrote an interesting article on how we setup a service for cost-effective, user-friendly & optimised images.
Because of highly interactive and content-rich webpages, crawlers & browsers often lose sight of what may be important. This is where HTML5 semantic tags come into play.
HTML5 provide numerous tags, which are similar to classical <div> but provide a universal semantic meaning. <header>, <footer>, <section>, etc. are a few to name which provide a semblance of HTML markup to crawlers and browsers.
Furthermore, modern browsers are resilient and often self-correct incorrect HTML tags (e.g. a tag you forgot to close), but we should make sure that we provide as perfect content as possible, therefore the HTML document should pass the W3C validations. Not only this helps browsers render the document with much ease, but makes your content apprehensible to crawlers.
We use Nginx as our primary front-facing load-balancer & web server. Following are general optimisations that should be performed to get most out of it.
Furthermore, do refer the [Mozilla SSL Configuration Generator] as a boilerplate to generate a secure & optimised Server configuration, as per the need.
The discussed optimisations are quite generic and can easily be extended to other web-servers (e.g. Apache, IIS).
The culmination of the set of aforementioned activities is evident in the following snapshot of ‘Average Page-Load Time’ for Makaan.com (taken from Google Analytics).
Not only did we managed to reduce the size of each asset (including HTML, CSS, and JS files), we chunked & linearised the delivery for the assets over http/2 protocol. This provided us a drop of ~60KB drop in average data transmission till page-load & full effective boost of ~2 seconds in page-load time across the entire website!!
For further detailed explanation, here’s a waterfall-snapshot for a webpage on Makaan.com
Following are popular webpage optimisation tools which should be used & referred for a better user-experience.
`The Secret Formula`: Hidden tips for improved Web Performance was originally published in Engineering @ Housing/Proptiger/Makaan on Medium, where people are continuing the conversation by highlighting and responding to this story.