feat: optimize performance and fix CLS issues

This commit is contained in:
Lorenzo Iovino 2026-01-09 16:40:37 +01:00
parent df04844ca2
commit 52f112568c
7 changed files with 88 additions and 17 deletions

View file

@ -1,7 +1,5 @@
---
import { Image } from "astro:assets";
import astroIcon from "../assets/astro.svg";
import tailwindIcon from "../assets/tailwind.svg";
import githubIcon from "../assets/github.svg";
---

View file

@ -10,24 +10,26 @@ import githubIcon from "../assets/github.svg";
<div class="mx-auto max-w-5xl">
<div
class="relative overflow-hidden rounded-3xl bg-white dark:bg-gray-800 shadow-soft-lg hover:shadow-soft-lg transition-all duration-300"
style="min-height: 300px;"
>
<div class="relative flex flex-col md:flex-row items-center md:items-end">
<!-- Photo Section -->
<div class="w-full md:w-auto flex-shrink-0 order-2 md:order-none">
<div class="relative overflow-hidden md:rounded-l-3xl flex justify-center md:block">
<div
class="relative overflow-hidden md:rounded-l-3xl flex justify-center md:block md:w-[300px]"
>
<Image
src={mePhoto}
alt="Photo of Lorenzo Iovino"
class="w-48 h-auto md:w-full object-cover object-center"
class="w-48 h-48 md:w-[300px] md:h-[300px] object-cover object-center"
width={300}
height={300}
quality={90}
format="webp"
loading="eager"
fetchpriority="high"
decoding="sync"
/>
<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>
</div>
</div>
@ -36,7 +38,7 @@ import githubIcon from "../assets/github.svg";
<div class="space-y-4 md:space-y-6">
<!-- Greeting -->
<div class="text-center md:text-left">
<h1 class="mb-3 text-gray-900 dark:text-gray-100">
<h1 class="mb-3 text-gray-900 dark:text-gray-100" style="min-height: 2.5rem;">
Hey, I'm <span class="text-gray-900 dark:text-gray-100 font-extrabold"
>Lorenzo</span
>!

View file

@ -134,6 +134,7 @@ const currentPath = Astro.url.pathname;
<div
id="mobile-menu"
class="hidden md:hidden bg-secondary dark:bg-gray-800 transition-colors duration-200"
style="max-height: 0; overflow: hidden; transition: max-height 0.3s ease-in-out;"
>
<div class="px-4 py-3 space-y-3">
<a
@ -176,7 +177,15 @@ const currentPath = Astro.url.pathname;
const mobileMenu = document.getElementById("mobile-menu");
mobileMenuButton?.addEventListener("click", () => {
mobileMenu?.classList.toggle("hidden");
if (mobileMenu?.classList.contains("hidden")) {
mobileMenu.classList.remove("hidden");
mobileMenu.style.maxHeight = "500px";
} else if (mobileMenu) {
mobileMenu.style.maxHeight = "0";
setTimeout(() => {
mobileMenu?.classList.add("hidden");
}, 300);
}
});
// Theme toggle functionality

View file

@ -170,13 +170,32 @@ const fullCanonicalUrl = canonicalUrl || `${siteUrl}${Astro.url.pathname}`;
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
rel="preload"
as="font"
type="font/woff2"
href="https://fonts.gstatic.com/s/inter/v13/UcCO3FwrK3iLTeHuS_fvQtMwCp50KnMw2boKoduKmMEVuLyfAZ9hiA.woff2"
crossorigin
/>
<style>
/* Fallback font ottimizzato per ridurre layout shift */
@font-face {
font-family: "Inter-fallback";
font-style: normal;
font-weight: 400 800;
src: local("Arial");
ascent-override: 90%;
descent-override: 22%;
line-gap-override: 0%;
size-adjust: 107%;
}
@font-face {
font-family: "Inter";
font-style: normal;
font-weight: 400 800;
font-display: swap;
font-display: optional;
src: url(https://fonts.gstatic.com/s/inter/v13/UcCO3FwrK3iLTeHuS_fvQtMwCp50KnMw2boKoduKmMEVuLyfAZ9hiA.woff2)
format("woff2");
unicode-range:
@ -184,6 +203,17 @@ const fullCanonicalUrl = canonicalUrl || `${siteUrl}${Astro.url.pathname}`;
U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF,
U+FFFD;
}
/* Previeni flash of unstyled content */
body {
font-family:
"Inter",
"Inter-fallback",
-apple-system,
BlinkMacSystemFont,
"Segoe UI",
sans-serif;
}
</style>
<link rel="icon" type="image/x-icon" href="/favicon.ico" />

View file

@ -108,7 +108,7 @@ const initialPosts: BlogPost[] = sortedPosts.slice(0, 6);
<div id="posts-container" class="space-y-8">
{
initialPosts.map((post: BlogPost) => (
initialPosts.map((post: BlogPost, index: number) => (
<article class="bg-white dark:bg-gray-800 rounded-2xl shadow-soft-lg overflow-hidden hover:shadow-soft-lg transition-all duration-300">
<div class="block">
{post.data.heroImage && (
@ -118,10 +118,12 @@ const initialPosts: BlogPost[] = sortedPosts.slice(0, 6);
src={post.data.heroImage}
alt={post.data.title}
class="w-full h-full object-cover hover:scale-105 transition-transform duration-300"
width={1200}
height={630}
quality={70}
width={760}
height={570}
quality={80}
format="webp"
loading={index === 0 ? "eager" : "lazy"}
fetchpriority={index === 0 ? "high" : undefined}
/>
<div class="absolute inset-0 bg-gradient-to-t from-black/50 to-transparent" />
</div>
@ -159,7 +161,7 @@ const initialPosts: BlogPost[] = sortedPosts.slice(0, 6);
<p class="text-gray-700 dark:text-gray-300 text-lg leading-relaxed mb-4">
{post.data.description}
</p>
<div class="flex items-center text-secondary-800 dark:text-primary font-medium">
<div class="flex items-center text-secondary-700 dark:text-primary font-medium">
Read more
<svg
xmlns="http://www.w3.org/2000/svg"
@ -220,6 +222,9 @@ const initialPosts: BlogPost[] = sortedPosts.slice(0, 6);
src="${post.data.heroImage}"
alt="${post.data.title}"
class="w-full h-full object-cover hover:scale-105 transition-transform duration-300"
loading="lazy"
width="760"
height="570"
/>
<div class="absolute inset-0 bg-gradient-to-t from-black/50 to-transparent"></div>
</div>

View file

@ -82,10 +82,12 @@ const heroImageSrc = entry.data.heroImage?.src || mePhoto.src;
src={entry.data.heroImage}
alt={entry.data.title}
class="w-full h-full object-cover"
width={1200}
height={630}
quality={70}
width={824}
height={618}
quality={80}
format="webp"
loading="eager"
fetchpriority="high"
/>
</div>
</div>

View file

@ -8,6 +8,15 @@
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-rendering: optimizeLegibility;
font-family:
"Inter",
-apple-system,
BlinkMacSystemFont,
"Segoe UI",
Roboto,
"Helvetica Neue",
Arial,
sans-serif;
}
/* Typography base */
@ -17,6 +26,9 @@
"kern" 1,
"liga" 1,
"calt" 1;
/* Previene layout shift durante il caricamento del font */
font-synthesis: none;
-webkit-text-size-adjust: 100%;
}
/* Headings ottimizzati */
@ -32,6 +44,8 @@
"liga" 1,
"calt" 1,
"ss01" 1;
/* Contenimento del layout per prevenire shift */
contain: layout style paint;
}
h1 {
@ -85,4 +99,15 @@
.text-pretty {
text-wrap: pretty;
}
/* Previeni layout shift per elementi con contenuto dinamico */
.prevent-shift {
contain: layout style paint;
content-visibility: auto;
}
/* Ottimizza rendering immagini */
img {
contain: size layout paint;
}
}