Earlier this week, I was working on optimizing an internal analysis website that uses many JSON files for its content collections. During the local development and with smaller datasets, the website was super fast, but when I received a larger dataset, I noticed that the website got very slow.
The slowness mainly came from the amount of data and the processing in React. The HTML page sizes quickly grew over 5 MB. The reason was that I retrieved the whole collection in the Astro component and passed it to the React component.
For the website I was working with Astro for building the pages, but still heavily relied on React for the data processing, searching, filtering, and more. The code for the simplified component looked like this:
|
|
To improve the performance, I had to understand Astro better and look into dynamic routing to improve the performance and lower the page sizes.
Optimizing the dataset size per page
First, I started thinking about how I could bring more logic over to Astro. Not every dashboard needs to have all the data always available. It could easily be split up into smaller datasets.
One way to achieve these smaller datasets, is to use Astro’s routing mechanism.
The idea was to create the following routes:
/dataset/
: show an overview of all the available datasets/dataset/<name>
: show the dashboard with the processed dataset by its name
To get both routes, you must use the rest parameter in the filename. In my case, this looks like this: /pages/dataset/[...name].astro
.
When using routing in Astro, you must define all the paths in the getStaticPaths()
function on the page.
|
|
importantThe
params
property is required to define the parameters of your paths. In my case, this is thename
for the dataset and corresponds to the filename.
In the above code block, you can see a parameter name
with the value set to undefined
. This value is required to get the top-level page route.
In my case, datasets are not predefined, so I needed a dynamic routing approach which I achieved as follows:
|
|
With the above code, I could get routes like:
/dataset/a
/dataset/b
Although there are pages for each dataset, there is still no data passed for each page, only the name of the dataset.
infoI tried to get the collection data outside the
getStaticPaths()
function and use it on the page and inside the routes, but this is impossible, as stated in the documentation - getStaticPaths.
Passing data to each route
To pass data to each of your routes, you need to define the props
parameter on each route.
|
|
To retrieve the data for the dataset, I only needed to add the following line: const { dataSet } = Astro.props;
.
infoThe
Dashboard
component is simplified, as the dataset analysis is moved into the Astro component.
With this logic in place, the original dataset page got split into an x-number of pages (depending on the number of JSON files and data to analyze), which are now much smaller and more performant as they only contain the data required to render the page.