{"record":{"id":"dc550c1b44d2148b","repo":"remix-run/remix","slug":"cascadingcomponentupdatecount-cascading-compone","errorCode":null,"errorMessage":"${cascadingComponentUpdateCount} cascading component updates detected in one event loop turn. Consider reducing hydration regions. Components: ${formatComponentCounts(cascadingComponentNameCounts)}","messagePattern":"(.+?) cascading component updates detected in one event loop turn\\. Consider reducing hydration regions\\. Components: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"packages/ui/src/runtime/scheduler.ts","lineNumber":122,"sourceCode":"  function trackCascadingUpdate(vnode: CommittedComponentNode): boolean {\n    cascadingComponentUpdateCount++\n\n    let componentName = getComponentName(vnode)\n    cascadingComponentNameCounts.set(\n      componentName,\n      (cascadingComponentNameCounts.get(componentName) ?? 0) + 1,\n    )\n\n    let componentUpdateCount = (cascadingComponentUpdateCounts.get(vnode) ?? 0) + 1\n    cascadingComponentUpdateCounts.set(vnode, componentUpdateCount)\n    scheduleCounterReset()\n\n    if (\n      !warnedAboutCascadingUpdates &&\n      cascadingComponentUpdateCount >= CASCADING_UPDATE_WARN_THRESHOLD\n    ) {\n      warnedAboutCascadingUpdates = true\n      console.warn(\n        `${cascadingComponentUpdateCount} cascading component updates detected in one event loop turn. Consider reducing hydration regions. Components: ${formatComponentCounts(cascadingComponentNameCounts)}`,\n      )\n    }\n\n    if (componentUpdateCount > MAX_CASCADING_COMPONENT_UPDATES) {\n      let error = new Error(\n        `handle.update() infinite loop detected in ${componentName} after ${componentUpdateCount} cascading updates. Components: ${formatComponentCounts(cascadingComponentNameCounts)}`,\n      )\n      dispatchError(error)\n      return false\n    }\n\n    return true\n  }\n\n  function flush() {\n    if (flushing) return\n    flushing = true","sourceCodeStart":104,"sourceCodeEnd":140,"githubUrl":"https://github.com/remix-run/remix/blob/9696913134be3a4423513d2775f7b31d6917c049/packages/ui/src/runtime/scheduler.ts#L104-L140","documentation":"The UI scheduler warns once per session when the number of cascading component updates in a single event loop turn exceeds CASCADING_UPDATE_WARN_THRESHOLD. Cascades mean one update triggers others (often via overlapping hydration regions), causing excess render work per tick.","triggerScenarios":"A flush() turn in which many components schedule updates in reaction to other updates — commonly large hydration regions where hydrated components each trigger further component updates.","commonSituations":"Apps with very large or heavily nested hydration regions, wide component trees hydrated at once, or state changes that fan out through many subscribed components in one tick.","solutions":["Split large hydration regions into smaller ones so each flush does less cascading work","Move fan-out state into fewer, coarser subscriptions or a store read during render","Memoize/isolate subtrees so unrelated components don't update together"],"exampleFix":"// before\n<div data-hydrate=\"whole-page\">...</div>\n// after\n<div data-hydrate=\"header\">...</div>\n<div data-hydrate=\"main\">...</div>","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Prefer many small hydration regions over one large one","Batch fan-out state updates so fewer components re-render per tick"],"tags":["ui","scheduler","performance","hydration"],"backgroundTag":"cascading-render-updates","analyzedSha":"9696913134be3a4423513d2775f7b31d6917c049","analyzedAt":"2026-08-27T19:55:01.024Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}