diff --git a/index.html b/index.html
index b93eb30..f63a437 100644
--- a/index.html
+++ b/index.html
@@ -13,7 +13,6 @@
-
@@ -25,17 +24,12 @@
-
+
+
+
+
diff --git a/src/pages/Home.jsx b/src/pages/Home.jsx
index e827299..9c59371 100644
--- a/src/pages/Home.jsx
+++ b/src/pages/Home.jsx
@@ -6,6 +6,7 @@ import { CardEffects } from '../ui/CardEffects';
import { ScrollEffects } from '../ui/ScrollEffects';
function Home({ onMount }) {
+ const [isLoading, setIsLoading] = useState(true);
const [isLoaded, setIsLoaded] = useState(false);
const sceneRef = useRef(null);
const scrollEffectsRef = useRef(null);
@@ -13,31 +14,45 @@ function Home({ onMount }) {
useEffect(() => {
if (!isLoaded) {
- onMount?.();
- setIsLoaded(true);
+ const initializeApp = async () => {
+ try {
+ onMount?.();
+
+ // Initialize Three.js scene
+ const container = document.getElementById('bg-canvas');
+ if (container) {
+ sceneRef.current = new Scene(container, {
+ width: window.innerWidth,
+ height: window.innerHeight
+ });
+ sceneRef.current.animate(0);
+ }
- // Initialize Three.js scene
- const container = document.getElementById('bg-canvas');
- if (container) {
- sceneRef.current = new Scene(container, {
- width: window.innerWidth,
- height: window.innerHeight
- });
- sceneRef.current.animate(0);
- }
+ // Initialize effects
+ scrollEffectsRef.current = new ScrollEffects();
+ cardEffectsRef.current = new CardEffects();
+
+ setIsLoaded(true);
+ } catch (error) {
+ console.error('Initialization error:', error);
+ } finally {
+ setIsLoading(false);
+ }
+ };
- // Initialize effects
- scrollEffectsRef.current = new ScrollEffects();
- cardEffectsRef.current = new CardEffects();
+ initializeApp();
return () => {
sceneRef.current?.dispose();
scrollEffectsRef.current?.dispose();
- // CardEffects doesn't need disposal as it only adds event listeners
};
}
}, [isLoaded, onMount]);
+ if (isLoading) {
+ return ;
+ }
+
const containerVariants = {
hidden: { opacity: 0 },
visible: {
diff --git a/src/three/Scene.js b/src/three/Scene.js
index 61b1ce6..9e8e2ea 100644
--- a/src/three/Scene.js
+++ b/src/three/Scene.js
@@ -10,12 +10,25 @@ export class Scene {
this.scene = new THREE.Scene();
this.camera = new THREE.PerspectiveCamera(75, dimensions.width / dimensions.height, 0.1, 1000);
this.renderer = new THREE.WebGLRenderer({
- antialias: true,
- alpha: true
+ antialias: window.devicePixelRatio < 2,
+ powerPreference: "high-performance",
+ alpha: true,
+ stencil: false,
+ depth: true
});
+
+ // Optimize renderer
this.renderer.setSize(dimensions.width, dimensions.height);
+ this.renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
+ this.renderer.shadowMap.enabled = false;
+
container.appendChild(this.renderer.domElement);
+ // Reduce post-processing quality on mobile
+ const isMobile = window.innerWidth < 768;
+ const bloomStrength = isMobile ? 0.3 : 0.5;
+ const bloomRadius = isMobile ? 0.3 : 0.4;
+
this.composer = null;
this.flowField = new FlowField();
this.spheres = new Spheres();
@@ -24,7 +37,7 @@ export class Scene {
this.targetRotation = new THREE.Vector2();
this.lastTime = 0;
- this.frameInterval = 1000 / 30; // Target 30 FPS
+ this.frameInterval = 1000 / (isMobile ? 30 : 60);
this.frames = 0;
this.lastFpsUpdate = 0;
diff --git a/vite.config.js b/vite.config.js
index ab2d59e..20120d3 100644
--- a/vite.config.js
+++ b/vite.config.js
@@ -48,10 +48,11 @@ export default defineConfig({
headers: {
'Content-Security-Policy': `
default-src 'self';
- script-src 'self' 'unsafe-inline';
- style-src 'self' 'unsafe-inline';
+ script-src 'self' 'unsafe-inline' 'unsafe-eval';
+ style-src 'self' 'unsafe-inline' https://fonts.googleapis.com;
+ font-src 'self' https://fonts.gstatic.com;
img-src 'self' data: blob:;
- font-src 'self';
+ connect-src 'self' https://fonts.googleapis.com https://fonts.gstatic.com;
object-src 'none';
base-uri 'self';
form-action 'self';