mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Merge pull request #35171 from rails/speed-up-partials
Speed up partial rendering by caching "variable" calculation
This commit is contained in:
commit
9483cdee0a
3 changed files with 41 additions and 19 deletions
|
@ -295,8 +295,21 @@ module ActionView
|
|||
end
|
||||
|
||||
def render(context, options, block)
|
||||
setup(context, options, block)
|
||||
template = find_partial
|
||||
as = as_variable(options)
|
||||
setup(context, options, as, block)
|
||||
|
||||
if @path
|
||||
if @has_object || @collection
|
||||
@variable, @variable_counter, @variable_iteration = retrieve_variable(@path, as)
|
||||
@template_keys = retrieve_template_keys(@variable)
|
||||
else
|
||||
@template_keys = @locals.keys
|
||||
end
|
||||
template = find_partial(@path, @template_keys)
|
||||
@variable ||= template.variable
|
||||
else
|
||||
template = nil
|
||||
end
|
||||
|
||||
@lookup_context.rendered_format ||= begin
|
||||
if template && template.formats.first
|
||||
|
@ -359,7 +372,7 @@ module ActionView
|
|||
# If +options[:partial]+ is a string, then the <tt>@path</tt> instance variable is
|
||||
# set to that string. Otherwise, the +options[:partial]+ object must
|
||||
# respond to +to_partial_path+ in order to setup the path.
|
||||
def setup(context, options, block)
|
||||
def setup(context, options, as, block)
|
||||
@options = options
|
||||
@block = block
|
||||
|
||||
|
@ -382,25 +395,25 @@ module ActionView
|
|||
|
||||
if @collection
|
||||
paths = @collection_data = @collection.map { |o| partial_path(o, context) }
|
||||
@path = paths.uniq.one? ? paths.first : nil
|
||||
if paths.uniq.length == 1
|
||||
@path = paths.first
|
||||
else
|
||||
paths.map! { |path| retrieve_variable(path, as).unshift(path) }
|
||||
@path = nil
|
||||
end
|
||||
else
|
||||
@path = partial_path(@object, context)
|
||||
end
|
||||
end
|
||||
|
||||
self
|
||||
end
|
||||
|
||||
def as_variable(options)
|
||||
if as = options[:as]
|
||||
raise_invalid_option_as(as) unless /\A[a-z_]\w*\z/.match?(as.to_s)
|
||||
as = as.to_sym
|
||||
as.to_sym
|
||||
end
|
||||
|
||||
if @path
|
||||
@variable, @variable_counter, @variable_iteration = retrieve_variable(@path, as)
|
||||
@template_keys = retrieve_template_keys
|
||||
else
|
||||
paths.map! { |path| retrieve_variable(path, as).unshift(path) }
|
||||
end
|
||||
|
||||
self
|
||||
end
|
||||
|
||||
def collection_from_options
|
||||
|
@ -414,8 +427,8 @@ module ActionView
|
|||
@object.to_ary if @object.respond_to?(:to_ary)
|
||||
end
|
||||
|
||||
def find_partial
|
||||
find_template(@path, @template_keys) if @path
|
||||
def find_partial(path, template_keys)
|
||||
find_template(path, template_keys)
|
||||
end
|
||||
|
||||
def find_template(path, locals)
|
||||
|
@ -511,9 +524,9 @@ module ActionView
|
|||
end
|
||||
end
|
||||
|
||||
def retrieve_template_keys
|
||||
def retrieve_template_keys(variable)
|
||||
keys = @locals.keys
|
||||
keys << @variable if @has_object || @collection
|
||||
keys << variable
|
||||
if @collection
|
||||
keys << @variable_counter
|
||||
keys << @variable_iteration
|
||||
|
|
|
@ -128,6 +128,8 @@ module ActionView
|
|||
end
|
||||
end
|
||||
|
||||
attr_reader :variable
|
||||
|
||||
def initialize(source, identifier, handler, details)
|
||||
format = details[:format] || (handler.default_format if handler.respond_to?(:default_format))
|
||||
|
||||
|
@ -138,6 +140,13 @@ module ActionView
|
|||
@original_encoding = nil
|
||||
@locals = details[:locals] || []
|
||||
@virtual_path = details[:virtual_path]
|
||||
|
||||
@variable = if @virtual_path
|
||||
base = @virtual_path[-1] == "/" ? "" : File.basename(@virtual_path)
|
||||
base =~ /\A_?(.*?)(?:\.\w+)*\z/
|
||||
$1.to_sym
|
||||
end
|
||||
|
||||
@updated_at = details[:updated_at] || Time.now
|
||||
@formats = Array(format).map { |f| f.respond_to?(:ref) ? f.ref : f }
|
||||
@variants = [details[:variant]]
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
module ActiveRecord
|
||||
module Railties # :nodoc:
|
||||
module CollectionCacheAssociationLoading #:nodoc:
|
||||
def setup(context, options, block)
|
||||
def setup(context, options, as, block)
|
||||
@relation = relation_from_options(options)
|
||||
|
||||
super
|
||||
|
|
Loading…
Reference in a new issue