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 { DynamicInitialLoader as InitialLoader } from '@/components/providers/DynamicInitialLoader';
|
||||||
import { DynamicMobileBottomNav as MobileBottomNav } from '@/components/layout/DynamicMobileBottomNav';
|
import { DynamicMobileBottomNav as MobileBottomNav } from '@/components/layout/DynamicMobileBottomNav';
|
||||||
|
|
||||||
import { DynamicCorporateBackground as CorporateBackground } from '@/components/decorations/DynamicCorporateBackground';
|
// Removed CorporateBackground to improve LCP by eliminating Framer Motion main thread block
|
||||||
const corporateBackground = null; // Removed to prevent line shifting
|
const corporateBackground = null;
|
||||||
|
|
||||||
const inter = Inter({
|
const inter = Inter({
|
||||||
subsets: ['latin'],
|
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>
|
<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}>
|
<NextIntlClientProvider messages={clientMessages} locale={safeLocale}>
|
||||||
<TransitionProvider>
|
<TransitionProvider>
|
||||||
<CorporateBackground />
|
|
||||||
{!hasSeenLoader && <InitialLoader shouldShowLoader={!hasSeenLoader} />}
|
|
||||||
{/* PageTransitionShutter loaded dynamically in TransitionProvider */}
|
{/* PageTransitionShutter loaded dynamically in TransitionProvider */}
|
||||||
<SkipLink />
|
<SkipLink />
|
||||||
<Header navLinks={navLinks} />
|
<Header navLinks={navLinks} />
|
||||||
|
|||||||
@@ -132,10 +132,10 @@ export default async function Home(props: { params: Promise<{ locale: string }>
|
|||||||
}
|
}
|
||||||
|
|
||||||
setRequestLocale(locale);
|
setRequestLocale(locale);
|
||||||
preload('/assets/videos/web/hero-kabelpflug-poster.webp', {
|
preload('/assets/videos/web/hero-kabelpflug-poster-v2.webp', {
|
||||||
as: 'image',
|
as: 'image',
|
||||||
fetchPriority: 'high',
|
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'
|
imageSizes: '100vw'
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -34,10 +34,13 @@ export function HeroVideo(props: HeroVideoProps) {
|
|||||||
|
|
||||||
let defaultPoster = "/assets/photos/DJI_0048.JPG";
|
let defaultPoster = "/assets/photos/DJI_0048.JPG";
|
||||||
if (videoUrl && videoUrl.endsWith('.mp4')) {
|
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 posterAlt = props.backgroundImage?.alt || data?.posterImage?.alt || "E-TIB Gruppe Baustelle";
|
||||||
|
|
||||||
const ctaLabel = props.ctaLabel || props.linkText || data?.ctaLabel || 'Unternehmen entdecken';
|
const ctaLabel = props.ctaLabel || props.linkText || data?.ctaLabel || 'Unternehmen entdecken';
|
||||||
@@ -53,14 +56,29 @@ export function HeroVideo(props: HeroVideoProps) {
|
|||||||
{/* Background color while video loads */}
|
{/* Background color while video loads */}
|
||||||
<div className="absolute inset-0 z-0 bg-neutral-dark" />
|
<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
|
<img
|
||||||
key={`img-${pathname}-${posterSrc}`}
|
key={`img-${pathname}-${posterSrc}`}
|
||||||
src={posterSrc}
|
src={posterSrc}
|
||||||
srcSet={posterSrc.includes('-poster.webp') ? `${posterSrc.replace('-poster.webp', '-poster-mobile.webp')} 800w, ${posterSrc} 1920w` : undefined}
|
srcSet={posterSrc.includes('-poster-v2.webp') ? `${posterSrc.replace('-poster-v2.webp', '-poster-mobile-v2.webp')} 800w, ${posterSrc} 1920w` : undefined}
|
||||||
sizes={posterSrc.includes('-poster.webp') ? "100vw" : undefined}
|
sizes={posterSrc.includes('-poster-v2.webp') ? "100vw" : undefined}
|
||||||
alt={posterAlt}
|
alt={posterAlt}
|
||||||
className="absolute inset-0 w-full h-full object-cover z-[1] pointer-events-none"
|
className="absolute inset-0 w-full h-full object-cover z-[1] pointer-events-none"
|
||||||
decoding="async"
|
|
||||||
loading="eager"
|
loading="eager"
|
||||||
fetchPriority="high"
|
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",
|
"name": "e-tib-nextjs",
|
||||||
"version": "2.4.14",
|
"version": "2.4.19",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"private": true,
|
"private": true,
|
||||||
"packageManager": "pnpm@10.18.3",
|
"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) */
|
/* E-TIB Custom Utilities (from previous globals.css) */
|
||||||
@layer utilities {
|
@utility text-balance {
|
||||||
.text-balance {
|
|
||||||
text-wrap: balance;
|
text-wrap: balance;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hide-scrollbar {
|
@utility hide-scrollbar {
|
||||||
-ms-overflow-style: none !important; /* IE and Edge */
|
-ms-overflow-style: none !important;
|
||||||
scrollbar-width: none !important; /* Firefox */
|
scrollbar-width: none !important;
|
||||||
}
|
&::-webkit-scrollbar {
|
||||||
.hide-scrollbar::-webkit-scrollbar {
|
display: none !important;
|
||||||
display: none !important; /* Chrome, Safari and Opera */
|
|
||||||
width: 0 !important;
|
width: 0 !important;
|
||||||
height: 0 !important;
|
height: 0 !important;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@keyframes bg-pulse-15 {
|
@keyframes bg-pulse-15 {
|
||||||
0%, 90%, 100% { opacity: 0.04; }
|
0%, 90%, 100% { opacity: 0.04; }
|
||||||
95% { opacity: 0.10; filter: brightness(1.2); }
|
95% { opacity: 0.10; filter: brightness(1.2); }
|
||||||
}
|
}
|
||||||
@keyframes bg-pulse-20 {
|
@keyframes bg-pulse-20 {
|
||||||
0%, 90%, 100% { opacity: 0.07; }
|
0%, 90%, 100% { opacity: 0.07; }
|
||||||
95% { opacity: 0.14; filter: brightness(1.2); }
|
95% { opacity: 0.14; filter: brightness(1.2); }
|
||||||
}
|
}
|
||||||
.animate-bg-pulse-15 { animation: bg-pulse-15 12s infinite ease-in-out; }
|
@utility 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; }
|
@utility animate-bg-pulse-20 { animation: bg-pulse-20 12s infinite ease-in-out; }
|
||||||
|
|
||||||
@keyframes hero-fade-in-up {
|
@keyframes hero-fade-in-up {
|
||||||
from { opacity: 0; transform: translateY(30px); }
|
from { opacity: 0; transform: translateY(30px); }
|
||||||
to { opacity: 1; transform: translateY(0); }
|
to { opacity: 1; transform: translateY(0); }
|
||||||
}
|
}
|
||||||
.animate-hero-fade-in-up {
|
@utility animate-hero-fade-in-up {
|
||||||
animation: hero-fade-in-up 0.8s cubic-bezier(0.16, 1, 0.3, 1) forwards;
|
animation: hero-fade-in-up 0.8s cubic-bezier(0.16, 1, 0.3, 1) forwards;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes hero-zoom-out {
|
@keyframes hero-zoom-out {
|
||||||
from { transform: scale(1.05); }
|
from { transform: scale(1.05); }
|
||||||
to { transform: scale(1); }
|
to { transform: scale(1); }
|
||||||
}
|
}
|
||||||
.animate-hero-zoom-out {
|
@utility animate-hero-zoom-out {
|
||||||
animation: hero-zoom-out 1.5s ease-out forwards;
|
animation: hero-zoom-out 1.5s ease-out forwards;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Base Styles */
|
/* Base Styles */
|
||||||
|
|||||||
Reference in New Issue
Block a user