Front-end performance: How we optimized our website (from the living style guide)
The front-end is the first place where you meet your users. But if your website takes too long to load, they won’t wait around.
No one is going to visit and appreciate a slow website. Not your customers, and especially not Google.
The page experience and overall performance of your website, such as page speed, are important ranking factors for search engines. Better performance means more chances to be found by your audience.
Optimizing your website for speed is very important to improve customer experience.
We’ve gathered our expertise on front-end and website optimization and are now sharing how we actually improved our own website performance from the living style guide.
We hope it will give you hints on how to tackle your own website performance review and update.
What is front-end optimization?
A key parameter to consider is the user experience, and how fast the main content of the page is rendered.
Nobody likes to see a blank screen for seconds.
As a website owner, you have to understand that website loading time is a critical ranking factor for Google and is measured as one of the key metrics of the Core Web Vitals: Largest Contentful Paint (LCP).
At One Inside, we take care of our customers and want to offer them a great experience when they visit our website as well.
Our approach to front-end development is to build a front-end living style guide. This is how we can fix front-end issues fast and in a streamlined way as well.
Before telling you how we improved our website, we need to introduce the concept of a living style guide – as it is where the improvement will take place.
What is a front-end living style guide?
The front-end living style guide is a website that defines the corporate design and user interface for your company websites or other web or mobile applications you may use.
Each component required to build your website such as the navigation, teasers, carousel, and banner, are displayed individually.
It helps the designer and developer understand how the website or mobile application will look, so they can focus on one single element at a time.
At One Inside, we built a living style guide for our corporate website as well as introduced this front-end best practice to customer projects.
Below we’ll show you how we improve our website by optimizing the living style guide.
Use the living style guide to improve page performance
As the name implies, the living style guide’s main purpose is to “guide” your design. It guarantees consistency among all the components of your website and for different devices.
The living style guide for our website was used as expected and drove the UI implementation. However it has one issue: a bad score with Google Lighthouse.
(Google Lighthouse is available via the Chrome developer console and generates reports about a web page speed and performance).
The living style guide was considered slow to load and slowed down interactions. The user had to wait to see the page and to be able to click on buttons and icons.
If the living style guide is slow, the resulting website will suffer from the same issue.
Analysis of the frontend code
The very first thing to do is to understand how frontend code is built.
The technical pattern of the living style guide was the following:
- All frontend components were compiled as one application or (one large JS file)
- All CSS were compiled as one large CSS file
This pattern used to be applied everywhere and is optimized for the HTTP1 protocol.
The HTTP1 protocol recommendations indicate to minimize the number of requests to the server and to load a few large files instead of multiple small files.
Because establishing a new request (connection to the server) can be time-consuming (independently from the size of the file) and many simultaneous requests are not allowed.
This approach has some advantages:
- A small number of requests to the server
- Servers get less load and run faster
- Better compression ratio (the compression is better on one big file than multiple individual small files)
The disadvantages are:
- Slow to download and decompress by the browser
- This means the interaction on the page is blocked and waiting as the browser doesn’t know what can interact, and with what.
- The display is blocked until the end of the loading of the stylesheet to render for each of the elements of the page.
The question we asked ourselves was: is there a way to get away from this current pattern?
Looking at the improvement brought by the new HTTP2 protocol gave us a solution.
HTTP2 to help the frontend developer
Today, modern servers provide the new version of the HTTP Protocol (HTTP2) and web browsers are using multithreaded and multicore capabilities of modern computers and mobile devices more and more.
This means we can process even more data simultaneously.
The HTTP2 protocol comes with great improvements:
- The protocol can accept multiple simultaneous requests by re-using the actual connection.
- It doesn’t need to negotiate and re-create a connection for each request. The lost-time disappears.
- It can send many files (from many requests) into one answer (multiplexing).
- And it offers better compression (30% better).
Thanks to HTTP2, frontend development recommendations got an update and today’s best practice is to split every file into small pieces.
Here we load the needed components of a page simultaneously.
It comes with many advantages for the web browser:
- They are rendered as soon they are available, without having to wait for the other files.
- Each UI component is interactive and has its definitive design and size.
On top of this, HTTP2 also supports a “push” function.
The server can send a file that is not yet requested but is known to be necessary. This is done by using “preload” in HTML.
How we boosted website performance
To improve the website we applied several changes to the living style guide such as:
- Loading critical files first
- Changing the code pattern
Let’s have a detailed look.
Splitting into small components
Our improved frontend is now divided into many components.
These components are a small part of the page, which has a specific functionality: display the image-gallery, display the main-menu, display the main-content, and so on.
Critical mandatory files first
These are usually corresponding to the first parts that we see. The header, the global styling, the main menu, and approximately the first 1/3rd of the screen.
In order to display these parts almost instantaneously, for an astonishing “perceived speed” and best user-experience, we need to provide them as fast as we can.
To do so, we need to extract this code into small files which will load faster.
As soon as the browser receives them, it can start to render the page without waiting for other parts of the page to load.
For the user, the page displays and the loading seems finished.
From one code to multiple codes
- it needs to extract (from compression).
- parse the file as code, check if it’s conform (no syntax errors, etc.)
- compile it for the machine (transform into something that the computer can execute)
- check to which element of the webpage it must be applied (when the user makes a click on a button or an icon).
During this time, the main thread of the browser will be busy and can’t do anything else. The browser is blocked and nothing happens.
The display is also suspended and clicking on items does nothing. The webpage is not yet interactive. The user can’t interact with it.
By going away from this pattern (and paradigm), we can take advantage of the modern architecture of browsers and of our modern computers and mobiles: real efficient multitasking.
The solution is to split everything into smaller pieces of code or components.
At the end, the result is the same: the browser has processed the same amount of code, the same amount of bytes is downloaded, but the browser did it by processing one small piece of code at time.
As soon as one piece is processed, this part of the webpage can go live, be displayed, rendered and made interactive, while other parts are still loading, or parsing, or compiling.
Async or defer? This is the question.
The existing solution to load a script and to not block the main thread is to specify it as asynchronous.
When we include it in the HTML page, we add the async attribute.
When the scripts are set as async, it simply tells the browser that the scripts are not blocking, hence, the browser doesn’t need to wait for them and that it can go on.
The scripts will be started as soon as they are received (without any notion of order).
An older defer attribute does exist too: it keeps the order of the script, even if the files are received differently.
- A first script is big, a second script is small. Both are set with defer.
- The browser will first receive the second file, as it is smaller.
- But it will wait for the first script, and start the first before starting the second.
Async & Defer are already a good solution, but in our case, it was a bit more complicated.
The components (and so, the composition of the page) can be freely chosen by the editor of the webpage in the CMS (content management system).
Of course, we don’t want to load everything, just in case it may be chosen to be used on that page. Otherwise, we are back to the monolithic, one global component pattern.
This is exactly what we want to avoid.
Our solution is to add a specific attribute in the HTML of each component, telling the page that this part is not a simple HTML, but a specific component.
About the styles
We separate the global mandatory stylesheets that are meant to be used on all pages: header, teaser, navigation-menus and more, and compile them into a separate CSS-file.
This is quick to load and the browser can start to render the DOM (styles and sizes) without waiting for the rest of the page.
Subsequently, the page can be rendered and viewed, even if other chunks are still loading at this moment.
By just changing this pattern, the Google performance score increased to over 90/100!
If we wanted to achieve a better score with our website, here’s what we could do additionally:
- Mobile-styles only when the browser is on mobile-devices, hence this means these styles must be delivered globally for the website and not within the payload of each component. This is difficult to manage in a project.
- Desktop styles only on desktop-device.
- Global styles can be a global small file (not duplicated in critical-CSS AND in component).
What is this all about? To summarize front-end performance optimization in one sentence: load only what is needed and when it is needed.
You will see drastic changes on your website performance and a direct positive impact on the customer experience.
And in the end, this is what we all want: happy customers.
Senior Software Engineer Frontend