| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This commit passes the template format to the digestor in order to come
up with a key. Before this commit, the digestor would depend on the
side effect of the template renderer setting the rendered_format on the
lookup context. I would like to remove that mutation, so I've changed
this to pass the template format in to the digestor.
I've introduced a new instance variable that will be alive during a
template render. When the template is being rendered, it pushes the
current template on to a stack, setting `@current_template` to the
template currently being rendered. When the cache helper asks the
digestor for a key, it uses the format of the template currently on the
stack.
|
|\
| |
| | |
Cached collections only work if there is one template
|
| |
| |
| |
| |
| | |
Cached collections only work if there is one template. If there are
more than one templates, the caching mechanism doesn't have a key.
|
|/
|
|
|
|
|
|
|
|
|
| |
This commit keeps a stack of lookup contexts on the ActionView::Base
instance. If a format is passed to render, we instantiate a new lookup
context and push it on the stack, that way any child calls to "render"
will use the same format information as the parent. This also isolates
"sibling" calls to render (multiple calls to render in the same
template).
Fixes #35222 #34138
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This commit speeds up rendering partials by caching the variable name
calculation on the template. The variable name is based on the "virtual
path" used for looking up the template. The same virtual path
information lives on the template, so we can just ask the cached
template object for the variable.
This benchmark takes a couple files, so I'll cat them below:
```
[aaron@TC ~/g/r/actionview (speed-up-partials)]$ cat render_benchmark.rb
require "benchmark/ips"
require "action_view"
require "action_pack"
require "action_controller"
class TestController < ActionController::Base
end
TestController.view_paths = [File.expand_path("test/benchmarks")]
controller_view = TestController.new.view_context
result = Benchmark.ips do |x|
x.report("render") do
controller_view.render("many_partials")
end
end
[aaron@TC ~/g/r/actionview (speed-up-partials)]$ cat test/benchmarks/test/_many_partials.html.erb
Looping:
<ul>
<% 100.times do |i| %>
<%= render partial: "list_item", locals: { i: i } %>
<% end %>
</ul>
[aaron@TC ~/g/r/actionview (speed-up-partials)]$ cat test/benchmarks/test/_list_item.html.erb
<li>Number: <%= i %></li>
```
Benchmark results (master):
```
[aaron@TC ~/g/r/actionview (master)]$ be ruby render_benchmark.rb
Warming up --------------------------------------
render 41.000 i/100ms
Calculating -------------------------------------
render 424.269 (± 3.5%) i/s - 2.132k in 5.031455s
```
Benchmark results (this branch):
```
[aaron@TC ~/g/r/actionview (speed-up-partials)]$ be ruby render_benchmark.rb
Warming up --------------------------------------
render 50.000 i/100ms
Calculating -------------------------------------
render 521.862 (± 3.8%) i/s - 2.650k in 5.085885s
```
|
|
|
|
|
| |
That method doesn't exist on LookupContext, so the delegate doesn't make
sense.
|
|
|
|
| |
We can remove the ivar by caching the digest on the stack
|
|
|
|
|
|
| |
This gets the PartialRenderer to be a bit closer to the
TemplateRenderer. TemplateRenderer already keeps its template in a
local variable.
|
|
|
|
| |
This method is private, and we always pass something in.
|
|
|
|
| |
Similar to 1853b0d0abf87dfdd4c3a277c3badb17ca19652e
|
|
|
|
|
|
|
|
|
|
| |
This reduces the surface area of our API and removes a Liskov issue.
Both TemplateRenderer and PartialRenderer inherit from AbstractRenderer,
but since PartialRenderer implements it's own `find_template` that is
private, and has the wrong method signature, an instance of
PartialRenderer cannot be substituted for an instance of
AbstractRenderer renderer. Removing the superclass implementation
solves both issues.
|
|
|
|
|
|
|
| |
This patch changes `with_fallbacks` to be a factory method that returns
a new instance of a lookup context which contains the fallback view
paths in addition to the controller specific view paths. Since the
lookup context is more "read only", we may be able to cache them
|
| |
|
|
|
|
|
| |
If we pass the view instance around it's easier to understand the flow
control.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Since Rails 6.0 will support Ruby 2.4.1 or higher
`# frozen_string_literal: true` magic comment is enough to make string object frozen.
This magic comment is enabled by `Style/FrozenStringLiteralComment` cop.
* Exclude these files not to auto correct false positive `Regexp#freeze`
- 'actionpack/lib/action_dispatch/journey/router/utils.rb'
- 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb'
It has been fixed by https://github.com/rubocop-hq/rubocop/pull/6333
Once the newer version of RuboCop released and available at Code Climate these exclude entries should be removed.
* Replace `String#freeze` with `String#-@` manually if explicit frozen string objects are required
- 'actionpack/test/controller/test_case_test.rb'
- 'activemodel/test/cases/type/string_test.rb'
- 'activesupport/lib/active_support/core_ext/string/strip.rb'
- 'activesupport/test/core_ext/string_ext_test.rb'
- 'railties/test/generators/actions_test.rb'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
In Ruby 2.3 or later, `String#+@` is available and `+@` is faster than `dup`.
```ruby
# frozen_string_literal: true
require "bundler/inline"
gemfile(true) do
source "https://rubygems.org"
gem "benchmark-ips"
end
Benchmark.ips do |x|
x.report('+@') { +"" }
x.report('dup') { "".dup }
x.compare!
end
```
```
$ ruby -v benchmark.rb
ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux]
Warming up --------------------------------------
+@ 282.289k i/100ms
dup 187.638k i/100ms
Calculating -------------------------------------
+@ 6.775M (± 3.6%) i/s - 33.875M in 5.006253s
dup 3.320M (± 2.2%) i/s - 16.700M in 5.032125s
Comparison:
+@: 6775299.3 i/s
dup: 3320400.7 i/s - 2.04x slower
```
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
On every iteration of generating a cache for a collection a “digest path” is calculated even though it’s exactly the same for every element.
This PR exposes a method `digest_path_from_virtual` that returns back a “digest_path”. This can in turn be passed back into `cache_fragment_name`. This not only does less work, but it also (you guessed it) uses less memory.
before: Total allocated: 762539 bytes (7035 objects)
after: Total allocated: 743590 bytes (6621 objects)
(762539 - 743590)/ 762539.0 # => 2.4% faster ⚡️⚡️
|
|\
| |
| | |
Allow usage of strings as locals for partial renderer
|
| | |
|
| |
| |
| |
| | |
stores the current locale in Thread.current[:local] (see: https://github.com/svenfuchs/i18n/blob/master/lib/i18n.rb#L23). StreamingTemplateRenderer is implemented with Fiber which have its own stack of locals and can not access Thread.current.locals(keys, see: https://ruby-doc.org/core-2.2.0/Thread.html#class-Thread-label-Fiber-local+vs.+Thread-local).
|
|/
|
|
| |
This basically reverts c4d1a4efeec6f0b5b58222993aa0bec85a19b6a8
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
refs: https://github.com/rails/rails/pull/30161
```
$ echo "+@size+" | rdoc --pipe
<p>+@size+</p>
$ echo "<tt>@size</tt>" | rdoc --pipe
<p><code>@size</code></p>
```
[ci skip]
|
| |
|
| |
|
| |
|
|
|
|
| |
st0012/fix-partial-cache-logging
|
|
|
|
| |
boolean.
|
| |
|
| |
|
|
|
|
|
|
|
| |
When rendering heterogeneous collection using `render @collection` or
`render partial: @collection`, the expected `<partial_name>_iteration`
variable is missing due to `find_template` not having the name of the
iteration variable included in its cache keys.
|
| |
|
| |
|
|
|
|
| |
(I personally prefer writing one string in one line no matter how long it is, though)
|
| |
|
| |
|
|\
| |
| | |
Add missing `+` around a some literals.
|
| |
| |
| |
| |
| |
| | |
Mainly around `nil`
[ci skip]
|
| | |
|
|/
|
|
|
|
| |
Regexp#match? should be considered to be part of the Ruby core library. We are
emulating it for < 2.4, but not having to require the extension is part of the
illusion of the emulation.
|
| |
|
|
|
|
|
|
| |
All indentation was normalized by rubocop auto-correct at 80e66cc4d90bf8c15d1a5f6e3152e90147f00772.
But comments was still kept absolute position. This commit aligns
comments with method definitions for consistency.
|
|
|
|
|
|
|
| |
CacheHelper is mixed in to Helpers, Helpers is mixed in to AV::Base.
This means we can count on instances of AV::Base to have the "cache hit"
method on them, and we can stop setting an ivar for cache logging and
just ask the view if it was a cache hit.
|
|
|
|
|
|
|
|
| |
Style/SpaceBeforeBlockBraces
Style/SpaceInsideBlockBraces
Style/SpaceInsideHashLiteralBraces
Fix all violations in the repository.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Implement naive partial caching mechanism.
Add test for LogSubscriber
Use ActionView::Base#log_payload to store log_subscriber's payload, so we can pass cache result into it.
Fixed tests
Remove useless settings
Check if #log_payload exists before calling it. Because other classes also includes CacheHelper but don't have is attribute
Use @log_payload_for_partial_reder instead of #log_payload to carry ActionView's payload.
Update test's hash syntax
Add configuration to enable/disable fragment caching logging
Remove unless test and add new test to ensure cache info won't effect next rendering's log
Move :enable_fragment_cache_logging config from ActionView to ActionPack
Apply new config to tests
Update actionview's changelog
Update configuration guide
Improve actionview's changelog
Refactor PartialRenderer#render and log tests
Mute subscriber's log instead of disabling instrumentation.
Fix typo, remove useless comment and use new hash syntax
Improve actionpack's log_subscriber test
Fix rebase mistake
Apply new config to all caching intstrument actions
|
| |
|
| |
|
|
|
|
|
| |
The current code base is not uniform. After some discussion,
we have chosen to go with double quotes by default.
|
|
|
|
|
|
|
|
| |
We can safely assume we're not dealing with an infinite collection as
we're about to call `each` on it and collect the results until it
terminates on its own. Given that, `to_a` is implemented by the normal
Array-like objects, and less Array-like objects like `Enumerator` and
`Enumerator::Lazy`.
|