Read our new Performance Guidelines

Building a successful ecommerce site isn't all about good functionality and the right inventory: it can be about other things like branding, user experience, and product imagery. But there's one thing that perhaps we don't talk about too much: performance.

Whenever performance comes up in ecommerce tech blogs, it's always along the lines of, "the faster your site is, the more likely a shopper is to convert". At NetSuite, we take steps to ensure that our customers' sites perform well, and this is something that runs all the way through the organization, from good, clean code in our source files, to opimizations to the backend, to having a team of engineers whose job it is to ensure our customer's sites perform well. But as the proprietor of your site, you also have a responsibility to ensure that your site operates to the best of its ability.

With that mind, some of our performance engineers have been busy putting together comprehensive standards and practical advice on performance. Without further ado, let me announce that we have completely rewritten the performance section with a downloadable checklist for performance improvements you can make to your site.

I strongly recommend reading through the document as it contains useful insights, action items and a checklist. Let me run through the sections of the guide and point out some interesting things that I've seen.

Caching

You know, we talked about caching a while back when I had a chat with Rafael Tucat. Implicitly, caching pre-generated resources improves the performance of applications because it removes the need for the application to generate those resources again. Furthermore, CDNs are geographically distributed and super-fast, which means that they excel at delivering these resources to the user.

Wherever possible, using caching is advised as it speeds everything up. A lot of what is covered in this part of guide is also covered by by the discussion I had with one of our performance engineers, Mark Sweeting. The advice was good then and it is good now.

SEO Engine (Page Generator)

As you'll know, we have a JavaScript engine running on the backend which can process the entire site and serve pure HTML if called to do so. It spins up when the server detects a search engine crawler, as they have no (or, at best, patchy) support for executing JavaScript.

We've talked about the SEO page generator a bit before, specifically coding with and debugging it. The general advice is that you want to keep the output from the page generator error-free and streamlined. In practice, this means that you need to cut the chaff from what is and isn't processed by the engine. Don't forget that a small bit of code can be used to hide certain bits of code from running when the page generator is used, eg:

if (SC.ENVIRONMENT.jsEnvironment === 'browser')
{
  alert('Only humans will see this message')
}

You can also convert this conditional statement into something you can pass to the context. Thus, if you want to render template content only to humans (or robots!) then you can.

The guide includes a number of action items that you can do to test the performance of the SEO page generator on your site. There's also good advice about code quality, such as removing certain jQuery and JS methods that could cause issues.

SuiteScript and Workflows

These two parts of NetSuite provide great of power to customize your site and its operation. However, with great power comes... yeah, well, great responsibility. Without a good understanding of this power, you can end up being reckless and causing a significant performance hit to your site.

Furthermore, this SuiteScript doesn't necessarily have to be script that you've written yourself. Bundles, whether from NetSuite or third-parties, will likely contain SuiteScript and/or workflows, and if any of these run against sales orders or customer/lead records, you could face a potential hit. Even simply having them installed could cause issues, so it's worth going through your bundles and removing any you don't use.

Our performance engineers give a lot of advice in this section — an indication of SuiteScript's power. The overall theme is look at how you can perform certain actions asynchronously or at scheduled times (ie in a non-live, non-blocking way). For SCA, consider how much data you are requesting from the backend when you access records, and if what you're sending back to it is only what is required.

SSP Environments

Here we're talking about shopping.environment.ssp and shopping.user.environment.ssp. The former contains things like site settings, categories, default session information, review configuration, content delivery entries, CMS entries and some extra settings. This makes it a prime example of something that should be cached by the CDN.

If you're going to do one thing, it's making sure that this cached (and that it contains nothing that shouldn't be cached). It should be trim: free it of all information that is not required on all pages. By default, it is 45KB before gzipping — if yours is over 150KB then you really must address this.

As for shopping.user.environment.ssp, this file is never cached. It's used to store personal information about the current user, such as information about their profile, session, product lists, and cases. If you need additional information about the current user then you could put it there.

DNS Prefetching

Every time a request is made to a domain name, its translation must first be looked up: while quite small, this is still a cost. One technique available to web developers is to make a request ahead of time and resolve the name before it's used. Thus, when the user does request it, the move is made much quicker as the initial lookup is not required. This is DNS prefetching.

In pre-Denali versions of SCA we put the following code in the head of index.ssp:

if (typeof nsglobal === 'undefined') {
  var prefetch_url = 'https://example.securedcheckout.com';
  document.write('');
  document.write('');
}

You can see the first document.write to be a little different, that's because this kind actually prefetches the entire page. The way we used it on our site, this would cause a 404 and effectively waste the roundtrip, but it was included for browsers that didn't support DNS prefetching. If you like, you can remove the line which does a full prefetch (and leave the DNS prefetch) or you can remove both.

Categories

Categories, categories, categories. As our performance engineers point out in their guide, this can be a major source of headache if you find your site running slow.

The data associated with a category tree can vary in size from site to site, and the more you take advantage of this functionality, the more you'll notice performance degrade.

Alas, while this may seem inevitable, there are certainly steps you can take to mitigate this. First and foremost: prune any categories that you don't need any more. While you're at it, remove any data associated with those categories that you don't need.

Items API

I think we covered a lot of advice on using the items API when we talked about showing shoppers their product reviews, and when we sat down with Pablo Zignani to learn about how we could improve the performance of field sets and facets.

The most common mistakes all relate to requesting more information than is required: when making a call, just be sure to specify exactly what you want. One of the things we learnt when we did the reviews tutorial is that when we make a call to the API, we must specify a field set and we can (and should) take the time to create a field set that returns only the data we need. This is good advice.

More good advice comes in the form of ensuring that you only include URL parameters that you need: the more you request, the longer it will take to run and the longer it will take to be returned. Furthermore, while one of the main uses of this API is to return results for keyword searches, keep in mind that this is generally the only time that you need to include facets — if you don't need them, don't use them; facets take time to generate.

To include facets in your items API response, you attach include=facets as part of the request URI. This will load the facets that you've set up to include as part of your website's setup record (in Setup > SuiteCommerce Advanced > Set Up Website > Search Index > Facet Fields). You can, therefore, choose not to include this parameter and all facets will be excluded.

However, you can also include facets but exclude specific facets from the response if you wish. To do this, you can add facet.exclude=<facet ID> to the request and the specified facet will not be included. You can also exclude specific facets from being included anywhere in the site (if you don't want to remove them from the configuration). To do this, you will need to extend the master search API options like this:

_.extend(SC.Application("Shopping").Configuration.searchApiMasterOptions.Facets, {
  "facet.exclude": "<facet ID 1>,<facet ID 2>,<facet ID 3>"
});

Content Management

There isn't too much to say other than that, in general, using the site management tools (SMTs) will cause a degradation in performance. I mentioned categories, but let's look at other forms of content.

Using the tools lightly will not create major problems but everything has a cost. This means that, where possible, you should minimize your use of it; for example, while you could create a header and footer using the SMTs, consider using standard views/templates instead.

Another example comes from how you implement merchandising zones. You should ensure you're using a field set that is appropriate for it; specifically you should use one for related items or co-related items (and not a custom search). Our standard advice applies: only include fields you need for the functionality.

Images

When we talked about optimizing images a little while ago, we looked at how you might, for example, run them through a compression algorithm or substitute them for code or text. But there's another way: use the resizing service built into NetSuite.

The service addresses the issue of loading images that are bigger than necessary. For example, if you know that you only need a thumbnail (of 150x150px size) then you do not need to load one bigger than this and have the browser scale it for you.

See our documentation on setting up image resizing. Ensure that you've set up all the sizes you need, and that their specified dimensions are correct.

As for other advice, the guide provides some excellent general tips around imagery that echo the advice I gave in my article. Namely:

  • Consider whether you need to use images at all, and whether they can be swapped for sprites, existing icons, or encoded in Base64 instead
  • Consider whether large backround images (which are frequently several hundred kilobytes each) can be replaced with CSS (eg gradients)
  • Avoid pulling images from outside of your site's domain — they will not be cached in the CDN and will require a DNS lookup

Other General Suggestions

One of the final areas the guide talks about is optimizing your CSS and JS. You'll know that this is something you should be doing as you go, but you can also use audit to ensure that you're actually doing it right. As the guide says, the performance-affecting culprits are usually:

  • Unused CSS and/or JS functions being included in core files
  • Duplicate CSS and/or JS
  • Poorly optimized / inefficient JS

On this subject, consider any third-party JavaScript or applications that you pull into your site. External resources always carry a significant performance cost, they can:

  • Create multiple requests
  • Become a single point of failure, if their resources are synchronous or otherwise required for the page to load
  • Load slowly as they might not be served from a CDN (they won't be served from the CDN for your site)
  • Slow down the rendering of your site, if they are called before your site's code
  • Make calls for additional resources, thus slowing loading even further

For more information, make sure you read the guide fully. Don't forget, too, that there is a checklist you can print out and follow.