What
PortfolioGrid.tsx:150 decides eagerness per card:
imageLoading={index < eagerCount ? 'eager' : 'lazy'}
eagerCount defaults to 0 (PortfolioGrid.tsx:51), and the only caller that overrides it is FeaturedPortfolio.tsx:489 with eagerCount={3}.
So the homepage is fine. Every gallery page is not: /events, /concerts, /nature, /portraits and /journalism render every cover with loading="lazy", including the first card, which is the LCP element on each of those pages.
loading="lazy" on an above-the-fold image is a direct LCP regression. The browser will not begin the fetch until layout has placed the element, which is precisely the delay the attribute exists to create, applied to the one image that should not have it.
Fix
Pass a small eagerCount from the gallery pages, matching however many cards are above the fold in the first row. FeaturedPortfolio already establishes the pattern with 3.
Worth checking at the same time whether the first card should also carry fetchPriority="high", which is what actually moves the needle once the image is discoverable, and whether the cover width cap is right for the rendered size.
Verifying it
The change is only meaningful if it is measured, so a before and after LCP on /events at a realistic viewport, not just a code diff. scripts/check-performance-budget.js already drives Playwright and would be the place for a guard.
Do not simply set eagerCount high. Eager loading every cover would trade one problem for a worse one on galleries with dozens of albums.
What
PortfolioGrid.tsx:150decides eagerness per card:eagerCountdefaults to0(PortfolioGrid.tsx:51), and the only caller that overrides it isFeaturedPortfolio.tsx:489witheagerCount={3}.So the homepage is fine. Every gallery page is not:
/events,/concerts,/nature,/portraitsand/journalismrender every cover withloading="lazy", including the first card, which is the LCP element on each of those pages.loading="lazy"on an above-the-fold image is a direct LCP regression. The browser will not begin the fetch until layout has placed the element, which is precisely the delay the attribute exists to create, applied to the one image that should not have it.Fix
Pass a small
eagerCountfrom the gallery pages, matching however many cards are above the fold in the first row.FeaturedPortfolioalready establishes the pattern with 3.Worth checking at the same time whether the first card should also carry
fetchPriority="high", which is what actually moves the needle once the image is discoverable, and whether the cover width cap is right for the rendered size.Verifying it
The change is only meaningful if it is measured, so a before and after LCP on
/eventsat a realistic viewport, not just a code diff.scripts/check-performance-budget.jsalready drives Playwright and would be the place for a guard.Do not simply set
eagerCounthigh. Eager loading every cover would trade one problem for a worse one on galleries with dozens of albums.