Compare commits
13
Commits
| 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"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -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)
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+2243
-7529
File diff suppressed because one or more lines are too long
+1
-1
@@ -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 |
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 39 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 86 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 103 KiB |
+33
-35
@@ -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;
|
}
|
||||||
}
|
|
||||||
|
@utility hide-scrollbar {
|
||||||
.hide-scrollbar {
|
-ms-overflow-style: none !important;
|
||||||
-ms-overflow-style: none !important; /* IE and Edge */
|
scrollbar-width: none !important;
|
||||||
scrollbar-width: none !important; /* Firefox */
|
&::-webkit-scrollbar {
|
||||||
}
|
display: none !important;
|
||||||
.hide-scrollbar::-webkit-scrollbar {
|
|
||||||
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