Perf: defer third party widgets#1045
Merged
Merged
Conversation
Both Senja embeds rendered below the fold but fetched their loader scripts eagerly on page parse — ~430 KB and ~1.5 s of JS plus a render-blocking Google Fonts (Inter) request on the initial path. Move each loader URL onto a `data-senja-src` attribute and inject it via a shared IntersectionObserver (200px rootMargin), mirroring the lazy feature-video pattern in Feature.astro. Reserve min-height on each embed so the late-loading widget does not shift content (CLS stays ~0). Verified via Lighthouse: zero senja.io / google-fonts requests on initial load; CLS ~0. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replace Intercom's window.load trigger with a first-interaction trigger (scroll/mousemove/touchstart/keydown/click) plus a requestIdleCallback idle fallback (5s backstop), so the ~344KB widget no longer competes for network and main thread during the critical initial load. Passive readers still get the launcher via the idle fallback. Window-level guards (__intercomArmed/__intercomLoaded) keep it from double-loading across Astro view-transition navigations. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Antoine reported the landing page felt slow — usable only once the Intercom bubble appeared. That's the tell: the page looks done fast but stays unresponsive while third-party scripts fire on
window.load.Findings (Lighthouse, mobile/throttled)
Page content is healthy; third-party is the cost. Speed Index 2.1 s but TTI 11.7 s — the "looks done but isn't" gap.
window.load— the worst moment for interactivity.Solution
fec0cdf): inject loaders via a sharedIntersectionObserver(200px margin) only as widgets near the viewport; reservemin-heightso CLS stays ~0.ac0d33a): replace thewindow.loadtrigger with first-interaction + arequestIdleCallbackidle fallback (5 s backstop). Passive readers still get the launcher via idle; window-level guards prevent double-loading across view transitions.Verification
senja.io/ Google-Fonts requests on initial load; CLS ~0.build,lint,format:check,typecheck,knipall pass.🤖 Generated with Claude Code