Repository navigation
Engine: Introduce SubtreeCompiler to compile part of a template - #2241
Merged
Merged
Conversation
SubtreeCompiler to render one part of a templateSubtreeCompiler to compile part of a template
|
| Command | Status | Duration | Result |
|---|---|---|---|
nx run-many -t test --all --parallel --exclude=... |
✅ Succeeded | 3m 23s | View ↗ |
nx run-many -t build --all --exclude=herb-langu... |
✅ Succeeded | 2m 32s | View ↗ |
nx build @herb-tools/tailwind-class-sorter |
✅ Succeeded | 1s | View ↗ |
💡 Verify your cache is correct by running tasks in a sandbox. Read docs ↗
☁️ Nx Cloud last updated this comment at 2026-08-15 15:34:47 UTC
marcoroth
marked this pull request as ready for review
August 15, 2026 15:34
🌿 Interactive Playground and Documentation PreviewA preview deployment has been built for this pull request. Try out the changes live in the interactive playground: 🌱 Grown from commit ✅ Preview deployment has been cleaned up. |
commit: |
This branch was successfully deployed
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.

This pull request introduces
Herb::Engine::SubtreeCompiler, which compiles a template into Ruby that renders one part of it instead of all of it.Re-rendering a region means running the template again and keeping only the piece that changed. The piece cannot be compiled on its own, because what it renders depends on everything the template did before reaching it.
Everything runs, only the target is kept
A local assigned earlier, a helper called for its side effect, the loop the target sits inside, all of it has to run for the target to render the same as it would have in a full render. So nothing is skipped.
Asking for the
<ul>returns<ul><li>assigned</li></ul>. The assignment above it ran, both tracked calls ran, and the<div>rendered into a buffer that is thrown away.What changes is where the output goes. The engine writes every append through one buffer variable, so the target's output is collected by pointing that variable at the buffer being returned while the target renders and at a sink the rest of the time. Escaping, blocks, and control flow then need no special handling, because none of them know which buffer they are writing to. That is also why the escaping is right without any work, since the target is going back to the place it was cut from.
Pruning the work that only fed discarded output is a separate question, and answering it needs to know which expressions the target actually depends on. Running everything is the answer that is correct without that analysis.
Control flow around the target
A target inside a loop renders once per iteration, and a target inside a branch that did not run renders nothing.
Asking for the
<li>with two items returns<li>a</li><li>b</li>, because the loop it sits in is part of what has to run.Addressing
The target is named by
node_path, the same pathSlotVisitorrecords for a slot in #1986 andHerb::ActionView::TemplateDependenciesreports for a node, so a caller holding one from either has one that works here. An empty path is the whole document, which is tested for output identity againstHerb::Engineitself. A path that leads nowhere raisesTargetNotFoundinstead of compiling a template that silently renders nothing.