Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .jules/bolt.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,8 @@

**Learning:** In Next.js/React applications, when grouping items (like schedules or talks) into a `Map` where the values are arrays, using the array spread operator `[...existing, item]` inside a loop (like `forEach` or `map`) causes amortized O(N^2) memory allocations and unnecessary Garbage Collection overhead.
**Action:** Always use `.push()` on the existing array reference if the data structure permits local mutation. For strict ESLint configurations enforcing `no-restricted-syntax`, extract the existing array, push to it, and handle the fallback elegantly (`if (!existing) { map.set(key, [item]); } else { existing.push(item); }`).

## 2024-05-19 - Parallelize next build generateStaticParams

**Learning:** When `generateStaticParams` uses a sequential `for...of` loop to iterate over multiple parameters (like event years) and fetches external data, it forces Next.js to wait sequentially for each fetch to finish before starting the next. This creates a significant, O(N) performance bottleneck during the build step.
**Action:** Replace sequential `for...of` loops with `await Promise.all(items.map(async (item) => { ... }))`. By mapping each item into an async data-fetching promise, Next.js executes the requests concurrently, resulting in significantly faster build times. Always make sure to preserve per-item `try/catch` fallbacks to avoid failing the entire batch if a single item errors.
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.

medium

The recommendation to 'always preserve per-item try/catch fallbacks to avoid failing the entire batch' contradicts the repository's general rule. For build-time data fetching, we want failures to halt the build so we do not deploy incomplete pages. Please update this documentation to recommend using strict mode for build-time data fetching.

References
  1. Data fetching functions used during the build process (e.g., for sitemap generation) should include a 'strict' mode that throws an error on failure. This ensures that data fetching problems cause the build to fail, preventing the deployment of incomplete pages.

26 changes: 13 additions & 13 deletions app/[year]/talks/[talkId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,21 +29,21 @@ interface TalkDetailProps {

export async function generateStaticParams() {
const years = getArchivedEditions();
const params = [];

for (const year of years) {
try {
const sessionGroups = await getTalks(year);
const allTalks = sessionGroups.flatMap((group) => group.sessions);
for (const talk of allTalks) {
params.push({ year, talkId: talk.id });

const nestedParams = await Promise.all(
years.map(async (year) => {
try {
const sessionGroups = await getTalks(year);
const allTalks = sessionGroups.flatMap((group) => group.sessions);
return allTalks.map((talk) => ({ year, talkId: talk.id }));
} catch (error) {
console.warn(`Failed to fetch talks for year ${year}:`, error);
return [];
}
} catch (error) {
console.warn(`Failed to fetch talks for year ${year}:`, error);
}
}
})
Comment on lines +34 to +43
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.

high

According to the repository's general rules, data fetching functions used during the build process (such as generateStaticParams) should run in strict mode. This ensures that any data fetching failure correctly halts the build, preventing the deployment of incomplete pages with missing talks. Swallowing the error and returning an empty array allows the build to succeed silently with incomplete data.

    years.map(async (year) => {
      const sessionGroups = await getTalks(year, { strict: true });
      const allTalks = sessionGroups.flatMap((group) => group.sessions);
      return allTalks.map((talk) => ({ year, talkId: talk.id }));
    })
References
  1. Data fetching functions used during the build process (e.g., for sitemap generation) should include a 'strict' mode that throws an error on failure. This ensures that data fetching problems cause the build to fail, preventing the deployment of incomplete pages.

);

return params;
return nestedParams.flat();
}

export async function generateMetadata({ params }: TalkDetailProps): Promise<Metadata> {
Expand Down
Loading