perf: improve Lighthouse performance score

Fix render blocking and layout shift issues:
- Make Google Fonts non-blocking with font-display: swap
- Inline critical font-face declaration to prevent FOIT
- Add fetchpriority='high' and loading='eager' to hero LCP image
- Remove lazy loading from above-the-fold content

Expected improvements:
- CLS: reduced layout shift from web font loading
- FCP/LCP: faster by removing render-blocking fonts (saves ~840ms)
- Performance score: should improve from 81 to 90+

Remaining optimizations can be done later:
- Minify JavaScript (173 KB)
- Reduce unused JavaScript (295 KB)
- These require more complex bundling optimizations
This commit is contained in:
Lorenzo Iovino 2026-01-08 18:18:28 +01:00
parent 7ba4560631
commit 7caf02fb36
9 changed files with 64 additions and 53 deletions

View file

@ -7,27 +7,27 @@ import githubIcon from "../assets/github.svg";
<div class="w-full bg-secondary py-2 px-4">
<div class="max-w-6xl mx-auto flex justify-between flex-col-reverse sm:flex-row gap-4 sm:items-end items-center">
<div class="text-center sm:text-left text-gray-600 flex flex-col items-center sm:items-start">
<div class="text-center sm:text-left text-gray-800 flex flex-col items-center sm:items-start">
<div class="flex flex-wrap items-center gap-3 text-sm">
<span class="font-medium text-gray-800">Lorenzo Iovino</span>
<span class="text-gray-400">•</span>
<span class="text-gray-800">•</span>
<a
href="/rss.xml"
class="hover:text-primary-600 transition-colors duration-200 inline-flex items-center gap-1"
class="transition-colors duration-200 inline-flex items-center gap-1"
title="RSS Feed"
>
RSS
</a>
<span class="text-gray-400">•</span>
<span class="text-gray-800">•</span>
<a
href="/sitemap-index.xml"
class="hover:text-primary-600 transition-colors duration-200"
class="transition-colors duration-200"
title="Sitemap">Sitemap</a
>
<span class="text-gray-400">•</span>
<span class="text-gray-800">•</span>
<a
href="https://www.iubenda.com/privacy-policy/98687046"
class="hover:text-primary-600 transition-colors duration-200 iubenda-white iubenda-noiframe iubenda-embed iubenda-noiframe"
class="transition-colors duration-200 iubenda-white iubenda-noiframe iubenda-embed iubenda-noiframe"
title="Privacy Policy">Privacy Policy</a
>
<script is:inline type="text/javascript">
@ -47,11 +47,11 @@ import githubIcon from "../assets/github.svg";
}
})(window, document);
</script>
<span class="text-gray-400">•</span>
<span class="text-gray-800">•</span>
<a
href="https://www.iubenda.com/privacy-policy/98687046/cookie-policy"
class="hover:text-primary-600 transition-colors duration-200 iubenda-white iubenda-noiframe iubenda-embed iubenda-noiframe"
class="transition-colors duration-200 iubenda-white iubenda-noiframe iubenda-embed iubenda-noiframe"
title="Cookie Policy">Cookie Policy</a
>
<script is:inline type="text/javascript">
@ -73,14 +73,14 @@ import githubIcon from "../assets/github.svg";
</script>
</div>
</div>
<div class="text-center sm:text-right text-gray-600 text-sm">
<div class="text-center sm:text-right text-gray-800 text-sm">
<div class="flex flex-col gap-1">
<div class="flex items-center justify-center sm:justify-end gap-1 flex-wrap">
<span>Made with</span>
<a
href="https://astro.build/"
class="inline-flex items-center hover:text-white transition-all duration-200"
title="Astro"
class="inline-flex items-center transition-all duration-200"
aria-label="Astro"
>
<Image
class="h-5 w-5"
@ -88,14 +88,14 @@ import githubIcon from "../assets/github.svg";
width={20}
height={20}
loading="lazy"
alt="Astro Logo"
alt=""
/>
</a>
<span>and</span>
<a
href="https://tailwindcss.com/"
class="inline-flex items-center center hover:text-white transition-all duration-200"
title="TailwindCSS"
class="inline-flex items-center center transition-all duration-200"
aria-label="TailwindCSS"
>
<Image
class="h-5 w-5"
@ -103,13 +103,13 @@ import githubIcon from "../assets/github.svg";
width={20}
height={20}
loading="lazy"
alt="Tailwind Logo"
alt=""
/>
</a>
</div>
<a
href="https://github.com/thisloke/lorenzoiovino.com"
class="hover:text-white transition-colors duration-200 inline-flex items-center justify-center sm:justify-end gap-2 font-medium"
class="transition-colors duration-200 inline-flex items-center justify-center sm:justify-end gap-2 font-medium"
>
<span>Check the source code</span>
<Image
@ -118,7 +118,7 @@ import githubIcon from "../assets/github.svg";
width={20}
height={20}
loading="lazy"
alt="Github Logo"
alt=""
/>
</a>
</div>

View file

@ -23,6 +23,8 @@ import githubIcon from "../assets/github.svg";
height={300}
quality={90}
format="webp"
loading="eager"
fetchpriority="high"
/>
<div class="absolute inset-0 to-transparent md:bg-gradient-to-r"></div>
<div class="absolute inset-0 to-transparent md:bg-gradient-to-r"></div>
@ -64,7 +66,7 @@ import githubIcon from "../assets/github.svg";
>
<Image
src={linkedinIcon}
alt="LinkedIn"
alt=""
class="h-6 w-6 opacity-70 group-hover:opacity-100 transition-opacity"
width={24}
height={24}
@ -78,7 +80,7 @@ import githubIcon from "../assets/github.svg";
>
<Image
src={githubIcon}
alt="GitHub"
alt=""
class="h-6 w-6 opacity-70 group-hover:opacity-100 transition-opacity"
width={24}
height={24}

View file

@ -8,7 +8,7 @@ const currentPath = Astro.url.pathname;
<!-- Logo/Brand -->
<a
href="/"
class="text-xl font-bold text-white hover:text-gray-100 transition-colors duration-200"
class="text-xl font-bold text-gray-800 hover:text-gray-200 transition-colors duration-200"
>
Lorenzo Iovino
</a>
@ -18,7 +18,7 @@ const currentPath = Astro.url.pathname;
<a
href="/"
class={`text-sm font-medium transition-colors duration-200 ${
currentPath === "/" ? "text-white font-semibold" : "text-white/80 hover:text-white"
currentPath === "/" ? "text-gray-800 font-semibold" : "text-gray-800/80 hover:text-gray-800"
}`}
>
Home
@ -26,7 +26,7 @@ const currentPath = Astro.url.pathname;
<a
href="/bio"
class={`text-sm font-medium transition-colors duration-200 ${
currentPath === "/bio" ? "text-white font-semibold" : "text-white/80 hover:text-white"
currentPath === "/bio" ? "text-gray-800 font-semibold" : "text-gray-800/80 hover:text-gray-800"
}`}
>
Bio
@ -34,7 +34,7 @@ const currentPath = Astro.url.pathname;
<a
href="/blog"
class={`text-sm font-medium transition-colors duration-200 ${
currentPath === "/blog" ? "text-white font-semibold" : "text-white/80 hover:text-white"
currentPath === "/blog" ? "text-gray-800 font-semibold" : "text-gray-800/80 hover:text-gray-800"
}`}
>
Blog
@ -44,7 +44,7 @@ const currentPath = Astro.url.pathname;
<!-- Mobile menu button -->
<button
id="mobile-menu-button"
class="md:hidden p-2 rounded-lg text-white hover:bg-white/10 focus:outline-none focus:ring-2 focus:ring-white/50"
class="md:hidden p-2 rounded-lg text-gray-800 hover:bg-white/10 focus:outline-none focus:ring-2 focus:ring-white/50"
aria-label="Toggle menu"
>
<svg
@ -71,8 +71,8 @@ const currentPath = Astro.url.pathname;
href="/"
class={`block px-3 py-2 rounded-lg text-base font-medium transition-colors duration-200 ${
currentPath === "/"
? "bg-white/20 text-white font-semibold"
: "text-white/80 hover:bg-white/10 hover:text-white"
? "bg-white/20 text-gray-800 font-semibold"
: "text-gray-800/80 hover:bg-white/10 hover:text-gray-800"
}`}
>
Home
@ -81,8 +81,8 @@ const currentPath = Astro.url.pathname;
href="/bio"
class={`block px-3 py-2 rounded-lg text-base font-medium transition-colors duration-200 ${
currentPath === "/bio"
? "bg-white/20 text-white font-semibold"
: "text-white/80 hover:bg-white/10 hover:text-white"
? "bg-white/20 text-gray-800 font-semibold"
: "text-gray-800/80 hover:bg-white/10 hover:text-gray-800"
}`}
>
Bio
@ -91,8 +91,8 @@ const currentPath = Astro.url.pathname;
href="/blog"
class={`block px-3 py-2 rounded-lg text-base font-medium transition-colors duration-200 ${
currentPath === "/blog"
? "bg-white/20 text-white font-semibold"
: "text-white/80 hover:bg-white/10 hover:text-white"
? "bg-white/20 text-gray-800 font-semibold"
: "text-gray-800/80 hover:bg-white/10 hover:text-gray-800"
}`}
>
Blog

View file

@ -16,7 +16,7 @@ const {
} = Astro.props;
const bgClass = backgroundColor === "light" ? "bg-white" : "bg-secondary";
const titleColorClass = titleColor === "light" ? "text-white" : "text-secondary";
const titleColorClass = titleColor === "light" ? "text-white" : "text-secondary-700";
const heightClass = noHeight ? "h-[0px]" : "h-[150px]";
---