From 0ea661b766b7bee8fe1acf06ab6eddd5094105b1 Mon Sep 17 00:00:00 2001 From: NicolasCantu Date: Wed, 29 Oct 2025 16:56:41 +0100 Subject: [PATCH] fix: improve memory management for WebAssembly initialization MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit **Motivations :** - WebAssembly échoue même avec 40% de mémoire utilisée, nécessite au moins 150MB disponibles - Ajouter une vérification mémoire plus stricte avant d'importer WebAssembly - Améliorer le nettoyage mémoire dans wallet-setup avant l'initialisation **Modifications :** - Ajouter vérification mémoire avant import WebAssembly dans service.ts init() - Vérifier que plus de 150MB sont disponibles ou moins de 85% utilisés - Améliorer nettoyage mémoire dans wallet-setup si >75% utilisé - Lancer erreur explicite si mémoire insuffisante avec détails **Pages affectées :** - src/services/service.ts (vérification mémoire avant import WebAssembly) - src/pages/wallet-setup/wallet-setup.ts (nettoyage mémoire amélioré) --- src/pages/wallet-setup/wallet-setup.ts | 48 ++++++++++++++++++++++++++ src/services/service.ts | 31 +++++++++++++---- 2 files changed, 73 insertions(+), 6 deletions(-) diff --git a/src/pages/wallet-setup/wallet-setup.ts b/src/pages/wallet-setup/wallet-setup.ts index dd6f625..53568a2 100644 --- a/src/pages/wallet-setup/wallet-setup.ts +++ b/src/pages/wallet-setup/wallet-setup.ts @@ -74,6 +74,54 @@ document.addEventListener('DOMContentLoaded', async () => { updateStatus('🔄 Initialisation des services...', 'loading'); updateProgress(20); + // Vérifier la mémoire avant d'initialiser WebAssembly + if ((performance as any).memory) { + const memory = (performance as any).memory; + const usedPercent = (memory.usedJSHeapSize / memory.jsHeapSizeLimit) * 100; + const usedMB = memory.usedJSHeapSize / 1024 / 1024; + const limitMB = memory.jsHeapSizeLimit / 1024 / 1024; + + console.log(`📊 Current memory usage: ${usedPercent.toFixed(1)}% (${usedMB.toFixed(1)}MB / ${limitMB.toFixed(1)}MB)`); + + // Si la mémoire est très élevée (>75%), tenter un nettoyage agressif + if (usedPercent > 75) { + console.warn('⚠️ High memory usage detected, attempting aggressive cleanup...'); + updateStatus('🧹 Nettoyage de la mémoire en cours...', 'loading'); + + // Nettoyage agressif + if (window.gc) { + for (let i = 0; i < 3; i++) { + window.gc(); + await new Promise(resolve => setTimeout(resolve, 100)); + } + } + + // Nettoyer les caches HTTP + if ('caches' in window) { + try { + const cacheNames = await caches.keys(); + await Promise.all(cacheNames.map(name => caches.delete(name))); + console.log('🧹 Caches cleared'); + } catch (e) { + console.warn('⚠️ Cache cleanup error:', e); + } + } + + // Vérifier la mémoire après nettoyage + const memoryAfter = (performance as any).memory; + const usedPercentAfter = (memoryAfter.usedJSHeapSize / memoryAfter.jsHeapSizeLimit) * 100; + console.log(`📊 Memory after cleanup: ${usedPercentAfter.toFixed(1)}% (${(memoryAfter.usedJSHeapSize / 1024 / 1024).toFixed(1)}MB)`); + + // Si toujours >90% après nettoyage, avertir l'utilisateur + if (usedPercentAfter > 90) { + console.error('❌ Memory still too high after cleanup'); + updateStatus('⚠️ Mémoire trop élevée. Fermez les autres onglets et actualisez la page.', 'error'); + alert('⚠️ Mémoire insuffisante détectée.\n\nVeuillez :\n- Fermer les autres onglets du navigateur\n- Actualiser cette page\n\nSi le problème persiste, redémarrez le navigateur.'); + return; + } + } + } + let services: any; // Déclarer services au niveau supérieur try { diff --git a/src/services/service.ts b/src/services/service.ts index e05c9a2..7822d9c 100755 --- a/src/services/service.ts +++ b/src/services/service.ts @@ -309,18 +309,21 @@ export default class Services { if ((performance as any).memory) { const memory = (performance as any).memory; const usedPercent = (memory.usedJSHeapSize / memory.jsHeapSizeLimit) * 100; + const availableMB = (memory.jsHeapSizeLimit - memory.usedJSHeapSize) / 1024 / 1024; - if (usedPercent > 98) { - console.log('🚫 Memory too high, skipping WebAssembly initialization'); - Services.instance = new Services(); + console.log(`📊 Memory check before WebAssembly: ${usedPercent.toFixed(1)}% used, ${availableMB.toFixed(1)}MB available`); + + // WebAssembly nécessite généralement au moins 100-200MB de mémoire disponible + // Si moins de 150MB disponibles ou plus de 85% utilisé, ne pas initialiser + if (usedPercent > 85 || availableMB < 150) { + console.error(`🚫 Memory insufficient for WebAssembly: ${usedPercent.toFixed(1)}% used, ${availableMB.toFixed(1)}MB available`); Services.initializing = null; - console.log('✅ Services initialized without WebAssembly'); - return Services.instance; + throw new Error(`Insufficient memory for WebAssembly initialization. Current usage: ${usedPercent.toFixed(1)}%, Available: ${availableMB.toFixed(1)}MB. Please close other tabs and refresh.`); } } // Memory is sufficient, load WebAssembly - Services.instance = await Services.initializing; + Services.instance = await Services.initializing; Services.initializing = null; console.log('✅ Services initialized with WebAssembly'); @@ -347,6 +350,22 @@ export default class Services { public async init(): Promise { this.notifications = this.getNotifications(); + + // Vérifier la mémoire avant d'importer WebAssembly + if ((performance as any).memory) { + const memory = (performance as any).memory; + const usedPercent = (memory.usedJSHeapSize / memory.jsHeapSizeLimit) * 100; + const availableMB = (memory.jsHeapSizeLimit - memory.usedJSHeapSize) / 1024 / 1024; + + console.log(`📊 Memory check before WebAssembly import: ${usedPercent.toFixed(1)}% used, ${availableMB.toFixed(1)}MB available`); + + // WebAssembly nécessite au moins 150MB de mémoire disponible + if (usedPercent > 85 || availableMB < 150) { + console.error(`🚫 Memory insufficient for WebAssembly import: ${usedPercent.toFixed(1)}% used, ${availableMB.toFixed(1)}MB available`); + throw new Error(`Insufficient memory for WebAssembly. Current usage: ${usedPercent.toFixed(1)}%, Available: ${availableMB.toFixed(1)}MB. Please close other tabs and refresh.`); + } + } + this.sdkClient = await import('../../pkg/sdk_client'); this.sdkClient.setup(); for (const wsurl of Object.values(BOOTSTRAPURL)) {