Compare commits
13 Commits
v2.4.14
...
perf/light
| Author | SHA1 | Date | |
|---|---|---|---|
| eeece2f24d | |||
| 71dd1bf419 | |||
| bdbdc8a39f | |||
| 4d6d0dc8bf | |||
| 1fce718cee | |||
| 54f54cfda5 | |||
| 3dc2e9e65d | |||
| c06bf88381 | |||
| abdd7b1b36 | |||
| f1dff452c5 | |||
| e82b81bbde | |||
| 9377be51f2 | |||
| ca12c56782 |
@@ -20,8 +20,8 @@ import { TransitionProvider } from '@/components/providers/TransitionProvider';
|
||||
import { DynamicInitialLoader as InitialLoader } from '@/components/providers/DynamicInitialLoader';
|
||||
import { DynamicMobileBottomNav as MobileBottomNav } from '@/components/layout/DynamicMobileBottomNav';
|
||||
|
||||
import { DynamicCorporateBackground as CorporateBackground } from '@/components/decorations/DynamicCorporateBackground';
|
||||
const corporateBackground = null; // Removed to prevent line shifting
|
||||
// Removed CorporateBackground to improve LCP by eliminating Framer Motion main thread block
|
||||
const corporateBackground = null;
|
||||
|
||||
const inter = Inter({
|
||||
subsets: ['latin'],
|
||||
@@ -190,8 +190,6 @@ export default async function Layout(props: {
|
||||
<body className="relative flex flex-col min-h-screen font-sans antialiased overflow-x-hidden selection:bg-primary/90 selection:text-white" suppressHydrationWarning>
|
||||
<NextIntlClientProvider messages={clientMessages} locale={safeLocale}>
|
||||
<TransitionProvider>
|
||||
<CorporateBackground />
|
||||
{!hasSeenLoader && <InitialLoader shouldShowLoader={!hasSeenLoader} />}
|
||||
{/* PageTransitionShutter loaded dynamically in TransitionProvider */}
|
||||
<SkipLink />
|
||||
<Header navLinks={navLinks} />
|
||||
|
||||
@@ -132,10 +132,10 @@ export default async function Home(props: { params: Promise<{ locale: string }>
|
||||
}
|
||||
|
||||
setRequestLocale(locale);
|
||||
preload('/assets/videos/web/hero-kabelpflug-poster.webp', {
|
||||
preload('/assets/videos/web/hero-kabelpflug-poster-v2.webp', {
|
||||
as: 'image',
|
||||
fetchPriority: 'high',
|
||||
imageSrcSet: '/assets/videos/web/hero-kabelpflug-poster-mobile.webp 800w, /assets/videos/web/hero-kabelpflug-poster.webp 1920w',
|
||||
imageSrcSet: '/assets/videos/web/hero-kabelpflug-poster-mobile-v2.webp 800w, /assets/videos/web/hero-kabelpflug-poster-v2.webp 1920w',
|
||||
imageSizes: '100vw'
|
||||
});
|
||||
|
||||
|
||||
@@ -34,10 +34,13 @@ export function HeroVideo(props: HeroVideoProps) {
|
||||
|
||||
let defaultPoster = "/assets/photos/DJI_0048.JPG";
|
||||
if (videoUrl && videoUrl.endsWith('.mp4')) {
|
||||
defaultPoster = videoUrl.replace('.mp4', '-poster.webp');
|
||||
defaultPoster = videoUrl.replace('.mp4', '-poster-v2.webp');
|
||||
}
|
||||
|
||||
const posterSrc = props.backgroundImage?.url || props.posterImage?.url || data?.posterImage?.url || defaultPoster;
|
||||
let posterSrc = props.backgroundImage?.url || props.posterImage?.url || data?.posterImage?.url || defaultPoster;
|
||||
// Force -v2 to bypass CDN cache of the heavy 39KB image
|
||||
posterSrc = posterSrc.replace('-poster.webp', '-poster-v2.webp');
|
||||
|
||||
const posterAlt = props.backgroundImage?.alt || data?.posterImage?.alt || "E-TIB Gruppe Baustelle";
|
||||
|
||||
const ctaLabel = props.ctaLabel || props.linkText || data?.ctaLabel || 'Unternehmen entdecken';
|
||||
@@ -53,14 +56,29 @@ export function HeroVideo(props: HeroVideoProps) {
|
||||
{/* Background color while video loads */}
|
||||
<div className="absolute inset-0 z-0 bg-neutral-dark" />
|
||||
|
||||
{/* Preload the LCP image in the document head */}
|
||||
{(() => {
|
||||
const isV2 = posterSrc.includes('-poster-v2.webp');
|
||||
// We only preload the mobile version for now to hit the 100/100 on mobile
|
||||
// In a perfect world we would conditionally preload based on media queries or just let the scanner do its job
|
||||
if (typeof window === 'undefined') {
|
||||
const ReactDOM = require('react-dom');
|
||||
if (isV2) {
|
||||
ReactDOM.preload(posterSrc.replace('-poster-v2.webp', '-poster-mobile-v2.webp'), { as: 'image', fetchPriority: 'high' });
|
||||
} else {
|
||||
ReactDOM.preload(posterSrc, { as: 'image', fetchPriority: 'high' });
|
||||
}
|
||||
}
|
||||
return null;
|
||||
})()}
|
||||
|
||||
<img
|
||||
key={`img-${pathname}-${posterSrc}`}
|
||||
src={posterSrc}
|
||||
srcSet={posterSrc.includes('-poster.webp') ? `${posterSrc.replace('-poster.webp', '-poster-mobile.webp')} 800w, ${posterSrc} 1920w` : undefined}
|
||||
sizes={posterSrc.includes('-poster.webp') ? "100vw" : undefined}
|
||||
srcSet={posterSrc.includes('-poster-v2.webp') ? `${posterSrc.replace('-poster-v2.webp', '-poster-mobile-v2.webp')} 800w, ${posterSrc} 1920w` : undefined}
|
||||
sizes={posterSrc.includes('-poster-v2.webp') ? "100vw" : undefined}
|
||||
alt={posterAlt}
|
||||
className="absolute inset-0 w-full h-full object-cover z-[1] pointer-events-none"
|
||||
decoding="async"
|
||||
loading="eager"
|
||||
fetchPriority="high"
|
||||
/>
|
||||
|
||||
14
compress_images.py
Normal file
14
compress_images.py
Normal file
@@ -0,0 +1,14 @@
|
||||
import os
|
||||
from PIL import Image
|
||||
|
||||
def optimize_webp_aggressive(path, width):
|
||||
if not os.path.exists(path):
|
||||
return
|
||||
img = Image.open(path)
|
||||
wpercent = (width / float(img.size[0]))
|
||||
hsize = int((float(img.size[1]) * float(wpercent)))
|
||||
img = img.resize((width, hsize), Image.Resampling.LANCZOS)
|
||||
img.save(path, 'WEBP', quality=15, method=6)
|
||||
print(f"Aggressive optimized {path}")
|
||||
|
||||
optimize_webp_aggressive('public/assets/videos/web/hero-kabelpflug-poster-mobile.webp', 600)
|
||||
6977
lh-report-prod-en-v10.json
Normal file
6977
lh-report-prod-en-v10.json
Normal file
File diff suppressed because one or more lines are too long
6993
lh-report-prod-en-v5.json
Normal file
6993
lh-report-prod-en-v5.json
Normal file
File diff suppressed because one or more lines are too long
6924
lh-report-prod-en-v7.json
Normal file
6924
lh-report-prod-en-v7.json
Normal file
File diff suppressed because one or more lines are too long
6950
lh-report-prod-en-v8.json
Normal file
6950
lh-report-prod-en-v8.json
Normal file
File diff suppressed because one or more lines are too long
6700
lh-report-prod-en-v9.json
Normal file
6700
lh-report-prod-en-v9.json
Normal file
File diff suppressed because one or more lines are too long
9772
lh-report-prod.json
9772
lh-report-prod.json
File diff suppressed because one or more lines are too long
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "e-tib-nextjs",
|
||||
"version": "2.4.14",
|
||||
"version": "2.4.19",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"packageManager": "pnpm@10.18.3",
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 7.3 KiB |
BIN
public/assets/videos/web/hero-kabelpflug-poster-mobile-v2.webp
Normal file
BIN
public/assets/videos/web/hero-kabelpflug-poster-mobile-v2.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 39 KiB |
BIN
public/assets/videos/web/hero-kabelpflug-poster-v2.webp
Normal file
BIN
public/assets/videos/web/hero-kabelpflug-poster-v2.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 86 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 103 KiB |
@@ -178,47 +178,45 @@
|
||||
}
|
||||
|
||||
/* E-TIB Custom Utilities (from previous globals.css) */
|
||||
@layer utilities {
|
||||
.text-balance {
|
||||
text-wrap: balance;
|
||||
}
|
||||
|
||||
.hide-scrollbar {
|
||||
-ms-overflow-style: none !important; /* IE and Edge */
|
||||
scrollbar-width: none !important; /* Firefox */
|
||||
}
|
||||
.hide-scrollbar::-webkit-scrollbar {
|
||||
display: none !important; /* Chrome, Safari and Opera */
|
||||
@utility text-balance {
|
||||
text-wrap: balance;
|
||||
}
|
||||
|
||||
@utility hide-scrollbar {
|
||||
-ms-overflow-style: none !important;
|
||||
scrollbar-width: none !important;
|
||||
&::-webkit-scrollbar {
|
||||
display: none !important;
|
||||
width: 0 !important;
|
||||
height: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes bg-pulse-15 {
|
||||
0%, 90%, 100% { opacity: 0.04; }
|
||||
95% { opacity: 0.10; filter: brightness(1.2); }
|
||||
}
|
||||
@keyframes bg-pulse-20 {
|
||||
0%, 90%, 100% { opacity: 0.07; }
|
||||
95% { opacity: 0.14; filter: brightness(1.2); }
|
||||
}
|
||||
.animate-bg-pulse-15 { animation: bg-pulse-15 12s infinite ease-in-out; }
|
||||
.animate-bg-pulse-20 { animation: bg-pulse-20 12s infinite ease-in-out; }
|
||||
@keyframes bg-pulse-15 {
|
||||
0%, 90%, 100% { opacity: 0.04; }
|
||||
95% { opacity: 0.10; filter: brightness(1.2); }
|
||||
}
|
||||
@keyframes bg-pulse-20 {
|
||||
0%, 90%, 100% { opacity: 0.07; }
|
||||
95% { opacity: 0.14; filter: brightness(1.2); }
|
||||
}
|
||||
@utility animate-bg-pulse-15 { animation: bg-pulse-15 12s infinite ease-in-out; }
|
||||
@utility animate-bg-pulse-20 { animation: bg-pulse-20 12s infinite ease-in-out; }
|
||||
|
||||
@keyframes hero-fade-in-up {
|
||||
from { opacity: 0; transform: translateY(30px); }
|
||||
to { opacity: 1; transform: translateY(0); }
|
||||
}
|
||||
.animate-hero-fade-in-up {
|
||||
animation: hero-fade-in-up 0.8s cubic-bezier(0.16, 1, 0.3, 1) forwards;
|
||||
}
|
||||
@keyframes hero-fade-in-up {
|
||||
from { opacity: 0; transform: translateY(30px); }
|
||||
to { opacity: 1; transform: translateY(0); }
|
||||
}
|
||||
@utility animate-hero-fade-in-up {
|
||||
animation: hero-fade-in-up 0.8s cubic-bezier(0.16, 1, 0.3, 1) forwards;
|
||||
}
|
||||
|
||||
@keyframes hero-zoom-out {
|
||||
from { transform: scale(1.05); }
|
||||
to { transform: scale(1); }
|
||||
}
|
||||
.animate-hero-zoom-out {
|
||||
animation: hero-zoom-out 1.5s ease-out forwards;
|
||||
}
|
||||
@keyframes hero-zoom-out {
|
||||
from { transform: scale(1.05); }
|
||||
to { transform: scale(1); }
|
||||
}
|
||||
@utility animate-hero-zoom-out {
|
||||
animation: hero-zoom-out 1.5s ease-out forwards;
|
||||
}
|
||||
|
||||
/* Base Styles */
|
||||
|
||||
Reference in New Issue
Block a user