Skip to content

feat: [performance improvement] optimize tag parsing in static pages - #369

Open
anyulled wants to merge 1 commit into
mainfrom
perf/optimize-tag-pages-static-gen-3422968904570674029
Open

feat: [performance improvement] optimize tag parsing in static pages#369
anyulled wants to merge 1 commit into
mainfrom
perf/optimize-tag-pages-static-gen-3422968904570674029

Conversation

@anyulled

@anyulled anyulled commented Aug 4, 2026

Copy link
Copy Markdown
Owner

💡 What: Replaced nested allTalks.flatMap().find() iterations in app/[year]/tags/[tag]/page.tsx and app/2026/tags/[tag]/page.tsx with early-exit array traversals (find and some). Hoisted the decodedTag.toLowerCase() out of inner loops. Reused the filteredTalks object to derive the display tag rather than repeating full searches.

🎯 Why: During generateStaticParams and tag page static generation, performing .flatMap() on the entire schedule across all talks generates significant intermediate arrays in memory. Doing this for every single tag causes O(N^2) memory allocations and unnecessary garbage collection overhead, heavily slowing down Next.js static generation.

📊 Impact: Reduces intermediate array memory allocations during static page build times for tag pages by completely bypassing .flatMap() calls. Decreases string .toLowerCase() transformation operations significantly.

🔬 Measurement: Verify by executing npm run build and checking the build time improvements and checking there are no errors inside tag generation (Route: /[year]/tags/[tag]). Run unit tests via npm run test to guarantee functionality remains unchanged.


PR created automatically by Jules for task 3422968904570674029 started by @anyulled

Summary by CodeRabbit

  • Bug Fixes
    • Improved tag matching on tag pages, including year-specific pages, for more consistent results.
    • Tag labels now preserve the original capitalization when available, while matching remains reliable for different casing or encoded values.
    • Added a clear fallback label when no matching tag is found.
  • Performance
    • Reduced unnecessary processing during tag matching to help page generation run more efficiently.

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
@google-labs-jules

Copy link
Copy Markdown
Contributor

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@gemini-code-assist

Copy link
Copy Markdown
Contributor

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e51d4ac8-b5b1-4122-9810-5c008e5c3934

📥 Commits

Reviewing files that changed from the base of the PR and between 557a21c and 48046ea.

📒 Files selected for processing (3)
  • .jules/bolt.md
  • app/2026/tags/[tag]/page.tsx
  • app/[year]/tags/[tag]/page.tsx

📝 Walkthrough

Walkthrough

Both tag routes normalize decoded tags once for matching. Metadata and page rendering preserve the original tag text from matching talks, with formatted fallbacks when no match exists. A guidance note recommends early-exit iteration instead of flatMap().find().

Changes

Tag lookup updates

Layer / File(s) Summary
Metadata tag matching
app/2026/tags/[tag]/page.tsx, app/[year]/tags/[tag]/page.tsx
Metadata generation matches normalized tags and uses the original matching tag text when available.
Page filtering and display labels
app/2026/tags/[tag]/page.tsx, app/[year]/tags/[tag]/page.tsx, .jules/bolt.md
Page rendering reuses the normalized tag, filters talks, and derives the display label from the first matching talk. The guidance documents early-exit iteration patterns.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

Poem

A rabbit hops through tags so neat,
One normalized path beneath each feat.
Original names now proudly show,
While early exits help flows go.
No flattened trails slow down the beat.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the performance improvement to tag parsing in static pages.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch perf/optimize-tag-pages-static-gen-3422968904570674029

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed: dependency version conflict. Check your lock file or package.json.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Optimize tag matching for static tag pages (avoid flatMap allocations)

✨ Enhancement 📝 Documentation 🕐 20-40 Minutes

Grey Divider

AI Description

• Avoid flatMap(getTagsFromTalk) during tag page metadata/page generation to reduce build-time
 allocations.
• Normalize decoded tag once and use early-exit traversal (find/some) for tag matching.
• Document the static-generation performance learning and preferred early-exit patterns.
Diagram

graph TD
  A(("Next.js build")) --> B["generateStaticParams"] --> E["getTalks(year)"] --> F["Session groups"]
  A --> C["generateMetadata"] --> E --> G["Early-exit tag match"]
  A --> D["Tag page render"] --> E --> H["Filter talks by tag"] --> G
  G --> I["displayTag (original casing)"]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Build a normalized tag index once per year
  • ➕ Single traversal to produce both filteredTalks and displayTag for all tags
  • ➕ Could reduce repeated scanning across generateStaticParams/metadata/page
  • ➕ Central place to unit test tag normalization and display casing rules
  • ➖ Larger refactor: requires shared module + careful caching semantics in Next.js build/SSG
  • ➖ More moving parts than the current localized change
2. Extract shared helper for tag normalization/matching
  • ➕ Removes duplicated logic between app/[year]/... and app/2026/...
  • ➕ Reduces risk of future divergence in casing/slug rules
  • ➖ Small up-front refactor; not strictly necessary for the performance win
  • ➖ Still scans talks per invocation (just with less duplication)
3. Use `getAllTalks(year)` from hooks for consistency
  • ➕ Centralizes the sessionGroups.flatMap(...sessions) step
  • ➕ Reduces boilerplate in route files
  • ➖ Does not address the main allocation hotspot (tag flatMap) by itself
  • ➖ Minor behavioral coupling to hook-level caching

Recommendation: Current approach is a good low-risk optimization: it removes the largest avoidable allocation (allTalks.flatMap(getTagsFromTalk)) while keeping route logic straightforward and preserving ordering semantics (first matching talk/tag drives display casing). If further build-time performance work is needed, the next step would be a per-year tag index to avoid repeated scans across SSG entry points; otherwise consider extracting a shared helper to prevent the duplicated matching logic from drifting.

Files changed (3) +27 / -10

Enhancement (2) +22 / -10
page.tsxAvoid tag 'flatMap' allocations and reuse normalized tag in 2026 route +11/-5

Avoid tag 'flatMap' allocations and reuse normalized tag in 2026 route

• Hoists 'decodedTag.toLowerCase()' into 'normalizedDecodedTag' and replaces 'allTalks.flatMap(getTagsFromTalk).find(...)' with an early-exit scan ('find' + 'some'). Reuses the already-filtered talk list to derive 'displayTag' without re-scanning all talks/tags.

app/2026/tags/[tag]/page.tsx

page.tsxOptimize tag matching in generic year tag route +11/-5

Optimize tag matching in generic year tag route

• Replaces 'flatMap(getTagsFromTalk).find(...)' with early-exit traversal using 'find'/'some' and hoists lowercase normalization outside inner loops. Derives 'displayTag' from the first matched talk in 'filteredTalks' to avoid repeating full searches.

app/[year]/tags/[tag]/page.tsx

Documentation (1) +5 / -0
bolt.mdDocument static-generation tag parsing performance lesson +5/-0

Document static-generation tag parsing performance lesson

• Adds a dated entry capturing the learning that nested traversals like 'flatMap().find()' can cause heavy allocations during Next.js static generation. Recommends early-exit traversal patterns ('for...of', 'some') to reduce GC pressure.

.jules/bolt.md

@qodo-code-review

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider

Great, no issues found!

Qodo reviewed your code and found no material issues that require review

Grey Divider

To customize comments, go to the Qodo configuration screen, or learn more in the docs.

Qodo Logo

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant