diff --git a/index.html b/index.html index 932ebc2..30c90af 100644 --- a/index.html +++ b/index.html @@ -7,7 +7,7 @@ - + @@ -33,14 +33,25 @@ - - + + + - + +
diff --git a/package.json b/package.json index 12c787f..1048b52 100644 --- a/package.json +++ b/package.json @@ -11,8 +11,7 @@ "lint": "eslint .", "preview": "vite preview", "optimize-images": "node scripts/optimize-images.js", - "analyze": "node scripts/analyze-bundle.js", - "analyze:js": "node scripts/analyze-js-bundle.js" + "analyze": "node scripts/analyze-bundle.js" }, "dependencies": { "@hookform/resolvers": "^3.10.0", diff --git a/src/App.tsx b/src/App.tsx index 5d9bd8e..594f1a8 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -6,30 +6,15 @@ import { createBrowserRouter, RouterProvider } from "react-router-dom"; import { lazy, Suspense } from "react"; import { ThemeProvider } from "./contexts/ThemeContext"; -// Lazy load pages et composants lourds pour de meilleures performances -// Cela réduit la quantité de JavaScript chargé initialement +// Lazy load pages and heavy components for better performance const Index = lazy(() => import("./pages/Index")); const ProjectPage = lazy(() => import("./pages/ProjectPage")); const NotFound = lazy(() => import("./pages/NotFound")); +const ParticlesBackground = lazy(() => import("./components/ParticlesBackground").then(m => ({ default: m.ParticlesBackground }))); -// ParticlesBackground est chargé en lazy car non critique pour le FCP/LCP -const ParticlesBackground = lazy(() => - import("./components/ParticlesBackground").then(m => ({ default: m.ParticlesBackground })) -); +const queryClient = new QueryClient(); -// Configuration QueryClient optimisée -const queryClient = new QueryClient({ - defaultOptions: { - queries: { - staleTime: 1000 * 60 * 5, // 5 minutes - gcTime: 1000 * 60 * 10, // 10 minutes - refetchOnWindowFocus: false, - retry: 1, - }, - }, -}); - -// Loading fallback component minimal +// Loading fallback component const PageLoader = () => (
diff --git a/src/components/ProjectCard.tsx b/src/components/ProjectCard.tsx index ee1db68..f4fde30 100644 --- a/src/components/ProjectCard.tsx +++ b/src/components/ProjectCard.tsx @@ -27,16 +27,16 @@ export const ProjectCard = ({ title, description, icon, image, technologies, del initial={{ opacity: 0, y: 20 }} whileInView={{ opacity: 1, y: 0 }} viewport={{ once: true }} - transition={{ duration: 0.2, delay }} - whileHover={{ y: -8, transition: { duration: 0.2 } }} + transition={{ duration: 0.5, delay }} + whileHover={{ y: -5 }} onClick={handleClick} className={projectId ? "cursor-pointer" : ""} > - + {/* Indicateur cliquable en bas à droite */} {projectId && ( -
- +
+
)} diff --git a/vite.config.ts b/vite.config.ts index cbc950c..6fddb7a 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -30,60 +30,17 @@ export default defineConfig(({ mode }) => ({ // Chunking optimal pour de meilleures performances rollupOptions: { output: { - // Split vendors pour améliorer le cache et réduire le code inutilisé - manualChunks: (id) => { - // Ignorer les node_modules non critiques - if (id.includes('node_modules')) { - // React core - bundle séparé pour un meilleur cache - if (id.includes('/react/') || id.includes('/react-dom/') || id.includes('/scheduler/')) { - return 'react-core'; - } - - // React Router - souvent utilisé - if (id.includes('/react-router-dom/') || id.includes('/@remix-run/')) { - return 'react-router'; - } - - // Radix UI - grouper tous les composants ensemble avec tree-shaking - if (id.includes('@radix-ui/')) { - return 'radix-ui'; - } - - // Framer Motion - animations (peut être volumineux) - if (id.includes('/framer-motion/')) { - return 'animations'; - } - - // Lucide React - icônes (volumineux) - if (id.includes('/lucide-react/')) { - return 'icons'; - } - - // tsparticles - animations de fond (optionnel) - if (id.includes('@tsparticles/') || id.includes('/tsparticles/')) { - return 'particles'; - } - - // TanStack Query - if (id.includes('@tanstack/')) { - return 'tanstack'; - } - - // Autres dépendances moins critiques - return 'vendor'; - } + // Split vendors pour améliorer le cache + manualChunks: { + 'react-vendor': ['react', 'react-dom', 'react-router-dom'], + 'ui-vendor': ['framer-motion', 'lucide-react'], + 'particles': ['@tsparticles/react', '@tsparticles/slim', '@tsparticles/engine'], }, // Nommer les chunks de manière cohérente pour le cache chunkFileNames: 'assets/js/[name]-[hash].js', entryFileNames: 'assets/js/[name]-[hash].js', assetFileNames: 'assets/[ext]/[name]-[hash].[ext]', }, - // Optimisations supplémentaires pour le tree-shaking - treeshake: { - moduleSideEffects: 'no-external', // Pas d'effets de bord pour les modules externes - propertyReadSideEffects: false, - unknownGlobalSideEffects: false, - }, }, // Optimisation des assets assetsInlineLimit: 4096, // Images < 4kb seront inline en base64