The new cms platform came with a great image api, so our editors could upload 100% quality images in high resolution but the images became responsive with different sizes depending on the user's device width. We also started using webp image format with jpg as fallback and made sure we lazy loaded images on every place where it made sense.
One drawback with the image api was that it was served from another domain then TUI. So, the DNS lookup and SSL handshake had to take placed. We solved that by having a proxy in our varnish cache that all our html, js, css, images and other assets are cached in. Finally, the top logo was a svg file which we included via the src attribute on an image tag. But that required an extra request. So we inlined the svg instead, making it possible for the user to see the logo much faster since it was already in the html response from the server.
The biggest improvement we have done with the css is to inline the css needed to render the above the fold content. We are using the npm module critical from the brilliant guy Addy Osmani. Then the rest of the css is loaded async with the technique from Filament group. That made a huge improvement for the first paint. We used to have a lot of css from bootstrap. We have part by part removed stuff from our bootstrap dependency and by that getting smaller file sizes. We are still not quite satisfied with the amount of css we deliver. But it’s a work in progress to reduce it even further. For the homepage we have a separate css file in order to make the page load fast.
As I mentioned before, my team has removed all jQuery code. We still serve jQuery to the client though since we have some widgets and 3rd party tracking scripts that require jQuery on our pages. We are working in the direction to be jQuery free but we are not there yet. But if we take care of loading jQuery we can do it the fastest way possible. We have put the defer attribute on all script tags. Some of the script that are not required for showing content above the fold we lazy load after the onload event.
A/B Testing tool
GTM and 3rd party script
We moved the execution of injecting GTM after the onload event. GTM in our case is responsible to injecting all tracking scripts and such. We have not seen any drop in tracking because of this. But this way, we don’t have to worry about poorly implemented scripts that block the rendering of the page.
Fonts are downloaded when the browser founds html that matches a css rule, which can take some time. We got fonts to load faster by using woff2, which has the best compression, and by instructing the browser via the browser hint preload with this code:
as="font" type="font/woff2" crossorigin=" ">
We used to have an icon font for icons on the site. Since fonts are slow to load, we have moved over to an svg sprite with icons instead.
We used to on every page download all files required to use our 3rd party site search app on load. But since the user doesn't need that before he or she decides to make a search, we now load the required files when they activate the search via the search icon.
Also, we have set long cache headers (about a year) on all of our assets and everything that should be gziped is gziped.
“Looking back, the key success factor for us has been that we’ve been given time and trust from the organization. We are trusted to judge for ourselves what to focus on and how to solve the problem. Second to that, it has been our ability to deploy changes as often as we need. Some days I’ve deployed tens of times to see if small tweaks made a different. With a traditional approach, with releases weekly or biweekly, you feel scared to do something that will be less good, since you have to wait weeks before you can fix it. This way, we can learn fast which is what it’s all about”, says Emil Wiklund.