Skip to content

perf(bundle): cut 377 kB gzip from every route's first load - #922

Open
thostetler wants to merge 4 commits into
adsabs:masterfrom
thostetler:bundle-size-pass-1
Open

perf(bundle): cut 377 kB gzip from every route's first load#922
thostetler wants to merge 4 commits into
adsabs:masterfrom
thostetler:bundle-size-pass-1

Conversation

@thostetler

@thostetler thostetler commented Aug 27, 2026

Copy link
Copy Markdown
Member

_app had grown to nearly 1 MB gzip and accounted for more than half of the client bundle. This pass reduced the shared baseline to about 620 kB.

The main improvements were:

Deep-importing Layout instead of using the barrel export, preventing the visualization/chart stack from being included globally.
Moving shared store constants into their own module, removing an unnecessary dependency on search/component code.
Fixing pnpm analyze so bundle analysis works correctly.
Adding PR reporting for per-route bundle-size changes.

A few pages grow slightly because their layout code now loads with the route rather than globally.

This is the first optimization pass.

@thostetler
thostetler requested a review from shinyichen August 27, 2026 13:24
@codecov

codecov Bot commented Aug 27, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 68.0%. Comparing base (131396b) to head (cbc4ffa).

Additional details and impacted files
@@           Coverage Diff            @@
##           master    #922     +/-   ##
========================================
- Coverage    68.0%   68.0%   -0.0%     
========================================
  Files         359     360      +1     
  Lines       42552   42575     +23     
  Branches     2269    2267      -2     
========================================
+ Hits        28917   28922      +5     
- Misses      13586   13604     +18     
  Partials       49      49             
Files with missing lines Coverage Δ
src/store/slices/appMode.ts 100.0% <100.0%> (ø)
src/utils/common/search-mode-constants.ts 100.0% <100.0%> (ø)
src/utils/common/searchMode.ts 98.5% <100.0%> (-0.1%) ⬇️

... and 4 files with indirect coverage changes

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Import `Layout` directly in `_app` instead of through the Layout barrel.

The barrel also exported visualization components, which caused the chart
stack to be included in every route's shared bundle. The direct import removes
roughly 370 kB gzip from the shared first load.
Move search mode constants into a dependency-free module.

This prevents the global store import from pulling search facet and lucene
parser code into every route, reducing the shared first-load bundle and
removing a store-to-components dependency.
@thostetler
thostetler marked this pull request as ready for review August 27, 2026 15:00
Copilot AI lite review requested due to automatic review settings August 27, 2026 15:00

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Risk summary: Medium. The PR meaningfully changes the client bundle composition (_app import path + shared search-mode constants), updates build tooling (@next/bundle-analyzer, pnpm analyze), and adds new CI workflows/scripts; the runtime impact should be positive, but CI/reporting plumbing changes carry some regression risk.

Changes:

  • Reduce global client baseline by deep-importing Layout in _app (avoids pulling VizPageLayout/chart stack into every route via the barrel).
  • Split SearchMode + related constants into a lightweight module to avoid dragging heavier search-mode dependencies into the store boundary.
  • Add bundle-size measurement + PR reporting (new Node scripts + two GitHub Actions workflows), and adjust analyzer wiring.

Reviewed changes

Copilot reviewed 10 out of 12 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/utils/common/searchMode.ts Re-exports search-mode constants from a new lightweight module while keeping existing call sites stable.
src/utils/common/search-mode-constants.ts New module holding SearchMode and ADS-compat constants without heavy imports.
src/store/slices/appMode.ts Switches store import to the lightweight constants module.
src/pages/_app.tsx Deep-imports Layout to avoid barrel side-effects pulling chart code into the shared baseline.
scripts/bundle-sizes.mjs New script to generate a per-route “first load” size manifest from build artifacts.
scripts/compare-bundle-sizes.mjs New script to diff size manifests into a markdown report for PR commenting.
package.json Updates analyze command and adds bundle:sizes / bundle:compare scripts.
next.config.mjs Fixes bundle-analyzer wiring to use the factory form with enabled.
.github/workflows/bundle-size.yml New workflow to build, measure, compare, and upload bundle-size artifacts.
.github/workflows/bundle-size-comment.yml New workflow to post a sticky PR comment using artifacts (without checking out PR code).
.gitignore Ignores generated bundle-size report artifacts.
pnpm-lock.yaml Lockfile updates including @next/bundle-analyzer bump.
Files not reviewed (1)
  • pnpm-lock.yaml: Generated file

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread scripts/compare-bundle-sizes.mjs Outdated
lines.push('No baseline found for the target branch — reporting absolute sizes only.', '');
lines.push('| Route | First load (gzip) |', '| --- | ---: |');
lines.push(`| **Shared by all** | **${kb(head.shared.gzip)}** |`);
for (const [route, size] of Object.entries(head.pages).sort()) {
Fix the bundle analyzer configuration so `pnpm analyze` produces webpack
reports correctly under Next 16.

Upgrade the analyzer, ensure `ANALYZE=true` reaches `next build`, and explicitly
use webpack. Add scripts for generating and comparing per-route gzip sizes.
Report per-route first-load gzip changes on pull requests.

Master builds publish the bundle-size baseline, while PR builds only measure
the current branch. Measurement and commenting use separate workflows so fork
PRs can remain read-only while the base repository posts the sticky comment.

Also publishes the report to the job summary and supports an optional failure
threshold for shared bundle growth.
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