Skip to content

Conversation

@stephenliang
Copy link
Member

@stephenliang stephenliang commented Nov 20, 2025

This PR refactors the data loading of the activity catalog to optimize its page size. Currently, the activity catalog is 3mb uncompressed (431kb compressed) which severely degrades performance and incurs bandwidth costs.

Background

The activity catalog uses a full-text search database called Orama. To eliminate the need to fetch data asynchronously, the original implementation serialized the Orama database to json on the server side and passed back to the client which deserializes it. Additionally, the server pre-rendered all 150+ activities and added it to the HTML response. The net effect is that all activity renders, the serialized database (which contains the same activities) were added to the payload.

Optimization

To optimize this, only the first 8 activities (the first two rows on the largest screen size) will be serialized (instead of all 100+ activities). The client will be responsible for loading the database asynchronously and populating the remaining activities. This optimization effectively allows the perceived performance to be high by pre-rendering only content above the fold. The remaining activities will be rendered in asynchronously after the page has loaded.

Perforamnce Gains

In testing, the current page is approximately 3mb uncompresed and 431kb compressed. It has a lighthouse performance score of 58.

After these changes, the page size is 972kb uncompressed and 120kb compressed (a 3x improvement). It has a lighthouse performance score of 72.

Before

Screenshot From 2025-11-20 14-23-21 Screenshot From 2025-11-20 14-24-06

After

Screenshot From 2025-11-20 14-41-43 Screenshot From 2025-11-20 14-44-20

@github-actions
Copy link

github-actions bot commented Nov 20, 2025

🖼️ Storybook Visual Comparison Report

✅ No Storybook eyes differences detected!

@stephenliang stephenliang force-pushed the stephen/optimize-activity-catalog branch 3 times, most recently from 9ba4228 to 9b3e961 Compare November 20, 2025 23:10
This PR refactors the data loading of the activity catalog to optimize
its page size. Currently, the activity catalog is 3mb uncompressed
(431kb compressed) which severely degrades performance and incurs
bandwidth costs.

\## Background

The activity catalog uses a full-text search database called Orama. To
eliminate the need to fetch data asynchronously, the original
implementation serialized the Orama database to json on the server side
and passed back to the client which deserializes it. Additionally, the
server pre-rendered all 150+ activities and added it to the HTML
response. The net effect is that all activity renders, the serialized
database (which contains the same activities) were added to the payload.

\## Optimization

To optimize this, only the first 8 activities (the first two rows on the
largest screen size) will be serialized (instead of all 100+
activities). The client will be responsible for loading the database
asynchronously and populating the remaining activities. This
optimization effectively allows the perceived performance to be high by
pre-rendering only content above the fold. The remaining activities will
be rendered in asynchronously after the page has loaded.

\## Perforamnce Gains

In testing, the current page is approximately 3mb uncompresed and
431kb compressed. It has a lighthouse performance score of 58.

After these changes, the page size is 972kb uncompressed and 120kb
compressed (a 3x improvement). It has a lighthouse performance score of
72.
@stephenliang stephenliang force-pushed the stephen/optimize-activity-catalog branch from 9b3e961 to 9109ed3 Compare November 20, 2025 23:15
@sureshc
Copy link
Contributor

sureshc commented Nov 21, 2025

What's the experience if the student scrolls past the first 8 Activities before the asynchronous fetch has completed?

@stephenliang
Copy link
Member Author

What's the experience if the student scrolls past the first 8 Activities before the asynchronous fetch has completed?

There is no async fetch, it's async processing of the client-side code to generate the remaining 150 activities. The user would have to have a very low powered device to have this be calculated before this processing is complete. However, I do think the UX would be improved by adding a loading indicator which indicates that processing is occurring to render the remaining activities.

@stephenliang
Copy link
Member Author

Updated PR to include loading state

Screencast.From.2025-11-21.09-13-44.webm

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants