Skip to content

Commit

Permalink
update performance
Browse files Browse the repository at this point in the history
  • Loading branch information
wheattoast11 committed Nov 30, 2024
1 parent 635e48f commit 0f6088a
Show file tree
Hide file tree
Showing 6 changed files with 135 additions and 71 deletions.
35 changes: 23 additions & 12 deletions src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import React, { Suspense, lazy, useEffect } from 'react';
import { HashRouter as Router, Routes, Route } from 'react-router-dom';
import {
createBrowserRouter,
RouterProvider,
UNSAFE_DataRouterContext,
UNSAFE_DataRouterStateContext
} from 'react-router-dom';
import LoadingState from './components/LoadingState';
import Canvas from './components/Canvas';
import ErrorBoundary from './components/ErrorBoundary';
Expand All @@ -9,6 +14,22 @@ import reportWebVitals from './utils/reportWebVitals';
const Home = lazy(() => import('./pages/Home'));
const Manifesto = lazy(() => import('./pages/Manifesto'));

const router = createBrowserRouter([
{
path: "/",
element: <Home />,
},
{
path: "/manifesto",
element: <Manifesto />,
}
], {
future: {
v7_startTransition: true,
v7_relativeSplatPath: true
}
});

function App() {
useEffect(() => {
if ('performance' in window) {
Expand All @@ -19,17 +40,7 @@ function App() {

return (
<ErrorBoundary>
<Router>
<div style={{ position: 'relative', minHeight: '100vh' }}>
<Canvas />
<Suspense fallback={<LoadingState />}>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/manifesto" element={<Manifesto />} />
</Routes>
</Suspense>
</div>
</Router>
<RouterProvider router={router} />
</ErrorBoundary>
);
}
Expand Down
75 changes: 30 additions & 45 deletions src/components/Canvas.jsx
Original file line number Diff line number Diff line change
@@ -1,61 +1,46 @@
import React, { useEffect, useRef, useState } from 'react';
import React, { useEffect, useRef, useState, useCallback } from 'react';
import { Scene } from '../three/Scene';

function Canvas() {
const containerRef = useRef(null);
const sceneRef = useRef(null);
const [dimensions, setDimensions] = useState({ width: 0, height: 0 });
const [scene, setScene] = useState(null);

// Handle resize
useEffect(() => {
const handleResize = () => {
if (containerRef.current) {
setDimensions({
width: containerRef.current.clientWidth,
height: containerRef.current.clientHeight
});
}
};

// Initial size
handleResize();

window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
const handleResize = useCallback(() => {
if (containerRef.current) {
const { clientWidth, clientHeight } = containerRef.current;
setDimensions({ width: clientWidth, height: clientHeight });
}
}, []);

// Initialize scene
useEffect(() => {
if (!containerRef.current || dimensions.width === 0 || dimensions.height === 0) {
return;
const resizeObserver = new ResizeObserver(handleResize);
if (containerRef.current) {
resizeObserver.observe(containerRef.current);
}
return () => resizeObserver.disconnect();
}, [handleResize]);

try {
const newScene = new Scene(containerRef.current, dimensions);
setScene(prev => {
if (prev) {
prev.dispose();
}
return newScene;
});

// Start animation
const animate = () => {
if (newScene) {
newScene.animate();
}
requestAnimationFrame(animate);
};
animate();
useEffect(() => {
if (!containerRef.current || dimensions.width === 0) return;

return () => {
if (newScene) {
newScene.dispose();
}
};
try {
if (!sceneRef.current) {
sceneRef.current = new Scene(containerRef.current, dimensions);
sceneRef.current.animate(0);
} else {
sceneRef.current.resize(dimensions);
}
} catch (error) {
console.error('Error initializing scene:', error);
console.error('Scene initialization error:', error);
}

return () => {
if (sceneRef.current) {
sceneRef.current.dispose();
sceneRef.current = null;
}
};
}, [dimensions]);

return (
Expand All @@ -76,4 +61,4 @@ function Canvas() {
);
}

export default Canvas;
export default React.memo(Canvas);
5 changes: 5 additions & 0 deletions src/main.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ import React from 'react';
import { createRoot } from 'react-dom/client';
import App from './App';
import '../style.css';
import { initPerformanceMonitoring } from './utils/performance';

if (process.env.NODE_ENV === 'development') {
initPerformanceMonitoring();
}

// Create React root and render App
const root = createRoot(document.getElementById('root'));
Expand Down
47 changes: 37 additions & 10 deletions src/three/Scene.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ export class Scene {
this.mouse = new THREE.Vector2();
this.targetRotation = new THREE.Vector2();

this.lastTime = 0;
this.frameInterval = 1000 / 30; // Target 30 FPS

this.frames = 0;
this.lastFpsUpdate = 0;

this.init();
this.setupLights();
this.setupPostProcessing();
Expand Down Expand Up @@ -85,20 +91,41 @@ export class Scene {
});
}

animate() {
requestAnimationFrame(this.animate.bind(this));
this.time += 0.001;
animate(currentTime) {
// Skip frames to maintain target FPS
if (currentTime - this.lastTime < this.frameInterval) {
requestAnimationFrame(this.animate.bind(this));
return;
}

// Calculate delta time
const deltaTime = currentTime - this.lastTime;
this.lastTime = currentTime;

// Smooth camera rotation
this.camera.rotation.x += (this.targetRotation.x - this.camera.rotation.x) * 0.05;
this.camera.rotation.y += (this.targetRotation.y - this.camera.rotation.y) * 0.05;
// FPS monitoring
this.frames++;
if (currentTime - this.lastFpsUpdate > 1000) {
console.debug('FPS:', this.frames);
this.frames = 0;
this.lastFpsUpdate = currentTime;
}

// Update components
this.flowField.update(this.time);
this.spheres.update(this.time);
// Batch geometry updates
this.flowField.update(this.time, deltaTime);
this.spheres.update(this.time, deltaTime);

// Use lower quality settings on mobile
if (window.innerWidth < 768) {
this.renderer.setPixelRatio(1);
this.composer.passes.forEach(pass => {
if (pass.uniforms?.resolution) {
pass.uniforms.resolution.value.set(window.innerWidth/2, window.innerHeight/2);
}
});
}

// Render with post-processing
this.composer.render();
requestAnimationFrame(this.animate.bind(this));
}

dispose() {
Expand Down
33 changes: 33 additions & 0 deletions src/utils/performance.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
export const initPerformanceMonitoring = () => {
// Create PerformanceObserver
const perfObserver = new PerformanceObserver((list) => {
list.getEntries().forEach((entry) => {
// Log only significant performance issues
if (entry.duration > 50) {
console.warn(`Performance entry: ${entry.name} took ${entry.duration}ms`);
}
});
});

// Observe paint timing
perfObserver.observe({ entryTypes: ['paint', 'largest-contentful-paint'] });

// Monitor long tasks
const longTaskObserver = new PerformanceObserver((list) => {
list.getEntries().forEach((entry) => {
console.warn(`Long task detected: ${entry.duration}ms`);
});
});

longTaskObserver.observe({ entryTypes: ['longtask'] });

// Monitor memory usage
if (performance.memory) {
setInterval(() => {
const { usedJSHeapSize, totalJSHeapSize } = performance.memory;
const usedMB = Math.round(usedJSHeapSize / 1024 / 1024);
const totalMB = Math.round(totalJSHeapSize / 1024 / 1024);
console.debug(`Memory usage: ${usedMB}MB / ${totalMB}MB`);
}, 10000);
}
};
11 changes: 7 additions & 4 deletions vite.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export default defineConfig({
manualChunks: {
'vendor': ['react', 'react-dom', 'react-router-dom'],
'three': ['three'],
'animation': ['framer-motion', 'pts']
'animation': ['framer-motion']
}
}
},
Expand All @@ -20,16 +20,19 @@ export default defineConfig({
minify: 'terser',
terserOptions: {
compress: {
drop_console: false,
drop_debugger: false
drop_console: true,
drop_debugger: true
}
}
},
resolve: {
extensions: ['.js', '.jsx']
},
optimizeDeps: {
include: ['three', 'framer-motion', 'pts']
include: ['three', 'framer-motion'],
esbuildOptions: {
target: 'esnext'
}
},
server: {
headers: {
Expand Down

0 comments on commit 0f6088a

Please sign in to comment.