This commit implements comprehensive performance optimizations to improve the PageSpeed Insights score from 70/100 to targeting 90+. ## Images & Assets (Est. 200+ KiB savings) - Optimize vocalinux.png: 207KB → 44KB (79% reduction) - Add WebP versions for all logo sizes (32, 64, 96, 192, 512px) - Create og-image.webp: 274KB → 176KB (36% reduction) - All WebP images provide ~92% size reduction over PNG ## JavaScript Optimization (Est. 84 KiB savings) - Lazy load react-syntax-highlighter with next/dynamic - Created CodeBlock component for async code highlighting - Reduces initial bundle size by deferring heavy syntax highlighter ## Bundle Configuration - Disable production source maps (reduces bundle size) - Add .browserslistrc targeting modern browsers (est. 12 KiB savings) - Remove legacy browser polyfills (IE11, old Android, etc.) ## Critical Rendering Path (Est. 300ms LCP improvement) - Add preconnect hint for api.github.com - Defer Google Analytics to lazyOnload strategy ## Caching Strategy - Add cache headers configuration for static assets - Cache-Control: public, max-age=31536000, immutable - Applied to _next/static/* and image assets ## Accessibility Fixes - Fix footer color contrast: text-zinc-500 → text-zinc-400 - Add prefers-reduced-motion media query support - All animations respect user motion preferences ## Expected Impact - Total estimated LCP reduction: ~1.5-2 seconds - Bundle size reduction: ~100 KB - Targeting 90+ performance score (up from 70)
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
"use client";
|
||||
|
||||
import React, { useState, useEffect } from "react";
|
||||
import dynamic from "next/dynamic";
|
||||
|
||||
// Lazy load syntax highlighter to reduce initial bundle size (~84KB savings)
|
||||
const SyntaxHighlighter = dynamic(
|
||||
() => import("react-syntax-highlighter").then(mod => mod.default),
|
||||
{
|
||||
ssr: false,
|
||||
loading: () => (
|
||||
<div className="bg-zinc-900 rounded-lg p-4 text-sm">
|
||||
<pre className="text-green-400 whitespace-pre-wrap">Loading...</pre>
|
||||
</div>
|
||||
),
|
||||
}
|
||||
);
|
||||
|
||||
interface CodeBlockProps {
|
||||
language: string;
|
||||
children: string;
|
||||
className?: string;
|
||||
customStyle?: React.CSSProperties;
|
||||
wrapLongLines?: boolean;
|
||||
}
|
||||
|
||||
export function CodeBlock({
|
||||
language,
|
||||
children,
|
||||
className = "",
|
||||
customStyle,
|
||||
wrapLongLines = false,
|
||||
}: CodeBlockProps) {
|
||||
const [style, setStyle] = useState<any>(null);
|
||||
|
||||
useEffect(() => {
|
||||
// Lazy load the style
|
||||
import("react-syntax-highlighter/dist/esm/styles/hljs").then(mod => {
|
||||
setStyle(mod.atomOneDark);
|
||||
});
|
||||
}, []);
|
||||
|
||||
if (!style) {
|
||||
return (
|
||||
<div className={`bg-zinc-900 rounded-lg p-4 text-sm ${className}`} style={customStyle}>
|
||||
<pre className="text-green-400 whitespace-pre-wrap">{children}</pre>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<SyntaxHighlighter
|
||||
language={language}
|
||||
style={style}
|
||||
className={className}
|
||||
customStyle={customStyle}
|
||||
wrapLongLines={wrapLongLines}
|
||||
>
|
||||
{children}
|
||||
</SyntaxHighlighter>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user