Dive Deeper

Performance

Differential loading

The pattern called Differential Loading by the Angular framework is an approach where modern browsers will download and use a more optimized JavaScript bundle. It is accomplished by taking advantage of the fact that only more recent browsers implement a feature called JavaScript Modules (often referred to as esm for ECMAScript Modules).

When using differential loading, browsers supporting JavaScript Modules will use modern ECMAScript features, saving approximately 15% script size for eSales Fashion. The legacy bundle will transform the code to support older browsers, such as Internet Explorer 11.

<head>
  <script src="https://cdn.esales.apptus.com/integration/v1/esales-fashion.js" type="module"></script>
  <script src="https://cdn.esales.apptus.com/integration/v1/esales-fashion.es5.js" nomodule defer></script>
  <script src="init-esales-fashion.js" defer></script>
</head>
  • type="module": This marks a script tag as a JavaScript Module. It enables import/export syntax in the code and is fetched with defer by default.
  • nomodule: This attribute on a script tag will make a browser that implements JavaScript Modules ignore the script tag. Older browsers, such as Internet Explorer 11, will ignore it and execute the script normally.

Deferring scripts

Due to module script tags always being deferred, defer must also be used in the script that runs the esales.init() code to bootstrap components. This also means that the eSales Fashion components will not be rendered until the DOM has been completely parsed (right before DOMContentLoaded event).

The amount of time before e.g. search results are rendered on a page depends a lot on the surrounding site when using defer. See the following performance suggestions.

  • Use the defer attribute to avoid having synchronous scripts as much as possible.
    Synchronous JavaScript blocks rendering of a web page, both CSS and HTML. One of the most important features for displaying a page quickly, other than having less JavaScript, is to make sure that non-critical JavaScript is not blocking page rendering. Critical JavaScript may be anything that displays content "above the fold". Non-critical JavaScripts should ideally use the defer attribute so that it executes when the document is fully parsed and ready. For more information about how browsers parse HTML, see the Mozilla blog.
  • Use as few scripts as possible (with defer or not) before esales-fashion.js.
    In general eSales Fashion displays important content, such as search results, category navigation, recommendations, and more. To reduce the time until such content is rendered, it is best to add the eSales Fashion scripts and initialization early. The sooner the script executes, the faster requests are sent to the server returning content to render.

Web components

The term "web components" is an umbrella term that refers to several technologies working together. The main parts of this are "custom elements", "HTML template tags" and "shadow DOM". The webcomponents.js includes all these in the bundle it provides. The polyfills for the main component libraries for modern and legacy browsers also include these features.

  • Custom elements - A way to package lifecycle hooks and logic into a re-usable tag, e.g. <product-card>.
  • HTML template tags - A <template> element contains inert content. That means it will not be rendered and links/sources will not be fetched. The content can be easily cloned and inserted into the DOM.
  • Shadow DOM - Provides a way to encapsulate DOM content inside a node, so that outside styling will not affect it.

Support for these three features needs to exist natively in the browser or be provided by webcomponents.js for eSales Fashion components to work correctly.

Slots

A <slot> is a way for web components (with Shadow DOM) to display content inside them. This allows custom content to be displayed in various locations or states of web components that support slots. The slot attribute is used with the slot id, to determine what slot (location or state) to display the content, e.g.

<p slot="[slot-identifier]">

Hiding slot content on load

The content of the slot may become visible before the component library is loaded. The standard way of avoiding this is to hide the content of the slot as long as the element is not defined. This is done by using a style tag outside of the component. The following example hides the Navigation assistant component, <esales-navigation-assistant>.

<style>
esales-navigation-assistant:not(:defined) {
    display:none;
}
</style>

Browser support

The list below shows which browsers we are currently supporting with the .es5.js version of the library. Older browsers may be supported, but they are not actively tested against.

  • Google Chrome v49+
  • Mozilla Firefox v46+
  • Microsoft Internet Explorer 11
  • Microsoft Edge v14+
  • Apple Safari v9+
  • Opera (latest two versions)

Polyfills

Polyfills are bits of code that are meant to fill in support for features that may not be available in all browsers yet. This is typically done by performing a check whether the API exists and possibly check that it is implemented correctly. If not, the script will add the API manually so that it will exist for forthcoming code.

Feature Package / Repository Legacy (es5) Modern
URL url-polyfill
URLSearchParams url-polyfill
KeyboardEvent.key Custom (based on keyboardevent-key)
es2015 API core-js/es6
array.includes() core-js/es7.array.includes
Object.entries() core-js/es7.object.entries
fetch() whatwg-fetch
IntersectionObserver IntersectionObserver
Web Components webcomponentsjs

Deferring script loading

Due to <script> tags default behaviour of blocking parsing of the HTML, it might be desired to use the defer attribute. To use defer, one needs to make sure esales.init({ ... }) is only called after the esales-fashion.js script has been executed.

Deferring can be performed by either using a script file or via an inline script.

Defer via script file

Keep the initialisation in its own script file, and load the scripts in the correct order with all script tags having the defer attribute.

<!-- index.html -->
<script defer src="https://cdn.esales.apptus.com/integration/v1/esales-fashion-polyfills.js"></script>
<script defer src="https://cdn.esales.apptus.com/integration/v1/esales-fashion.js"></script>
<script defer src="esales-init.js"></script>
// esales-init.js

esales.init({
  // ...
});

Defer via inline script

The DOMContentLoaded event can be used to preserve the correct execution order, since defer has no effect on inline scripts. The defer scripts are executed right before DOMContentLoaded. This way inline scripts can be paused until the deferred scripts have run.

<script defer src="https://cdn.esales.apptus.com/integration/v1/esales-fashion-polyfills.js"></script>
<script defer src="https://cdn.esales.apptus.com/integration/v1/esales-fashion.js"></script>
<script>
window.addEventListener('DOMContentLoaded', function() {
  esales.init({
    // ...
  });
});
</script>
×
Copyright

This online publication is intellectual property of Apptus Technologies. Its contents can be duplicated in part or whole, provided that a copyright label is visibly located on each copy and the copy is used in conjunction with the product described within this document.

All information found in these documents has been compiled with utmost attention to detail. However, this does not guarantee complete accuracy. Neither Apptus Technologies nor the authors shall be held liable for possible errors or the consequences thereof.

Software and hardware descriptions cited in these documents might be registered trademarks. All trade names are subject to copyright restrictions and may be registered trademarks. Apptus Technologies essentially adheres to the manufacturer’s spelling. Names of products and trademarks appearing in this document, with or without specific notation, are likewise subject to trademark and trade protection laws and may thus fall under copyright restrictions.

CLOSE