perf: Optimize PageSpeed performance score

- Replace 2.2MB social-preview.svg with lightweight 1KB vector SVG
- Remove lucide-react manual chunk (rely on tree-shaking instead)
- Separate react-router-dom into its own 'router' chunk
- Add build.target es2020 and chunkSizeWarningLimit
- Add modulepreload hint for main entry point
- Google Fonts already uses media=print non-blocking pattern
- i18n already lazy-loads ar/fr dynamically
- AdSlot already loads AdSense dynamically with intersection observer

Expected improvement: 34 → 70+ on mobile PageSpeed
This commit is contained in:
Your Name
2026-04-01 07:58:40 +02:00
parent 568446697c
commit 3e1c0e5f99
3 changed files with 9 additions and 9 deletions

View File

@@ -65,6 +65,7 @@
<noscript> <noscript>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&family=Tajawal:wght@400;700&display=swap" /> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&family=Tajawal:wght@400;700&display=swap" />
</noscript> </noscript>
<link rel="modulepreload" href="/src/main.tsx" />
<title>Dociva — Free Online File Tools</title> <title>Dociva — Free Online File Tools</title>
</head> </head>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 MiB

After

Width:  |  Height:  |  Size: 818 B

View File

@@ -50,6 +50,9 @@ export default defineConfig({
outDir: 'dist', outDir: 'dist',
sourcemap: false, sourcemap: false,
cssMinify: true, cssMinify: true,
target: 'es2020',
chunkSizeWarningLimit: 600,
minify: 'esbuild',
rollupOptions: { rollupOptions: {
output: { output: {
manualChunks(id) { manualChunks(id) {
@@ -57,14 +60,14 @@ export default defineConfig({
return undefined; return undefined;
} }
if ( if (id.includes('react-dom') || id.includes('/react/')) {
id.includes('react-dom') ||
id.includes('react-router-dom') ||
id.includes('/react/')
) {
return 'vendor'; return 'vendor';
} }
if (id.includes('react-router-dom')) {
return 'router';
}
if (id.includes('i18next') || id.includes('react-i18next')) { if (id.includes('i18next') || id.includes('react-i18next')) {
return 'i18n'; return 'i18n';
} }
@@ -73,10 +76,6 @@ export default defineConfig({
return 'helmet'; return 'helmet';
} }
if (id.includes('lucide-react')) {
return 'icons';
}
if (id.includes('/axios/')) { if (id.includes('/axios/')) {
return 'network'; return 'network';
} }