Files
voculinux/web/next.config.js
T
Jatin K MalikandGitHub 071b7b5da3 perf: optimize PageSpeed Insights performance score (#105) (#106)
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)
2026-01-30 22:47:59 -08:00

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;