Whitepaper: Improving web performance for an Nextjs powered ecommerce platform
Wiseland Engineering provides deep consulting services to ecommerce companies to improve their tech stack and help them adapt to the modern web technologies.
In this whitepaper we discuss how we achieved this goal for one of our ecommerce clients who sells shoes and outdoor gear on their ecommerce platform.
When our client engaged us they had a fairly good functional website that saw over 250K distinct users in North America and resulted into around 1K sales each day. However their website was fairl bloated and took several seconds to load. Also their competitiors were beating them in SEO as well and they were seeing a decline in their search engine traffic.
Their engineering team figured that they need to do better on web vitals and other search enginer paramters while giving a much better experience to their users. Towards this goal they were willing to even reachitect their front end pipeline.
By the end of the exercise, our customer's cloud costs were down by 15%, SEO score on lighthouse was 100% and performance score was 95%. This was achieved using minimal archiectal changes and zero disruption to their business. In subsequent sections we explain how we did it.
An ecommerce site is very different from social media and other social sites because the data on a product listing page does not change very often and showing somewhat stale data is not a problem. However the page not loading quickly is a big problem.
NextJS supports Server Side Rendering and Static Site Generation out of the box. Our client had not thought deeply about these two and had left the decision to the individual teams to decide which of these two options to use.
Server Side Rendering vs Static Site Generation is an important tradeoff that has huge implication for web performance. In SSR, the page is generated everytime user requests it. In SSG, the page is build during build time and simply sent as as response for every request.
As you can guess, the SSR pages will always show latest data but will take longer to respond where as SSG pages will respond super fast but could show stale data.
After several meetings with the leadership we convinced our client that SSG is worth considering for all their pages except very handful of pages.
Our client had over 4000 distinct products leading to 4000 distinct product pages. Each of these products had variants such as colors and sizes which increased this count to around 32000.
Our client had this setup as SSR pages where the data is fetched per request and the page was rendered. They did this because some of the data like product titles and availability of inventory could change few times a day. The other components on the page were user reviews and ratings, related products and products you might like sections where were very specific to the usr and depended on user cookies or search history.
What our client did not know however was tht it is possible to isolate such dynamic components on a page using Suspense boundary so only those components get generated on per request basis. Since these components were irrelevant to SEO there was not need to render them on server.
We statically generated all the product details pages including even use ratings and reviews section. "Product availability" and "Products you might like" components alone were isolated using the suspense boundary.
This vastly reduces traffic from front end servers to the backend servers. Thus our client could reduce the number of backend servers by around 30%.
The disadvantage of the SSG was that everytime the business analysts changed a product description or image, this was not automatically available to the end user. It had to wait until the next build.
This problem was solved using a build train. 32K pages werent too hard to build in matter of seconds and pushing a new build every 6 hours worked sufficiently well for our client.
The harder part however was solving the A/B testing that happens in any ecommerce site. For example you want to check which change lead to greater conversions. Some of the tests are at code level where you modify the code itself based on a flag where as some changes are purely at code level.
This was enabled using middleware. NextJS has a concept of middleware where we intercept HTTP request in flight and modify them. We were able to create a middleware what would divide the incoming requests into experiment buckets and redirect the user to appropriate statically generated page.
The user classification into bucket was generated by generating a cookie on the fist request.
Example code for this can be seen here.
WebP is a newer image format that offers a number of advantages over PNG. These advantages include:
- Smaller file sizes: WebP images are typically 25-34% smaller than comparable PNG images. This can lead to faster loading times for web pages, which can improve user experience.
- Lossless and lossy compression: WebP supports both lossless and lossy compression. Lossless compression means that no image data is lost, while lossy compression means that some image data is discarded to reduce the file size. WebP's lossy compression is more efficient than PNG's, so WebP images can be smaller while still maintaining good image quality.
- Transparency: WebP supports transparency, which means that images can have a transparent background. This is useful for images that need to be placed on top of other images or text.
- Animation: WebP supports animation, which means that images can be animated. This is useful for creating animated GIFs or other animated images. Overall, WebP offers a number of advantages over PNG, including smaller file sizes, lossless and lossy compression, transparency, and animation. If you are looking for a way to reduce the file size of your images without sacrificing image quality, then WebP is a good option.
After this our client saw a reduction of 20% in bandwidth usage.
Our client was not using PurgeCSS with tailwindcss. We enabled purging the CSS classes that were not being used. This not only reduced the CSS payload but also improved the Web Vitals like LCP.
One of the reasons why page feels slugish is if you that too many DOM items. We worked with our client to audit all their component DOM tree and to reduce its complexity. We also put in place suffient linting mechanism to detect needless DOM nesting during compiled time.
Whenever product urls are shared on social media, the social media platform searches for "og:image" meta tag to display the image representing your page. Our client use to set some of the product images per product. However we changed this to a simple endpoint
/og/product/:id. The NexJS endpoint to generate an image specific to the social media platform by looking at the referrer portion of the http request. This image would have proper dimensions as required by the social media platform, client's clear branding and additional information such as sale, price drop etc.
You can see some exmaple code here.
Post this our client's product details page was loading 50% faster. The Web vital score was 95 and SEO score 100%. We were told that the client saw a 5% uptick in conversions as well as a result of this which mean 5% increase in revenue. As a bonus, the cost of infrastructure reduced significantly too by around 15%.
Whether you are a large ecommerce company or a small content site, you can always write to us for consultation and we can help you improve your web site performance. Send your website link to
firstname.lastname@example.org for some advice on how we can help your web site perform better.