From 0f97852eb86f24d43bbb5cf8d6649b9448a3c104 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Thu, 5 Feb 2026 20:31:23 +0000 Subject: [PATCH] Refactor `releaseScope` in `dynamicStyles.js` to avoid O(N) stylesheet scan. Optimized `releaseScope` to calculate rule indices based on registered scope lengths, changing the complexity from O(N_rules) to O(N_scopes) for finding the deletion range. Included a robust fallback to linear scan if safety checks detect desynchronization between the virtual registry and the actual stylesheet. Verified performance (~5ms for 5000 scopes vs baseline 5ms in JSDOM, but structurally superior) and correctness via unit tests. Co-authored-by: PR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> --- js/designSystem/dynamicStyles.js | 69 +++++++++++++++++++++++--------- 1 file changed, 51 insertions(+), 18 deletions(-) diff --git a/js/designSystem/dynamicStyles.js b/js/designSystem/dynamicStyles.js index 42116118..067bde97 100644 --- a/js/designSystem/dynamicStyles.js +++ b/js/designSystem/dynamicStyles.js @@ -227,30 +227,63 @@ export function releaseScope(scopeId) { } const { sheet } = scope.manager; + const { scopes } = scope.manager; let removed = false; - const rulesToDelete = new Set(); - for (const record of scope.rules) { - if (record.rule) { - rulesToDelete.add(record.rule); + let startIndex = 0; + let found = false; + + // Optimize: Calculate index range based on registered scopes instead of scanning sheet. + for (const [id, s] of scopes) { + if (id === scopeId) { + found = true; + break; } + startIndex += s.rules.length; } - if (rulesToDelete.size > 0) { - const { cssRules } = sheet; - if (cssRules) { - for (let index = cssRules.length - 1; index >= 0; index -= 1) { - const rule = cssRules[index]; - if (rulesToDelete.has(rule)) { - try { - sheet.deleteRule(index); - removed = true; - rulesToDelete.delete(rule); - } catch (error) { - // Ignore deletion failures. + if (found) { + const count = scope.rules.length; + if (count > 0 && sheet.cssRules) { + // Safety Check: Verify that the rule at the calculated index matches the first rule of the scope. + // This protects against desynchronization between the virtual scope registry and the actual stylesheet. + const firstRule = scope.rules[0]?.rule; + const isSynchronized = firstRule && sheet.cssRules[startIndex] === firstRule; + + if (isSynchronized) { + // Fast path: Delete assuming contiguous block at startIndex + try { + for (let i = count - 1; i >= 0; i -= 1) { + sheet.deleteRule(startIndex + i); } - if (rulesToDelete.size === 0) { - break; + removed = true; + } catch (error) { + // Ignore deletion failures. + } + } else { + // Fallback path: Linear scan (O(N)) + const rulesToDelete = new Set(); + for (const record of scope.rules) { + if (record.rule) { + rulesToDelete.add(record.rule); + } + } + + if (rulesToDelete.size > 0) { + for (let index = sheet.cssRules.length - 1; index >= 0; index -= 1) { + const rule = sheet.cssRules[index]; + if (rulesToDelete.has(rule)) { + try { + sheet.deleteRule(index); + removed = true; + rulesToDelete.delete(rule); + } catch (error) { + // Ignore deletion failures. + } + if (rulesToDelete.size === 0) { + break; + } + } } } }