bettered pageindex performances

This commit is contained in:
2026-04-09 17:50:15 +02:00
parent c7011c5574
commit 8fdf2e47a2
10 changed files with 62 additions and 84 deletions
+26 -7
View File
@@ -69,6 +69,32 @@ img {
decoding: async; decoding: async;
} }
/* Hero entrance animations */
@keyframes hero-fade-up {
from {
opacity: 0;
transform: translateY(60px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.hero-fade-up {
animation: hero-fade-up 1s cubic-bezier(0.33, 1, 0.68, 1) both;
}
.hero-fade-up-delay-1 {
animation-delay: 0.6s;
animation-duration: 0.6s;
}
.hero-fade-up-delay-2 {
animation-delay: 0.75s;
animation-duration: 0.6s;
}
/* Skeleton wave animation */ /* Skeleton wave animation */
@keyframes wave { @keyframes wave {
0% { 0% {
@@ -92,13 +118,6 @@ img {
/* Optimize font loading */
@font-face {
font-family: "Inter";
font-display: swap;
src: url("https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;900");
}
/* Prevent layout shift for lazy-loaded images */ /* Prevent layout shift for lazy-loaded images */
img { img {
aspect-ratio: auto; aspect-ratio: auto;
+3 -12
View File
@@ -54,22 +54,13 @@ export default function RootLayout({
{/* DNS prefetch for third-party domains */} {/* DNS prefetch for third-party domains */}
<link rel="dns-prefetch" href="https://fonts.googleapis.com" /> <link rel="dns-prefetch" href="https://fonts.googleapis.com" />
{/* Material Symbols with swap for faster first paint */} {/* Material Symbols — reduced to single weight/fill, display=swap prevents render blocking */}
<link <link
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@400,0&display=swap"
rel="stylesheet" rel="stylesheet"
/> />
{/* Preload critical fonts */} {/* Inter font is self-hosted by next/font — no external preload needed */}
<link
rel="preload"
as="font"
href="https://fonts.gstatic.com/s/inter/v18/UcCO3FwrK3iLTeHAPMtMT7kjjj0P.woff2"
type="font/woff2"
crossOrigin="anonymous"
/>
{/* Optimize LCP by reducing render-blocking resources */}
</head> </head>
<body className="min-h-screen flex flex-col"> <body className="min-h-screen flex flex-col">
<Navbar /> <Navbar />
+2 -16
View File
@@ -1,25 +1,11 @@
"use client";
import { useGsapScrollTrigger } from "@/components/hooks/useGsapScrollTrigger";
import HeroSection from "@/components/sections/HeroSection"; import HeroSection from "@/components/sections/HeroSection";
import ApproccioSection from "@/components/sections/ApproccioSection"; import HomeSections from "@/components/HomeSections";
import BeforeAfterSection from "@/components/sections/BeforeAfterSection";
import ServicesSection from "@/components/sections/ServicesSection";
import AboutSection from "@/components/sections/AboutSection";
import FilosofiaSection from "@/components/sections/FilosofiaSection";
import CtaSection from "@/components/sections/CtaSection";
export default function Home() { export default function Home() {
useGsapScrollTrigger();
return ( return (
<div className="snap-container"> <div className="snap-container">
<HeroSection /> <HeroSection />
<ApproccioSection /> <HomeSections />
<BeforeAfterSection />
<ServicesSection />
<AboutSection />
<FilosofiaSection />
<CtaSection />
</div> </div>
); );
} }
+25
View File
@@ -0,0 +1,25 @@
"use client";
import dynamic from "next/dynamic";
import { useGsapScrollTrigger } from "@/components/hooks/useGsapScrollTrigger";
const ApproccioSection = dynamic(() => import("@/components/sections/ApproccioSection"), { ssr: false });
const BeforeAfterSection = dynamic(() => import("@/components/sections/BeforeAfterSection"), { ssr: false });
const ServicesSection = dynamic(() => import("@/components/sections/ServicesSection"), { ssr: false });
const AboutSection = dynamic(() => import("@/components/sections/AboutSection"), { ssr: false });
const FilosofiaSection = dynamic(() => import("@/components/sections/FilosofiaSection"), { ssr: false });
const CtaSection = dynamic(() => import("@/components/sections/CtaSection"), { ssr: false });
export default function HomeSections() {
useGsapScrollTrigger();
return (
<>
<ApproccioSection />
<BeforeAfterSection />
<ServicesSection />
<AboutSection />
<FilosofiaSection />
<CtaSection />
</>
);
}
@@ -4,9 +4,6 @@ import Image from "next/image";
import { useRef } from "react"; import { useRef } from "react";
import { useGSAP } from "@gsap/react"; import { useGSAP } from "@gsap/react";
import gsap from "gsap"; import gsap from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";
gsap.registerPlugin(ScrollTrigger);
export default function AboutSection() { export default function AboutSection() {
const sectionRef = useRef<HTMLElement>(null); const sectionRef = useRef<HTMLElement>(null);
@@ -48,6 +45,7 @@ export default function AboutSection() {
alt="Architettura moderna in vetro e acciaio" alt="Architettura moderna in vetro e acciaio"
src="/images/architecture.jpg" src="/images/architecture.jpg"
fill fill
sizes="100vw"
className="object-cover" className="object-cover"
priority={false} priority={false}
/> />
@@ -2,9 +2,6 @@
import { useRef } from "react"; import { useRef } from "react";
import { useGSAP } from "@gsap/react"; import { useGSAP } from "@gsap/react";
import gsap from "gsap"; import gsap from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";
gsap.registerPlugin(ScrollTrigger);
export default function ApproccioSection() { export default function ApproccioSection() {
const sectionRef = useRef<HTMLElement>(null); const sectionRef = useRef<HTMLElement>(null);
@@ -2,9 +2,6 @@
import { useRef } from "react"; import { useRef } from "react";
import { useGSAP } from "@gsap/react"; import { useGSAP } from "@gsap/react";
import gsap from "gsap"; import gsap from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";
gsap.registerPlugin(ScrollTrigger);
export default function BeforeAfterSection() { export default function BeforeAfterSection() {
const sectionRef = useRef<HTMLElement>(null); const sectionRef = useRef<HTMLElement>(null);
@@ -2,9 +2,6 @@
import { useRef } from "react"; import { useRef } from "react";
import { useGSAP } from "@gsap/react"; import { useGSAP } from "@gsap/react";
import gsap from "gsap"; import gsap from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";
gsap.registerPlugin(ScrollTrigger);
export default function FilosofiaSection() { export default function FilosofiaSection() {
const sectionRef = useRef<HTMLElement>(null); const sectionRef = useRef<HTMLElement>(null);
@@ -1,52 +1,23 @@
"use client";
import Link from "next/link"; import Link from "next/link";
import { useRef } from "react";
import { useGSAP } from "@gsap/react";
import gsap from "gsap";
export default function HeroSection() { export default function HeroSection() {
const sectionRef = useRef<HTMLElement>(null);
const headlineRef = useRef<HTMLHeadingElement>(null);
const ctaRef = useRef<HTMLDivElement>(null);
useGSAP(() => {
if (!headlineRef.current || !ctaRef.current) return;
const tl = gsap.timeline({ defaults: { ease: "power3.out" } });
tl.fromTo(headlineRef.current,
{ y: 60, opacity: 0 },
{ y: 0, opacity: 1, duration: 1 }
).fromTo(
Array.from(ctaRef.current.children),
{ y: 30, opacity: 0 },
{ y: 0, opacity: 1, duration: 0.6, stagger: 0.15 },
"-=0.4"
);
}, { scope: sectionRef });
return ( return (
<section <section className="snap-section min-h-screen flex items-center justify-center px-6 lg:px-8 pt-20">
ref={sectionRef}
className="snap-section min-h-screen flex items-center justify-center px-6 lg:px-8 pt-20"
>
<div className="max-w-5xl mx-auto text-center"> <div className="max-w-5xl mx-auto text-center">
<h1 <h1 className="text-huge font-black uppercase mb-8 sm:mb-12 hero-fade-up">
ref={headlineRef}
className="text-huge font-black uppercase mb-8 sm:mb-12"
>
La <span className="text-primary">struttura</span> digitale del La <span className="text-primary">struttura</span> digitale del
tuo business. tuo business.
</h1> </h1>
<div ref={ctaRef} className="flex flex-col sm:flex-row gap-6 justify-center"> <div className="flex flex-col sm:flex-row gap-6 justify-center">
<Link <Link
href="/contatti" href="/contatti"
className="bg-primary text-on-primary px-6 py-3 sm:px-10 sm:py-5 font-bold uppercase tracking-widest text-sm sm:text-lg transition-all hover:brightness-110 active:scale-[0.98] text-center" className="hero-fade-up hero-fade-up-delay-1 bg-primary text-on-primary px-6 py-3 sm:px-10 sm:py-5 font-bold uppercase tracking-widest text-sm sm:text-lg transition-all hover:brightness-110 active:scale-[0.98] text-center"
> >
Inizia il Progetto Inizia il Progetto
</Link> </Link>
<a <a
href="#filosofia" href="#filosofia"
className="border-2 border-on-background text-on-background px-6 py-3 sm:px-10 sm:py-5 font-bold uppercase tracking-widest text-sm sm:text-lg transition-all hover:bg-on-background hover:text-background active:scale-[0.98] text-center" className="hero-fade-up hero-fade-up-delay-2 border-2 border-on-background text-on-background px-6 py-3 sm:px-10 sm:py-5 font-bold uppercase tracking-widest text-sm sm:text-lg transition-all hover:bg-on-background hover:text-background active:scale-[0.98] text-center"
> >
Scopri il Metodo Scopri il Metodo
</a> </a>
@@ -2,11 +2,8 @@
import { useRef, useState, useCallback, useEffect } from "react"; import { useRef, useState, useCallback, useEffect } from "react";
import { useGSAP } from "@gsap/react"; import { useGSAP } from "@gsap/react";
import gsap from "gsap"; import gsap from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";
import ScrollProgressDots from "@/components/ScrollProgressDots"; import ScrollProgressDots from "@/components/ScrollProgressDots";
gsap.registerPlugin(ScrollTrigger);
const services = [ const services = [
{ {
id: "portali", id: "portali",