E-shop Speed Optimization – Part 3 (Frontend)
We dedicated the second part of this series to backend and server optimizations. In this article, we’ll take a look at other optimizations that apply to the frontend.
Images, along with scripts, usually pose the biggest problems with website speed.
We can achieve image responsiveness by using the srcset attribute.
Srcset allows us to define one source image in multiple sizes. The sizes attribute defines how much space a given image takes up at different screen sizes.
The WebP format allows us to reduce the size of images without compromising their quality. Support for WebP images is high in browsers, but for IE and older Safari it’s necessary to use the picture element, where we define the webp image source as well as the jpg image source for unsupported browsers.
For images that we use directly in css using background-image, we can use Modernizr https://modernizr.com/download?setclasses&q=webp, which detects what features are available in a browser. If a browser doesn’t support webp, the no-webp class is added to the html element and subsequently it’s possible to use the image in the basic format in these cases.
<img loading = ”lazy”
The loading attribute with a lazy value allows us to delay the loading of images until the images need to be loaded (the user scrolls the page and is getting closer to the image). If we apply this attribute to images that we don’t need to load as soon as possible (such as a banner image that appears at the top of the page), this technique can speed up page loading and reduce the overall amount of data transferred. The attribute is available in most browsers except Safari.
CSS styles are a fairly large part of websites. What usually helps us with CSS optimization are various tools or frameworks that prepare optimized CSS files for us when creating a production build.
Removing Unnecessary CSS Code / Code Splitting
To reduce the total amount of CSS code, it’s a good idea to remove generally unused CSS. In addition to the generally unused CSS, we’ll probably also use CSS specific to one subpage. In this case, it’s advisable not to load this CSS on the home page and to load it only after going to the subpage that will use the given code. Of course, it also depends on the size of the particular code, if it’s a small amount, then there is no need to split the CSS.
By minification we can reduce file size by removing redundant characters, unifying common classes without changing the functionality of that CSS. It’s possible to minimize CSS automatically, for example with Webpack, using mini-css-extract-plugin or css-minimizer-webpack-plugin.
We can use two attributes for <script> tags in HTML:
It’s good to use async for third-party scripts. It’s good to test the defer attribute to determine whether scripts work correctly with this attribute. With our website’s scripts, there may be a ranking issue with async loading, as the scripts may be of different sizes, so the script that was originally supposed to be executed later will be executed before another script. That’s why it’s better to use the defer attribute for larger applications.
Duplicates in the Resulting Bundle
In case we find duplicate libraries in a bundle, we can solve these duplicates using yarn resolutions:
Similarly to the pictures, lazy loading can help us delay loading. An example of such loading might be loading an external library only after clicking on the button when the library is first used:
Finally, I offer 5 points that can be used to achieve the best possible optimization in the shortest possible time:
- Minify CSS and JS + gzip
- Images – use loading = “lazy” and WebP format
- Use async for external scripts and, if possible, defer as well
- Code splitting – split CSS and JS based on individual subpages
- Upgrade of used external libraries, removal of libraries