lib/roda/plugins/render.rb in roda-3.39.0 vs lib/roda/plugins/render.rb in roda-3.40.0
- old
+ new
@@ -331,10 +331,29 @@
end
end
end
module ClassMethods
+ # :nocov:
+ if COMPILED_METHOD_SUPPORT
+ # :nocov:
+ # If using compiled methods and there is an optimized layout, speed up
+ # access to the layout method to improve the performance of view.
+ def freeze
+ begin
+ _freeze_layout_method
+ rescue
+ # This is only for optimization, if any errors occur, they can be ignored.
+ # One possibility for error is the app doesn't use a layout, but doesn't
+ # specifically set the :layout=>false plugin option.
+ nil
+ end
+
+ super
+ end
+ end
+
# Copy the rendering options into the subclass, duping
# them as necessary to prevent changes in the subclass
# affecting the parent class.
def inherited(subclass)
super
@@ -350,10 +369,31 @@
# Return the render options for this class.
def render_opts
opts[:render]
end
+
+ private
+
+ # Precompile the layout method, to reduce method calls to look it up at runtime.
+ def _freeze_layout_method
+ if render_opts[:layout]
+ instance = allocate
+ instance.send(:retrieve_template, instance.send(:view_layout_opts, OPTS))
+
+ # :nocov:
+ if COMPILED_METHOD_SUPPORT
+ # :nocov:
+ if (layout_template = render_opts[:optimize_layout]) && !opts[:render][:optimized_layout_method_created]
+ instance.send(:retrieve_template, :template=>layout_template, :cache_key=>nil, :template_method_cache_key => :_roda_layout)
+ layout_method = opts[:render][:template_method_cache][:_roda_layout]
+ define_method(:_layout_method){layout_method}
+ opts[:render] = opts[:render].merge(:optimized_layout_method_created=>true)
+ end
+ end
+ end
+ end
end
module InstanceMethods
# Render the given template. See Render for details.
def render(template, opts = (no_opts = true; optimized_template = _cached_template_method(template); OPTS), &block)
@@ -377,19 +417,23 @@
# and render it inside the layout. See Render for details.
def view(template, opts = (optimized_template = _cached_template_method(template); OPTS))
if optimized_template
content = send(optimized_template, OPTS)
- render_opts = self.class.opts[:render]
- if layout_template = render_opts[:optimize_layout]
- method_cache = render_opts[:template_method_cache]
- unless layout_method = method_cache[:_roda_layout]
- retrieve_template(:template=>layout_template, :cache_key=>nil, :template_method_cache_key => :_roda_layout)
- layout_method = method_cache[:_roda_layout]
- end
+ # First, check if the optimized layout method has already been created,
+ # and use it if so. This way avoids the extra conditional and local variable
+ # assignments in the next section.
+ if layout_method = _layout_method
+ return send(layout_method, OPTS){content}
+ end
- if layout_method
+ # If we have an optimized template method but no optimized layout method, create the
+ # optimized layout method if possible and use it. If you can't create the optimized
+ # layout method, fall through to the slower approach.
+ if layout_template = self.class.opts[:render][:optimize_layout]
+ retrieve_template(:template=>layout_template, :cache_key=>nil, :template_method_cache_key => :_roda_layout)
+ if layout_method = _layout_method
return send(layout_method, OPTS){content}
end
end
else
opts = parse_template_opts(template, opts)
@@ -426,10 +470,15 @@
# Return the instance method symbol for the template in the method cache.
def _cached_template_method_lookup(method_cache, template)
method_cache[template]
end
+ # Return a symbol containing the optimized layout method
+ def _layout_method
+ self.class.opts[:render][:template_method_cache][:_roda_layout]
+ end
+
# Use an optimized render path for templates with a hash of locals. Returns the result
# of the template render if the optimized path is used, or nil if the optimized
# path is not used and the long method needs to be used.
def _optimized_render_method_for_locals(template, locals)
return unless method_cache = render_opts[:template_method_cache]
@@ -469,14 +518,18 @@
end
end
end
else
# :nocov:
- def _cached_template_method(template)
+ def _cached_template_method(_)
nil
end
- def _cached_template_method_key(template)
+ def _cached_template_method_key(_)
+ nil
+ end
+
+ def _layout_method
nil
end
def _optimized_render_method_for_locals(_, _)
nil