10/12/2021

Hyva Themes x Frontend performance

Author: Michał Ł.

It has been proven that improving user experience along with the feature set is directly bound to the sales rate. One of the Google Lighthouse tips states: “Walmart saw a 1% increase in revenue for every 100ms improvement in page load.” The frontend performance can be tricky and there are some caveats we have to be aware of. However, it is worth the time and effort to observe, measure and analyze the performance results of a given area to offer a superior user experience without compromising on content richness and quality.

Common issues

Store owners, understandably, often want to serve the best content quality to promote products or current events. "The bigger the better" is not always the best solution. Large images or videos are costly in terms of request time, file transfer size and computing resources, all of which takes time to process.

In the e-commerce-oriented business, collecting data of user interaction with the website is crucial but adding too many trackers is a common problem. Every data analytics service offers some common and/or unique features and using them all at once negatively impacts the frontend performance.

Loading all the content at once is often considered a mistake in terms of performance and end-user attention, for example placing a promotional video with autoplay somewhere in the middle of the page will impact performance and decrease user experience a lot.

Using custom images as content background is eye candy but it directly impacts performance in additional ways. This is the most aggravating factor for page rendering in the context of CSS parsing. Adding JavaScript libraries to a page can provide the requested functionality but the libraries often contain a lot more than we actually use and need. This leads to increased file size and transfer for unused code.

General tips for a better frontend performance

According to our experience and based on our last projects, for further analysis, we should assume backend performance and page delivery are constant and are served within optimal time.

  1. Make sure that the multimedia content is suited for the device.
  • To ensure properly-sized images are served for such clients like retina iPhones or desktops you can use the picture HTML tag,
  • Use newer image formats - WebP or AVIF with the default image fallback of the picture HTML tag (e.g. jpeg),
  • Use separate images for mobile and desktop served either with media queries or backend mobile detection (preferably),
  • Keep image size low, around 100kB for mobile image should be plenty,
  • Try to deliver portrait pictures for mobile devices to properly display content, but remember some devices have a taller aspect ratio than others (9:16, 9:18, 9:18.5, 9:20) so a compromise might be to use a more square aspect ratio (e.g. 4:5, 4:6): such images will be easier to handle.

  1. Videos should not be preloaded, unless in the main view
  • Consider limiting video quality to 720p30 for mobile users and 1080p30 or 720p60 for desktop users, both with an option to switch for higher quality. If you use an embedded video player e.g. YouTube or Vimeo, they offer such functionality natively,
  • Use a script which switches the video tag preload attribute from none to metadata when the end user scrolls to it or slightly above.

  1. If handling large amount of product images in different resolutions and pixel densities is or will be too much time-consuming, consider using a 3rd party solution for managing image optimization e.g. imgix.

  1. Use fewer trackers and schedule them according to priority: not all of them have to run right when the page starts loading, a large portion of them will be fine when included after the page is fully loaded, assuming page load time is low,
  • Some external scripts like support chats, opinion and review providers or external image galleries should be delayed and excluded from main thread,
  • Make sure that the functionality of the tracker you want to use is not available in already used trackers or cannot be added and/or won’t be added in the nearest future: reusing what you already have is the preferred solution.

  1. Network requests and transfer are one of the most cost inefficient aspects of the frontend so keep in mind that delivering lots of small scripts, images and fonts impacts performance. Even if you combine it into one large CSS or JS file, most code may not be used on most of the pages
  • Introducing Hyva Themes into our projects allowed us to heavily focus on this aspect and significantly improve results: while implementing a theme, we avoided large JS libraries and pruned unused CSS to leverage the power of AlpineJS and TailwindCSS included with Hyva Themes,
  • Equally important is to reduce unused HTML code in DOM, which is delivered with the implementation of Hyva Themes to the project,
  • As we mentioned in previous articles, highly specialized JS libraries like GlideJs can complement functionality on selected pages, avoiding large amount of unused code on the pages not requiring such a feature.

  1. Granular control over the frontend development is a priceless advantage: if you are able to implement a Hyva-based you definitely should
  • Hyva Themes allowed us to rewrite the crucial parts of the frontend design from the ground up for a modern, mobile-first approach. In the case of BedreNaetter we have managed to achieve a noticeable performance increase, however we are still working towards greater improvements and a polished look,
  • Even rewriting basics like the home page, product display page and product list page gives an edge over the competition. We have done it before for other projects as well,
  • A frontend based on a Hyva Themes project can be introduced in batches, piece by piece and this, in our opinion, is a hugely undervalued merit.

  1. Load content partially: most users attention ends after the first scroll
  • Modern browsers implement a few mechanisms to improve performance, one of which is the HTML attribute loading for instructing the browser if image loading could be delayed (lazy) or should be loaded immediately (eager),
  • An efficient cache policy will speed up the loading of common page elements such as styles, fonts, external scripts: for the next visit loading times will be decreased, thus it is more likely for users to scroll lower and load more content,
  • Load mobile scripts and styles first and alter them for desktops: currently most Internet traffic is mobile-based so it is expected to deliver lightweight pages for mobile and extend it for more powerful desktops.

Tricks for edge cases

Sometimes it is impossible or extremely difficult to build a great performance-wise store, which will be appreciated by the end user and the Google indexing engine, but Hyva Themes delivers a solid performance base which can be leveraged to achieve ambitious goals. Furthermore, considering that we implemented Hyva along with our own ideas and solutions, we have delivered an impressive product.

To take advantage of Hyva Themes consider the following:

  1. Use the IMG tag with loading lazy and position absolute instead of a CSS background to prevent blocking page load while the browser reads the CSS file.

  1. Use SVG or encoded SVG in the IMG tag for small, uncomplicated images, e.g. a calendar icon, check icon, account icon etc.

  1. Do not use external hosted fonts, if possible host fonts locally (may require a license).

  1. Do not use typographic fonts for only a few elements on a page, it is more efficient to use SVG as a plain HTML tag or use the IMG tag with base64-encoded SVG contents, this saves requests and transfer.

  1. If some of your content like video comes through CMS content instead of a template, consider placing the IMG tag before with a script attached and the loading lazy attribute to trigger switching video preload from none to metadata, when the user scrolls to the position. Either attach the script to the load event on a base64-encoded SVG 1x1 viewbox content or the error event with an empty src attribute.
  • Some browsers are impatient (Chromium-based) and load more than the user sees (height-wise),
  • Some browsers have not caught up yet (Safari) and load full page content. In this case make sure to run a switching script attached to the above mentioned IMG within a setTimeout function to delegate work to a separate thread,
<script async>
if (!window.preload) {
   window.preload = () => {
       let video = document.getElementById('video').querySelector('video');
       video.preload = 'metadata';
       video.src = video.src + '#t=0.1';
   }
}
</script>
<div class="parent">
   <img src onerror="() => { setTimeout(window.preload, 1) }" loading="lazy"/>
   <div id="video"><?= $videoCMSblock ?></div>
</div>

  1. Use placeholders/mockups to support chat add-ons and load a full script file only when the user interacts with it (preferred) or after a significant delay.

  1. Write local (within-template) scripts, avoid global libraries, attach global scripts only when required. Remember to use the async attribute for scripts that should be run after a page is loaded to avoid blocking the browser from interpreting the code. Hyva Themes with AlpineJS is a great tool for that.

  1. Leverage preloading (HTML link tag with attribute rel and value preload) to load a hero image as soon as possible (Caution! Preloading when your page is fast enough may actually cause a delay and consequently slightly lower lower the score).

<link rel="preload" href="//example.com/resource.jpeg" crossorigin=""

  1. Move external script loading after a window load event with a custom event triggered when the file is available to run functions from the loaded file attached to above mentioned custom event. For example we want to run the foo function from an example object in example.com/foo.js. So we use the following code.

<script async>
window.addEventListener('load', () => {
   setTimeout(() => {
       let script = document.createElement('script');
       script.addEventListener('load', () => {
           window.dispatchEvent(new CustomEvent('example-foo-loaded'));
       });
       script.addEventListener('error', () => {
           window.dispatchEvent(new CustomEvent('example-foo-failed'));
       });
       script.async = true;
       script.src = '//example.com/foo.js';
       document.getElementsByTagName('head')[0].appendChild(script);
   }, 1);
});
window.addEventListener('example-foo-loaded', () => {
   setTimeout(() => {
       try {
           window.example.foo();
       }
       catch (exception) {
           // handle exception
       }
   }, 1);
});
window.addEventListener('example-foo-failed', () => {
   setTimeout(() => {
       // handle script not loaded
   }, 1);
});
</script>

  1. If you have a chance to implement mobile detect on the backend side, it is generally a good idea to do so to reduce transferred data and the usage of media queries for every piece of content.

  2. Use width and height with images on the IMG tag especially with SVG’s. This allows browsers to set the rendering limit within image sizing first and then scale, for example if you don't set this attribute the browser will attempt to render SVG in an IMG tag with the native resolution of the window/screen and then scale it down to CSS served sizing and that is more computing than required.

Conclusion

It is worth noting that optimizing the frontend requires much more time than just implementing it. It is required to cooperate with the store owner for content preparation, lots of measurement and careful analysis of harvested data to prioritize the most beneficial path to optimize performance. You can read more about this here and here.

Optimizing the frontend performance requires time, work and experience to achieve great performance results. Hyva Themes provides tools and a good base for further work and creates an opportunity for outstanding user experience. Implementing Hyva Themes within an existing project revealed many imperfections of current solutions and inspired us to research and improve our approach to modern problems.

Related Posts

Contact with: Michał Ł.