Repository navigation
Only recompile components when a template changed, instead of before every request - #2730
Merged
joelhawksley merged 1 commit intoOct 19, 2026
Merged
Conversation
When templates aren't cached, the engine emptied the compile cache before every request, so every request recompiled every component it rendered, even when nothing changed. Like Action View does for views, watch the templates and translation files in the autoload paths with config.file_watcher, and only invalidate the cache when one of them is added, changed, or removed. Changes to Ruby files reload the application, which clears the cache.
joelhawksley
approved these changes
Oct 19, 2026
Contributor
Author
|
Thanks a lot @joelhawksley ! |
joelhawksley
added a commit
to mhenrixon/view_component
that referenced
this pull request
Oct 19, 2026
Resolve conflicts with ViewComponent#2730's template watcher. Move hook registration into CompileCache.watch_templates so the cached-templates case is tested in-process instead of in a subprocess, and drop the runtime caching check, which only existed to support a test that toggled caching after boot. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: f2e356ff-16cd-4517-8e63-a8600747d3fa
joelhawksley
added a commit
to mhenrixon/view_component
that referenced
this pull request
Oct 19, 2026
…olation Boot a fresh development or production app per test in a forked process, the way railties tests do, instead of an Open3 subprocess or an extracted method. These tests run in their own rake task since the sandbox is already booted in the test process. Inline the executor hook back into the engine, and restore ViewComponent#2730's integration tests that a previous commit dropped by mistake. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: f2e356ff-16cd-4517-8e63-a8600747d3fa
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.
Closes #2729
What are you trying to accomplish?
When templates aren't cached, which is the default in development, the engine empties the compile cache before every request, so every request recompiles every component it renders, even when no template changed. This only invalidates the cache when a template or a translation file was added, changed, or removed.
On our app (between 43 and 60 components per page), median of 7 requests after a warm-up:
What approach did you choose and why?
The same one as Action View's
ActionView::CacheExpiry::ViewReloaderfor views: aconfig.file_watcherover the autoload paths, since components can live outsideapp/componentsand in engines, watchingActionView::Template::Handlers.extensionsplusymlandyamlfor sidecar translations. Changes to Ruby files, inline templates included, already reload the application, so the cache is also cleared onbefore_class_unload.The watcher is built on the first request that doesn't cache templates, so the template handlers registered by gems like Slim or Haml are known by then, and
ActionView::Base.cache_template_loadingis still checked on every request, as the test helpers toggle it.Anything you want to highlight for special attention from reviewers?
The existing tests for template changes being reflected on the next request fail if the watcher doesn't invalidate the cache, so they cover the change. I added one checking that a component isn't recompiled when no template changed, which fails on
main, and one for an added template.