Skip to content
Closed
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
2 changes: 1 addition & 1 deletion src/components/Dots.astro
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>
Copy link
Collaborator

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

</div>
19 changes: 15 additions & 4 deletions src/components/ShowArtwork.astro
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,20 @@ const { image } = Astro.props;
</a>

<script>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<script>
<script type="module">

this essentially does the same thing, allows deferred non-blocking initialization

Copy link
Contributor

@delucis delucis Oct 22, 2025

Choose a reason for hiding this comment

The 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 type="module" yourself, Astro assumes you're in charge and doesn't process it at all, which would break the import.

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>
68 changes: 67 additions & 1 deletion src/layouts/Layout.astro
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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
Copy link
Collaborator

Choose a reason for hiding this comment

The 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 fetchpriority="high" on the image in the HTML + a preload tag if we want. here's some docs https://developer.mozilla.org/en-US/blog/fix-image-lcp/

Copy link
Contributor

Choose a reason for hiding this comment

The 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={{
Expand Down Expand Up @@ -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;"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

noise imo

>
<ShowArtwork image={show.image} />

Expand Down Expand Up @@ -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;"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

noise imo

>
</div>

Expand Down