1- import React from 'react' ;
1+ import React , { useEffect , useRef , useState , Suspense } from 'react' ;
22import 'bootstrap/dist/css/bootstrap.min.css' ;
33import './App.css' ;
44
55import { ThemeProvider } from './contexts/ThemeContext' ;
66import Navbar from './components/Navbar' ;
77import Hero from './components/Hero' ;
8- import About from './components/About' ;
9- import Projects from './components/Projects' ;
10- import Contact from './components/Contact' ;
11- import Footer from './components/Footer' ;
128import DecorativeElement from './components/DecorativeElement' ;
13- import Timeline from './components/Timeline' ;
9+ const About = React . lazy ( ( ) => import ( './components/About' ) ) ;
10+ const Projects = React . lazy ( ( ) => import ( './components/Projects' ) ) ;
11+ const Contact = React . lazy ( ( ) => import ( './components/Contact' ) ) ;
12+ const Footer = React . lazy ( ( ) => import ( './components/Footer' ) ) ;
13+ const Timeline = React . lazy ( ( ) => import ( './components/Timeline' ) ) ;
14+
15+ function LazySection ( { children, rootMargin = '200px' } ) {
16+ const [ isVisible , setIsVisible ] = useState ( false ) ;
17+ const containerRef = useRef ( null ) ;
18+
19+ useEffect ( ( ) => {
20+ const observer = new IntersectionObserver (
21+ ( [ entry ] ) => {
22+ if ( entry . isIntersecting ) {
23+ setIsVisible ( true ) ;
24+ observer . disconnect ( ) ;
25+ }
26+ } ,
27+ { root : null , rootMargin, threshold : 0.1 }
28+ ) ;
29+
30+ if ( containerRef . current ) {
31+ observer . observe ( containerRef . current ) ;
32+ }
33+
34+ return ( ) => observer . disconnect ( ) ;
35+ } , [ rootMargin ] ) ;
36+
37+ return < div ref = { containerRef } > { isVisible ? children : null } </ div > ;
38+ }
1439
1540function App ( ) {
1641 return (
@@ -19,14 +44,34 @@ function App() {
1944 < Navbar />
2045 < Hero />
2146 < DecorativeElement type = "music-note" position = "right" />
22- < About />
47+ < LazySection >
48+ < Suspense fallback = { null } >
49+ < About />
50+ </ Suspense >
51+ </ LazySection >
2352 < DecorativeElement type = "music-note" position = "left" />
24- < Timeline />
53+ < LazySection >
54+ < Suspense fallback = { null } >
55+ < Timeline />
56+ </ Suspense >
57+ </ LazySection >
2558 < DecorativeElement type = "diamond" position = "right" />
26- < Projects />
59+ < LazySection >
60+ < Suspense fallback = { null } >
61+ < Projects />
62+ </ Suspense >
63+ </ LazySection >
2764 < DecorativeElement type = "corner" position = "right" />
28- < Contact />
29- < Footer />
65+ < LazySection >
66+ < Suspense fallback = { null } >
67+ < Contact />
68+ </ Suspense >
69+ </ LazySection >
70+ < LazySection >
71+ < Suspense fallback = { null } >
72+ < Footer />
73+ </ Suspense >
74+ </ LazySection >
3075 </ div >
3176 </ ThemeProvider >
3277 ) ;
0 commit comments