Full document, spreadsheet, slideshow, and diagram tooling
0
fork

Configure Feed

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

Merge pull request 'fix: debounce renderGrid to eliminate typing lag in sheets' (#32) from fix/sheets-render-perf into main

scott 6f5289aa a0f1d761

+11 -9
+11 -9
src/sheets/main.js
··· 224 224 const sheetContainer = document.getElementById('sheet-container'); 225 225 const sheetTabsContainer = document.getElementById('sheet-tabs'); 226 226 227 - // --- Grid rendering --- 227 + // --- Grid rendering (debounced to avoid multiple re-renders per edit) --- 228 + let _renderGridTimer = null; 229 + function scheduleRenderGrid() { 230 + if (_renderGridTimer) return; 231 + _renderGridTimer = requestAnimationFrame(() => { _renderGridTimer = null; renderGrid(); }); 232 + } 228 233 function renderGrid() { 229 234 const sheet = getActiveSheet(); 230 235 const rowCount = sheet.get('rowCount') || DEFAULT_ROWS; ··· 1177 1182 statusText.textContent = 'Synced'; 1178 1183 // Re-attach cell observer after sync — the snapshot may have replaced the Y.Map 1179 1184 // that getCells() returned during initial setup (before data loaded) 1180 - getCells().observeDeep(() => { evalCache.clear(); renderGrid(); updateFormulaBar(); }); 1185 + getCells().observeDeep(() => { evalCache.clear(); scheduleRenderGrid(); updateFormulaBar(); }); 1181 1186 renderGrid(); 1182 1187 }); 1183 1188 ··· 1375 1380 }); 1376 1381 1377 1382 // --- React to Yjs changes --- 1378 - getCells().observeDeep(() => { evalCache.clear(); renderGrid(); updateFormulaBar(); }); 1383 + getCells().observeDeep(() => { evalCache.clear(); scheduleRenderGrid(); updateFormulaBar(); }); 1379 1384 ySheets.observe(() => { renderSheetTabs(); }); 1380 1385 1381 1386 // Re-render when colWidths, freeze state, CF rules, validations, or stripedRows change from remote collaborators 1382 1387 ySheets.observeDeep((events) => { 1383 1388 for (const event of events) { 1384 - if (event.target && event.target === getColWidths()) { renderGrid(); return; } 1389 + if (event.target && event.target === getColWidths()) { scheduleRenderGrid(); return; } 1385 1390 const changed = event.changes?.keys; 1386 1391 if (changed) { 1387 1392 for (const [key] of changed) { 1388 - if (key === 'freezeRows' || key === 'freezeCols' || key === 'stripedRows') { renderGrid(); return; } 1393 + if (key === 'freezeRows' || key === 'freezeCols' || key === 'stripedRows') { scheduleRenderGrid(); return; } 1389 1394 } 1390 1395 } 1391 1396 // CF rules or validations changed ··· 1692 1697 closeAllDropdowns(); 1693 1698 }); 1694 1699 1695 - // Re-render charts when cell data changes 1696 - getCells().observeDeep(() => { 1697 - if (chartInstances.size > 0) renderCharts(); 1698 - }); 1700 + // Charts re-render is handled by the main cell observer + scheduleRenderGrid 1699 1701 1700 1702 // ======================================================== 1701 1703 // Multi-Column Filter Feature