Nov 20, 2023
Sitecore JSS (JavaScript Services) and Next.js are powerful frameworks for building modern web applications. They offer a robust solution for developing dynamic and interactive websites. However, as with any technology, there are observations and challenges that arise while working with these frameworks.
In this blog post, we will discuss some of the key items we have found when doing JSS plus Next.js Sitecore implementations related to our ability to affect the size of the initial HTML payload and JavaScript bundle size.
Increase in Size of Initial HTML Payload:
One of the noticeable effects of using Sitecore JSS and Next.js is the increase in the size of the initial HTML payload. This increase occurs because the layout service JSON is embedded as page props in a script element, identified as __NEXT_DATA__
. This JSON is essential for rehydration on the client side, allowing React to attach event handlers to DOM elements.
<script id="__NEXT_DATA__" type="application/json"></script>
Our tests found that this embedded JSON accounted for a significant portion of the HTML document's size, sometimes exceeding 50%, which can lead to delays in downloading the initial HTML document. It's important to understand that, in the case of Sitecore JSS, this JSON is embedded because it is needed to pass the layout service data as props to the page. The more components on a page with data sources, the larger this layout service JSON becomes, increasing the time to download the initial document. A potential solution to this is to transform the layout service data into a format that is less heavy and sufficient for rendering the page and pass it as props for the page.
The presence of the__NEXT_DATA__
element raises questions, and you can find discussions on this topic within the Next.js community here and here.
Javascript Bundle Size for Components:
While the increased HTML size may be a minor concern from a bandwidth perspective, JavaScript bundle size is often the more critical factor. The complexity of your web experience, including features like carousels, animations, and video players, can significantly impact the size of the JavaScript libraries in the client bundle. In Sitecore JSS with Next.js, there are specific factors that can exacerbate this issue:
[[...path]].tsx
that is catch all for all the pages to be generated through SSGimport { componentFactory, editingComponentFactory } from 'temp/componentFactory';
statements in the[[...path]].tsx
- a set of dynamically generated import statements to import all the components into the
componentFactory
similar to
import * as CdpPageView from 'src/components/CdpPageView';
import * as ColumnSplitter from 'src/components/ColumnSplitter';
import * as Container from 'src/components/Container';
import * as ContentBlock from 'src/components/ContentBlock';
import * as FEaaSWrapper from 'src/components/FEaaSWrapper';
import * as Image from 'src/components/Image';
import * as LinkList from 'src/components/LinkList';
These three things together result in bundles that have all the components bundled for every page, whether they need it or not.
While this approach may be developer-friendly and accommodate the dynamic nature of components, it's not ideal from the end user's perspective, as they end up downloading numerous components that aren't present on the page. As your site grows, so does the bundle size.
Javascript Bundle Size for node_modules:
The same argument applies to the bundle containing all the node_modules for your site. It forms another significant bundle, contributing to the overall bundle size.
Code Splitting and Tree Shaking
To alleviate the problems with bundle sizes, developers often turn to code splitting and tree shaking. However, the applicability of these techniques is influenced by the project's structure.
- Code splitting in Next.js is performed automatically based on the pages in the "pages" directory. However, the way components are imported in the componentFactory and imported into pages hinders effective code splitting.
- Tree shaking helps remove unused code, and is more effective when dealing with third-party packages and assuming they are treeshakable. In new projects where components are built from scratch, there is less likelihood of unused code in the project. Even with tree shaking, you may still encounter large JavaScript bundle sizes.
Tools to Analyze Bundles
To address bundle size concerns, you can use tools like "@next/bundle-analyzer" to analyze your bundle and identify modules contributing to the bloat. Additionally, the “Import Cost” extension in Visual Studio Code and BundlePhobia’s sizing tool are useful resources for evaluating the impact of specific packages on your bundle size.
As we continue to work with Sitecore JSS and Next.js, it's essential to be aware of the challenges related to initial HTML payload size and JavaScript bundle size. While these challenges exist, the community is actively exploring advancements in the Next.js space, such as React Server components and streaming. These innovations may offer solutions to reduce bundle sizes, resulting in improved page speed insights scores and a better user experience.
For more information, this great video by Addy Osmani explains the cost of Javascript in 2023.
Related Insights
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.