feat(performance): Core Web Vitals optimizations

- Font optimization: Replace @font-face with next/font/google (DM Sans, Inter) for faster font loading and no render-blocking
- Image optimization: Add Unsplash to remotePatterns, configure AVIF/WebP formats, add device/image sizes
- Convert native <img> tags to next/image with proper sizing and priority for LCP images
- Add optimizePackageImports for lucide-react and framer-motion to reduce bundle size
- Fix CLS: Urgency message uses fixed min-height instead of animated height
- Fix CLS: ProductCard quick-add button uses opacity instead of translate for hover
- Convert HeroVideo scroll indicator to CSS animation
- Script loading: Rybbit uses lazyOnload strategy for better INP
This commit is contained in:
Unchained
2026-03-31 12:03:34 +02:00
parent d4039c6e3b
commit 8eb9f24b33
9 changed files with 92 additions and 63 deletions

View File

@@ -5,6 +5,7 @@ import { getPageMetadata } from "@/lib/i18n/pageMetadata";
import { isValidLocale, DEFAULT_LOCALE, type Locale } from "@/lib/i18n/locales";
import { getPageKeywords } from "@/lib/seo/keywords";
import { Metadata } from "next";
import Image from "next/image";
const baseUrl = process.env.NEXT_PUBLIC_SITE_URL || "https://manoonoils.com";
@@ -67,10 +68,13 @@ export default async function AboutPage({ params }: AboutPageProps) {
</div>
<div className="relative h-[400px] md:h-[500px] overflow-hidden">
<img
<Image
src="https://images.unsplash.com/photo-1608571423902-eed4a5ad8108?q=80&w=2000&auto=format&fit=crop"
alt={metadata.about.productionAlt}
className="w-full h-full object-cover"
fill
priority
className="object-cover"
sizes="100vw"
/>
<div className="absolute inset-0 bg-black/20" />
</div>

View File

@@ -60,7 +60,7 @@ export default async function LocaleLayout({
<Script
src="/api/script.js"
data-site-id={RYBBIT_SITE_ID}
strategy="afterInteractive"
strategy="lazyOnload"
/>
<NextIntlClientProvider messages={messages}>
{children}

View File

@@ -14,6 +14,7 @@ import { getPageMetadata } from "@/lib/i18n/pageMetadata";
import { isValidLocale, DEFAULT_LOCALE, getSaleorLocale, type Locale } from "@/lib/i18n/locales";
import { getPageKeywords, getBrandKeywords } from "@/lib/seo/keywords";
import { Metadata } from "next";
import Image from "next/image";
const baseUrl = process.env.NEXT_PUBLIC_SITE_URL || "https://manoonoils.com";
@@ -157,10 +158,12 @@ export default async function Homepage({ params }: { params: Promise<{ locale: s
</a>
</div>
<div className="relative aspect-[4/3] bg-[#e8f0f5] rounded-lg overflow-hidden">
<img
<Image
src="https://images.unsplash.com/photo-1608571423902-eed4a5ad8108?q=80&w=800&auto=format&fit=crop"
alt={metadata.home.productionAlt}
className="w-full h-full object-cover"
fill
className="object-cover"
sizes="(max-width: 768px) 100vw, 50vw"
/>
</div>
</div>