-
-
Notifications
You must be signed in to change notification settings - Fork 28
Attempt to improve LCP #28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,3 @@ | ||
| <div class="absolute top-0 left-0 flex h-12 w-full justify-center p-2"> | ||
| <div class="bg-dots-light dark:bg-dots-dark h-12 w-full bg-repeat-x"></div> | ||
| <div class="bg-dots-light dark:bg-dots-dark h-12 w-full bg-repeat-x" style="content-visibility: auto;"></div> | ||
| </div> | ||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -33,9 +33,20 @@ const { image } = Astro.props; | |||||
| </a> | ||||||
|
|
||||||
| <script> | ||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
this essentially does the same thing, allows deferred non-blocking initialization
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ooh, best not to do this! Astro will bundle this script and make it a module for you. But if you add |
||||||
| import Atropos from 'atropos'; | ||||||
| // Defer Atropos initialization to after LCP | ||||||
| function initAtropos() { | ||||||
| import('atropos').then((module) => { | ||||||
| const Atropos = module.default; | ||||||
| Atropos({ | ||||||
| el: '.show-art' | ||||||
| }); | ||||||
| }); | ||||||
| } | ||||||
|
|
||||||
| Atropos({ | ||||||
| el: '.show-art' | ||||||
| }); | ||||||
| // Initialize after page load to avoid blocking LCP | ||||||
| if (document.readyState === 'complete') { | ||||||
| initAtropos(); | ||||||
| } else { | ||||||
| window.addEventListener('load', initAtropos); | ||||||
| } | ||||||
| </script> | ||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -35,6 +35,35 @@ const { imageUrl, title } = Astro.props; | |
| const canonicalURL = | ||
| Astro.props.canonicalURL ?? new URL(Astro.url.pathname, Astro.site); | ||
| const description = Astro.props.description ?? starpodConfig.description; | ||
|
|
||
| function extractDomain(url: string): string | null { | ||
| try { | ||
| return new URL(url).hostname; | ||
| } catch { | ||
| return null; | ||
| } | ||
| } | ||
|
|
||
| function getExternalDomains(): string[] { | ||
| const domains = new Set<string>(); | ||
| const siteHostname = Astro.site?.hostname; | ||
|
|
||
| // Add RSS feed domain | ||
| const feedDomain = extractDomain(starpodConfig.rssFeed); | ||
| if (feedDomain && feedDomain !== siteHostname) { | ||
| domains.add(feedDomain); | ||
| } | ||
|
|
||
| // Add image domain if it's external | ||
| const imageDomain = extractDomain(show.image); | ||
| if (imageDomain && imageDomain !== siteHostname) { | ||
| domains.add(imageDomain); | ||
| } | ||
|
|
||
| return Array.from(domains); | ||
| } | ||
|
|
||
| const externalDomains = getExternalDomains(); | ||
| --- | ||
|
|
||
| <!doctype html> | ||
|
|
@@ -92,10 +121,45 @@ const description = Astro.props.description ?? starpodConfig.description; | |
|
|
||
| <meta property="og:site_name" content={show.title} /> | ||
|
|
||
| <link rel="preload" as="image" href={show.image} /> | ||
| <!-- Preload critical resources for faster LCP --> | ||
| <link rel="preload" as="image" href={show.image} fetchpriority="high" /> | ||
|
|
||
| <Font cssVariable="--astro-font-inter" preload /> | ||
|
|
||
| <!-- DNS prefetch for external resources --> | ||
| { | ||
| externalDomains.map((domain) => ( | ||
| <> | ||
| <link rel="dns-prefetch" href={`//${domain}`} /> | ||
| <link rel="preconnect" href={`https://${domain}`} crossorigin /> | ||
| </> | ||
| )) | ||
| } | ||
|
|
||
| <!-- Prefetch for Vercel image optimization --> | ||
| {Astro.site && <link rel="preconnect" href={Astro.site.origin} />} | ||
|
|
||
| <!-- Critical CSS for LCP optimization --> | ||
| <style> | ||
| /* Critical styles for above-the-fold content */ | ||
| body { | ||
| font-family: 'Inter', system-ui, sans-serif; | ||
| margin: 0; | ||
| } | ||
|
|
||
| .atropos-inner img { | ||
| max-width: 100%; | ||
| height: auto; | ||
| display: block; | ||
| } | ||
|
|
||
| /* Ensure LCP image renders quickly */ | ||
| .show-art img { | ||
| content-visibility: auto; | ||
| contain: layout style paint; | ||
| } | ||
|
Comment on lines
+156
to
+160
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i dont think this is doing anything either. containment comes with content-visibility, and content-visibility doesnt really do much alone, needs paired with contain-intrinsic-size. i think what is needed instead is
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looking at WebPageTest traces earlier, the image already downloads as early as possible. There's a gap between download completion and paint that could maybe be tackled, but I suspect the image itself is already as optimized for loading as possible. |
||
| </style> | ||
|
|
||
| <Schema | ||
| slot="head" | ||
| item={{ | ||
|
|
@@ -133,6 +197,7 @@ const description = Astro.props.description ?? starpodConfig.description; | |
| <div class="relative z-10 mx-auto lg:min-h-full lg:flex-auto"> | ||
| <div | ||
| class="bg-light-card dark:bg-dark-card m-2 rounded-lg pt-10 pb-4 lg:pt-16 lg:pb-12" | ||
| style="contain: layout style;" | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. noise imo |
||
| > | ||
| <ShowArtwork image={show.image} /> | ||
|
|
||
|
|
@@ -167,6 +232,7 @@ const description = Astro.props.description ?? starpodConfig.description; | |
| <div class="relative mt-2 pt-16"> | ||
| <div | ||
| class="bg-gradient-light dark:bg-gradient-dark absolute top-0 right-0 left-0 z-0 h-80 w-full opacity-30" | ||
| style="content-visibility: auto;" | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. noise imo |
||
| > | ||
| </div> | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this isn't doin anything