optimization and moved link after description in project page

This commit is contained in:
kinou-p 2025-10-02 16:37:04 +02:00
parent 4895541c61
commit fb841cb17c
4 changed files with 73 additions and 67 deletions

View File

@ -4,6 +4,10 @@
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<!-- Preload des ressources critiques -->
<link rel="preload" as="script" href="/src/main.tsx" />
<title>Alexandre Pommier - Portfolio</title>
<meta name="description" content="Alexandre Pommier, étudiant en informatique à 42, développeur passionné par les technologies web et systèmes." />
<meta name="author" content="Alexandre Pommier" />
@ -17,10 +21,14 @@
<meta name="twitter:site" content="@lovable_dev" />
<meta name="twitter:image" content="https://lovable.dev/opengraph-image-p98pqg.png" />
<!-- Google Fonts -->
<!-- Google Fonts - Optimisé avec display=swap et preload -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="preload" as="style" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Montserrat:wght@400;500;600;700&display=swap">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Montserrat:wght@400;500;600;700&display=swap" rel="stylesheet" media="print" onload="this.media='all'">
<noscript>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Montserrat:wght@400;500;600;700&display=swap" rel="stylesheet">
</noscript>
<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':

View File

@ -8,11 +8,16 @@ export const ParticlesBackground = () => {
const { theme } = useTheme();
useEffect(() => {
// Retarder l'initialisation des particules pour ne pas bloquer le premier rendu
const timer = setTimeout(() => {
initParticlesEngine(async (engine) => {
await loadSlim(engine);
}).then(() => {
setInit(true);
});
}, 1000); // Attendre 1 seconde après le chargement initial
return () => clearTimeout(timer);
}, []);
const particlesLoaded = async (container) => {
@ -73,12 +78,12 @@ export const ParticlesBackground = () => {
density: {
enable: true,
},
value: 70,
value: 70, // Réduit de 70 à 30 pour de meilleures performances
},
opacity: {
value: { min: 0.1, max: theme === "dark" ? 0.5 : 0.6 },
animation: {
enable: true,
enable: false, // Désactiver l'animation d'opacité pour meilleures performances
speed: 3,
sync: false,
},
@ -89,14 +94,14 @@ export const ParticlesBackground = () => {
size: {
value: { min: 0.1, max: 5 },
animation: {
enable: true,
enable: false, // Désactiver l'animation de taille pour meilleures performances
speed: 20,
sync: false,
},
},
twinkle: {
lines: {
enable: true,
enable: false, // Désactiver le scintillement pour meilleures performances
frequency: 0.005,
opacity: 1,
color: {
@ -104,7 +109,7 @@ export const ParticlesBackground = () => {
}
},
particles: {
enable: true,
enable: false, // Désactiver le scintillement pour meilleures performances
frequency: 0.05,
opacity: 1,
color: {

View File

@ -1,16 +1,18 @@
import { useEffect } from "react";
import { useEffect, lazy, Suspense } from "react";
import { useLocation } from "react-router-dom";
import { Header } from "@/components/Header";
import { Footer } from "@/components/Footer";
import { ScrollProgress } from "@/components/ScrollProgress";
import { CookieBanner } from "@/components/CookieBanner";
import { HeroSection } from "@/components/sections/HeroSection";
import { ProjectsSection } from "@/components/sections/ProjectsSection";
import { SkillsSection } from "@/components/sections/SkillsSection";
import { ContactSection } from "@/components/sections/ContactSection";
import { LanguageProvider } from "@/contexts/LanguageContext";
import { CookieBannerProvider } from "@/contexts/CookieBannerContext";
// Lazy load des sections non critiques
const ProjectsSection = lazy(() => import("@/components/sections/ProjectsSection").then(module => ({ default: module.ProjectsSection })));
const SkillsSection = lazy(() => import("@/components/sections/SkillsSection").then(module => ({ default: module.SkillsSection })));
const ContactSection = lazy(() => import("@/components/sections/ContactSection").then(module => ({ default: module.ContactSection })));
const Index = () => {
const location = useLocation();
@ -34,9 +36,15 @@ const Index = () => {
<Header />
<main>
<HeroSection />
<Suspense fallback={<div className="py-20 md:py-32" />}>
<ProjectsSection />
</Suspense>
<Suspense fallback={<div className="py-20 md:py-32" />}>
<SkillsSection />
</Suspense>
<Suspense fallback={<div className="py-20 md:py-32" />}>
<ContactSection />
</Suspense>
</main>
<Footer />
<CookieBanner />

View File

@ -103,9 +103,40 @@ const ProjectPageContent = () => {
<h2 className="text-3xl md:text-4xl font-bold mb-6">
{t("project.description") || "Description"}
</h2>
<p className="text-lg text-muted-foreground leading-relaxed mb-12">
<p className="text-lg text-muted-foreground leading-relaxed mb-6">
{project.detailedDescription[language]}
</p>
{/* Liens intégrés dans la description */}
{(project.githubUrl || project.demoUrl) && (
<div className="flex flex-wrap gap-3 mb-12">
{project.githubUrl && (
<Button
variant="outline"
size="sm"
asChild
className="gap-2"
>
<a href={project.githubUrl} target="_blank" rel="noopener noreferrer">
<Github className="w-4 h-4" />
{t("project.viewGithub") || "View on GitHub"}
</a>
</Button>
)}
{project.demoUrl && (
<Button
size="sm"
asChild
className="gap-2"
>
<a href={project.demoUrl} target="_blank" rel="noopener noreferrer">
<ExternalLink className="w-4 h-4" />
{t("project.viewDemo") || "View Live Demo"}
</a>
</Button>
)}
</div>
)}
</motion.div>
<div className="grid md:grid-cols-2 gap-8">
@ -198,54 +229,8 @@ const ProjectPageContent = () => {
</section>
)}
{/* Links Section */}
{(project.githubUrl || project.demoUrl) && (
<section className="py-20 bg-muted/30">
<div className="container mx-auto px-4">
<motion.div
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.5 }}
className="max-w-4xl mx-auto text-center"
>
<h2 className="text-3xl md:text-4xl font-bold mb-8">
{t("project.links") || "Project Links"}
</h2>
<div className="flex flex-wrap gap-4 justify-center">
{project.githubUrl && (
<Button
variant="outline"
size="lg"
asChild
className="gap-2"
>
<a href={project.githubUrl} target="_blank" rel="noopener noreferrer">
<Github className="w-5 h-5" />
{t("project.viewGithub") || "View on GitHub"}
</a>
</Button>
)}
{project.demoUrl && (
<Button
size="lg"
asChild
className="gap-2"
>
<a href={project.demoUrl} target="_blank" rel="noopener noreferrer">
<ExternalLink className="w-5 h-5" />
{t("project.viewDemo") || "View Live Demo"}
</a>
</Button>
)}
</div>
</motion.div>
</div>
</section>
)}
{/* CTA Section */}
<section className="py-20">
<section className="py-20 bg-muted/30">
<div className="container mx-auto px-4">
<motion.div
initial={{ opacity: 0, y: 20 }}