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)
77 lines
1.5 KiB
JavaScript
77 lines
1.5 KiB
JavaScript
// @ts-ignore
|
|
/** @type {import("next").NextConfig} */
|
|
const config = {
|
|
output: 'export',
|
|
trailingSlash: true,
|
|
// Configuration for custom domain deployment
|
|
distDir: 'out',
|
|
|
|
// Configure cache headers for static assets
|
|
// This generates a _headers file for platforms like Netlify/Vercel
|
|
async headers() {
|
|
return [
|
|
{
|
|
source: '/_next/static/:path*',
|
|
headers: [
|
|
{
|
|
key: 'Cache-Control',
|
|
value: 'public, max-age=31536000, immutable',
|
|
},
|
|
],
|
|
},
|
|
{
|
|
source: '/:all*(svg|jpg|jpeg|png|webp|avif|ico|woff|woff2)',
|
|
headers: [
|
|
{
|
|
key: 'Cache-Control',
|
|
value: 'public, max-age=31536000, immutable',
|
|
},
|
|
],
|
|
},
|
|
];
|
|
},
|
|
images: {
|
|
unoptimized: true,
|
|
remotePatterns: [
|
|
{
|
|
protocol: 'https',
|
|
hostname: '*',
|
|
pathname: '**',
|
|
},
|
|
],
|
|
},
|
|
eslint: {
|
|
ignoreDuringBuilds: true,
|
|
},
|
|
typescript: {
|
|
ignoreBuildErrors: true,
|
|
},
|
|
// Disable source maps in production to reduce bundle size
|
|
productionBrowserSourceMaps: false,
|
|
webpack: (config, { isServer, dev }) => {
|
|
// Only use source maps in development
|
|
if (!dev) {
|
|
config.devtool = false;
|
|
}
|
|
// Enhanced node polyfills for postgres and other modules
|
|
if (!isServer) {
|
|
config.resolve.fallback = {
|
|
...config.resolve.fallback,
|
|
// File system - never needed in browser
|
|
fs: false,
|
|
net: false,
|
|
tls: false,
|
|
crypto: false,
|
|
stream: false,
|
|
'perf_hooks': false,
|
|
|
|
// Definitely not needed in browser
|
|
child_process: false,
|
|
dns: false,
|
|
};
|
|
}
|
|
return config;
|
|
},
|
|
};
|
|
export default config;
|