Fast renderer: retry an effect that raised, like the default renderer - #67
Merged
Merged
Conversation
When an effect raises, it stays marked as not executed, and the default renderer runs it again on the next tree walk. The fast renderer skipped a component whose element and state did not change, so for the root component and for memoized children a failed effect was never retried. A component with effect work left to do is now never skipped as clean. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of the audit of
REACTON_FAST=1against the default renderer. This is one small PR per finding; this one is F2.Problem
When an effect raises,
Effect.executedstaysFalse, and the default renderer runs it again on the next tree walk. The fast renderer skips a component whose element and state did not change (the clean-subtree fast path). So a failed effect in the root component, or in a memoized child, was never retried in fast mode.Fix
The clean-subtree fast path in
_RenderContextFast._rendernow also requires that the context has no effect work left: no effect that was never executed, and no pendingnexteffect. The check loops over that component's own effects, so it is cheap. The benchmarks do not change: leaf update 0.65 ms, memo subtree skip 1.20 ms. The default renderer is not touched.Tests
test_failed_root_effect_is_retried_on_later_tree_walkandtest_failed_effect_in_memoized_child_is_retried_on_later_tree_walkfail on master withREACTON_FAST=1.test_effect_cleanup_exception_does_not_retry_cleaned_effectchecks that a cleanup that raised does not cause an extra retry.The fix was written by a codex worker and verified by me. It is small, so it got no crossreview.
🤖 Generated with Claude Code