Performance Best Practices for SHOPLINE Themes

Performance is crucial for merchants when they choose a theme for their online store. When you build or customize a theme, you should focus on performance.

Optimizing your theme for performance is key to the success of the merchants you support and their customers' experiences. Performance directly impacts conversion rates, repeat business, and search engine rankings.

When a theme is submitted to the SHOPLINE Theme Store, its performance is tested on a benchmark shop to determine its score. To be accepted into the SHOPLINE Theme Store, a theme must have a minimum average Lighthouse performance score of 60 across the home page, product page, and collection page.

You can run a similar test on your theme using a development store.

Note

SHOPLINE built Seed with performance in mind. You can explore the Seed repository to see how SHOPLINE applies these principles.


Optimizing for Performance

Consider the following best practices for improving your theme's performance:


Optimize Your JavaScript

Optimize the JavaScript in your theme using the following tips.


Reduce JavaScript Usage

Consider building your theme using mainly HTML and CSS. JavaScript shouldn't be required for the basic functionality of your theme, such as finding or buying products.

Instead, use JavaScript as a progressive enhancement, and only where there is no HTML or CSS solution available.

CSS parses and displays much more quickly than JavaScript, so whenever possible, utilize CSS features to create interactivity. You can find additional details online by searching for the phrase "using CSS instead of JavaScript." One example is the blog 5 Things You Can Do with CSS Instead of JavaScript by Juan Martín García.

Your minified JavaScript bundle size should be 16 KB or less. SHOPLINE automatically minifies JavaScript when it's requested by the storefront.


Avoid Namespace Collisions

Namespaces allow you to put variables into unique containers to prevent conflicts in the global scope. However, JavaScript minifiers shorten JavaScript variable names, which can cause conflicts.

To avoid namespace conflicts in the global scope, enclose JavaScript values in a function scope. Values defined in a function scope are accessible only within that function, so there's no risk of conflict with other variables in the global scope.

The following example shows you how to wrap minified and renamed JavaScript variables in a function scope:

(function () {
var test; function test_function() {}
})();

For instance, the Immediately Invoked Function Expression (IIFE) pattern is a JavaScript function that executes immediately upon definition. The IIFE pattern guarantees that the values defined within the script are confined to the function created by the IIFE, thereby eliminating the risk of collisions in the global namespace.

Note

Scripts injected in themes should always be wrapped in an IIFE to prevent global namespace collisions.


Reduce Your Dependency on External Frameworks and Libraries

If you need to use JavaScript, consider avoiding third-party frameworks, libraries, and dependencies. Instead, use native browser features and modern DOM APIs whenever possible.

Adding JavaScript libraries to your package can result in large bundle sizes, slower load times, and a subpar experience for users. Frameworks like Angular, Vue and React, as well as extensive utility libraries like jQuery, come with substantial performance overhead.

Refrain from adding polyfill libraries for outdated browsers (anything that doesn't support async/await). If you use a browserslist, you can target browsers with a market share greater than 1%.


Avoid Parser-Blocking Scripts

Parser-blocking scripts block the construction and rendering of the DOM until the script is loaded, parsed, and executed. They also cause network congestion and significantly delay page rendering. This affects metrics like First Contentful Paint and Largest Contentful Paint. To prevent this, use defer or async attributes on your script tags.


Preload Key Resources, Defer or Avoid Loading Others

Preloading resources allows the browser to download resources before they are discovered.

Choosing to load some resources later and using system resources helps you reduce the size of the initial package of resources that need to be downloaded before a customer can meaningfully interact with the page.


Use Resource Hints to Preload Key Resources

You can add up to two resource hints to your code per template by using one of the following:

When SHOPLINE generates a page with preload directives, it will include a preload resource hint as a Link header in subsequent requests.

Resource hints should be used judiciously. For instance, consider preloading only render-blocking stylesheets that are needed for the initial functionality of the page, such as above-the-fold content.


Lazy Load Below-the-Fold Images

Load images only when necessary on a page, and think about using placeholders until customers scroll down. This can also enhance perceived performance, making the page appear to load faster than it actually does. Instead of using a library, you should add a loading: 'lazy' attribute to your image tag using the image_tag helper:

{{ image_tag (image_url settings.favicon) loading='lazy' }}

Anything that shows up above the fold shouldn't be lazy-loaded. Above-the-fold content is what a viewer sees when the page first loads before scrolling down. These resources should be treated as critical assets and loaded immediately.

Tip

For a more complex instance using responsive images, refer to Use responsive images.


Load Non-Critical Resources on Interaction

Your page might include code for a component or resource that isn't always utilized. You can load these resources using an import on interaction pattern to prevent loading, parsing, and running unnecessary code.


Consider Using a System Font

Using a system font avoids the client needing to download another resource before the online store's text can be rendered.

System fonts are fonts that are already installed on the user's device. Using system fonts directly avoids relying on external font files, which eliminates the time browsers need to wait for font files to download before rendering fonts, allowing for better theme performance.

If you choose to use system fonts, the font used to render the text will depend on the user's operating system. There are three generic system font types. The following are examples of fonts in these types:

  • mono - Menlo, Consolas, Monaco, Liberation Mono, and Lucida Console
  • sans-serif - BlinkMacSystemFont, Segoe UI, Roboto, Ubuntu, and Helvetica Neue
  • serif - Iowan Old Style, Apple Garamond, Baskerville, Times New Roman, Droid Serif, Times, and Source Serif Pro

Host Assets on SHOPLINE Servers

Deliver as much as you can from the SHOPLINE content delivery network (CDN). Using the same host for your assets avoids unnecessary HTTP connections and allows the server to prioritize delivery of blocking resources using HTTP/2 prioritization.

Within a SHOPLINE context, you can achieve this by placing your assets in the theme's /assets folder using the Asset REST Admin API resource. You can generate links to these assets using URL helpers. Learn more about the SHOPLINE CDN.


Use Responsive Images

Viewing large images on a small device can be frustrating and can reduce page load speed. Using responsive images automatically resizes them to match the device screen that customers are using.

Defining an image size guarantees that you download the smallest possible image without losing quality. The storefront requests the image size that will be shown, then reduces the file size downloaded from the CDN. This minimizes dependence on browser-side scaling.

You can add responsive images to your theme by using the image_tag filter. This filter returns a srcset for the image using a smart default set of widths.

Input:

{{ image_tag (image_url product.featured_image) }}

Output:

<img
src="https://img.myshopline.com/image/store/3400001642/1668500337237/5a2bf4bbfbdf4d59a69aad12b0cf1c7c.jpg?w=1032&amp;h=1333"
srcset="https://img.myshopline.com/image/store/3400001642/1668500337237/5a2bf4bbfbdf4d59a69aad12b0cf1c7c_375x.jpg?w=1032&amp;h=1333 375w,
https://img.myshopline.com/image/store/3400001642/1668500337237/5a2bf4bbfbdf4d59a69aad12b0cf1c7c_540x.jpg?w=1032&amp;h=1333 540w,
https://img.myshopline.com/image/store/3400001642/1668500337237/5a2bf4bbfbdf4d59a69aad12b0cf1c7c_720x.jpg?w=1032&amp;h=1333 720w"
width="1032"
height="1333">

Optimize Handlebars Code

You can edit almost all of the Handlebars that is used to render your store. There are efficient and inefficient ways of writing Handlebars code. Doing complex operations repeatedly can increase your Handlebars render time, which impacts your overall store speed.

For instance, If you need to sort the products in a collection by price, you should do this prior to looping through the products in your collection, rather than within the loop code.

This is because the order of the products does not change for each product, and calculating the order of the products adds processing time to the request.


Testing for Performance

SHOPLINE offers merchants a speed report that helps them to understand the performance of their store. This report is a weighted average of the Lighthouse performance scores of certain pages. You can run Lighthouse audits manually.


Run a Lighthouse Audit Using SHOPLINE Data

Follow these steps to replicate the tests that SHOPLINE conducts to gauge an online store's speed score. SHOPLINE performs a comparable test on themes before they are accepted into the SHOPLINE Theme Store. You can run a similar test on your theme to see how it performs.

  1. Set up a development store.
  2. Import the test product CSV to the store. The store should have no other products, variants, or collections.
  3. In your development store, beside Online Store, click the eye icon to preview your store.
  4. Get the URLs for the pages that you want to audit. You should test the home page (hp), any collection page (cp), and any product page (pp).
  5. Go to Google Lighthouse and follow the instructions to generate a report for each of your pages. Record the mobile score for each page.
  6. Use this formula to calculate your results: [(cp * 33) + (hp * 13) + (pp * 31)] / 77. This will give you your theme's speed score.
Tip

You can perform this process several times and use the median of the scores to obtain a more precise result.

Was this article helpful to you?

Error loading component.

Error loading component.