Monorepo for Aesthetic.Computer aesthetic.computer
4
fork

Configure Feed

Select the types of activity you want to include in your feed.

perf: reduce boot delay — race WS vs HTTP, fastest wins

Production: 100ms WS grace (down from 2000ms) then straight to HTTP
via Cloudflare edge cache. WS still races if it connected in time.
Localhost: 800ms WS wait preserved for hot-reload.

importWithRetry always races both paths when WS is available —
no more sequential fallback. Siberian users on Cloudflare Moscow
POP now get cached .mjs files without waiting for a WebSocket
connection to NYC.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

+45 -54
+45 -54
system/public/aesthetic.computer/boot.mjs
··· 713 713 const IMPORT_MAX_RETRIES = 3; 714 714 const IMPORT_RETRY_DELAY = 1500; 715 715 716 - async function importWithRetry(modulePath, retries = IMPORT_MAX_RETRIES, useWsBundle = false) { 717 - const loader = window.acModuleLoader; 718 - const isLocalhost = window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1'; 719 - const retryDelay = isLocalhost ? 300 : IMPORT_RETRY_DELAY; 720 - let triedWs = false; 721 - 722 - const clearLoaderCacheForPath = async (relativePath) => { 723 - if (!loader || !relativePath) return; 724 - try { loader.modules?.delete?.(relativePath); } catch (_) {} 725 - try { loader.blobUrls?.delete?.(relativePath); } catch (_) {} 726 - try { loader.bundleContents?.delete?.(relativePath); } catch (_) {} 727 - if (loader.db) { 728 - try { 729 - const tx = loader.db.transaction("modules", "readwrite"); 730 - tx.objectStore("modules").delete(relativePath); 731 - } catch (_) {} 732 - } 733 - }; 716 + async function importWithRetry(modulePath, retries = IMPORT_MAX_RETRIES, useWsBundle = false) { 717 + const loader = window.acModuleLoader; 718 + const isLocalhost = window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1'; 719 + const retryDelay = isLocalhost ? 300 : IMPORT_RETRY_DELAY; 720 + let triedWs = false; 721 + 722 + const clearLoaderCacheForPath = async (relativePath) => { 723 + if (!loader || !relativePath) return; 724 + try { loader.modules?.delete?.(relativePath); } catch (_) {} 725 + try { loader.blobUrls?.delete?.(relativePath); } catch (_) {} 726 + try { loader.bundleContents?.delete?.(relativePath); } catch (_) {} 727 + if (loader.db) { 728 + try { 729 + const tx = loader.db.transaction("modules", "readwrite"); 730 + tx.objectStore("modules").delete(relativePath); 731 + } catch (_) {} 732 + } 733 + }; 734 734 735 735 const waitForWsConnection = async () => { 736 736 if (!loader?.connecting) return; 737 + // Short grace: if WS is almost connected, let it finish. 738 + // Otherwise HTTP wins the race anyway. 737 739 await Promise.race([ 738 740 loader.connecting, 739 - new Promise(resolve => setTimeout(resolve, 400)) 741 + new Promise(resolve => setTimeout(resolve, isLocalhost ? 400 : 50)) 740 742 ]); 741 743 }; 742 744 743 - const tryLoadViaWs = async () => { 744 - if (!loader?.loadWithDeps) throw new Error('ws-unavailable'); 745 - triedWs = true; 746 - await waitForWsConnection(); 747 - if (!loader.connected) throw new Error('ws-not-connected'); 748 - const relativePath = modulePath.replace(/^\.\//, '').split('?')[0]; 749 - // Respect cache-busted URLs by clearing cached module before WS load. 750 - if (modulePath.includes('?v=')) { 751 - await clearLoaderCacheForPath(relativePath); 752 - } 753 - const blobUrl = await loader.loadWithDeps(relativePath, 5000); 754 - if (blobUrl && blobUrl.startsWith('blob:')) { 755 - return await import(blobUrl); 756 - } 745 + const tryLoadViaWs = async () => { 746 + if (!loader?.loadWithDeps) throw new Error('ws-unavailable'); 747 + triedWs = true; 748 + await waitForWsConnection(); 749 + if (!loader.connected) throw new Error('ws-not-connected'); 750 + const relativePath = modulePath.replace(/^\.\//, '').split('?')[0]; 751 + // Respect cache-busted URLs by clearing cached module before WS load. 752 + if (modulePath.includes('?v=')) { 753 + await clearLoaderCacheForPath(relativePath); 754 + } 755 + const blobUrl = await loader.loadWithDeps(relativePath, 5000); 756 + if (blobUrl && blobUrl.startsWith('blob:')) { 757 + return await import(blobUrl); 758 + } 757 759 throw new Error('ws-missing-blob'); 758 760 }; 759 761 ··· 771 773 } 772 774 }); 773 775 774 - // Parallel paths on localhost or when explicitly requested 775 - // Skip WS race if loader already confirmed not connected (avoids unnecessary delays) 776 - if ((useWsBundle || isLocalhost) && loader?.connected !== false) { 776 + // Race WS vs HTTP — fastest wins. Always include HTTP. 777 + // If WS is connected (or connecting on localhost), race both paths. 778 + const wsAvailable = loader?.connected || ((useWsBundle || isLocalhost) && loader?.connected !== false); 779 + if (wsAvailable) { 777 780 try { 778 781 return await raceToSuccess([tryLoadViaWs(), tryLoadViaHttp()]); 779 782 } catch (err) { 780 783 // Fall through to retry loop 781 - } 782 - } else if (useWsBundle || isLocalhost) { 783 - // Loader is confirmed disconnected — just use HTTP directly 784 - try { 785 - return await tryLoadViaHttp(); 786 - } catch (err) { 787 - // Fall through to retry loop 788 - } 789 - } else if (loader?.connected) { 790 - // Opportunistic WS load even if boot decided not to wait 791 - try { 792 - return await tryLoadViaWs(); 793 - } catch (err) { 794 - // Fall through to HTTP 795 784 } 796 785 } 797 786 ··· 883 872 884 873 let boot, parse, slug; 885 874 try { 886 - // 🚀 Wait for WebSocket module loader (max 2s total, already started at top of file) 887 - // This ensures we USE the WebSocket when available instead of falling back to HTTP 888 - // Race with a timeout so boot never stalls if module loader hangs 875 + // 🚀 Module loading strategy: always race WS vs HTTP — fastest wins. 876 + // Production: don't block on WS connection. If WS is already connected 877 + // (from early init), it races. Otherwise HTTP goes alone. 878 + // Dev: allow a short WS wait (800ms) since hot-reload needs it. 879 + const wsWaitMs = isLocalhost ? 800 : 100; // 100ms grace for already-connecting WS 889 880 const useWsBundle = await Promise.race([ 890 881 moduleLoaderReady, 891 - new Promise(resolve => setTimeout(() => resolve(false), 2000)) 882 + new Promise(resolve => setTimeout(() => resolve(false), wsWaitMs)) 892 883 ]); 893 884 const loader = window.acModuleLoader; 894 885