class Liquid::Profiler

Profiler enables support for profiling template rendering to help track down performance issues.

To enable profiling, first require ‘liquid/profiler’. Then, to profile a parse/render cycle, pass the profile: true option to Liquid::Template.parse. After Liquid::Template#render is called, the template object makes available an instance of this class via the Liquid::Template#profiler method.

template = Liquid::Template.parse(template_content, profile: true)
output  = template.render
profile = template.profiler

This object contains all profiling information, containing information on what tags were rendered, where in the templates these tags live, and how long each tag took to render.

This is a tree structure that is Enumerable all the way down, and keeps track of tags and rendering times inside of {% include %} tags.

profile.each do |node|
  # Access to the node itself
  node.code

  # Which template and line number of this node.
  # If top level, this will be "<root>".
  node.partial
  node.line_number

  # Render time in seconds of this node
  node.render_time

  # If the template used {% include %}, this node will also have children.
  node.children.each do |child2|
    # ...
  end
end

Profiler also exposes the total time of the template’s render in Liquid::Profiler#total_render_time.

All render times are in seconds. There is a small performance hit when profiling is enabled.

Public Class Methods

current_profile() click to toggle source
# File lib/liquid/profiler.rb, line 95
def self.current_profile
  Thread.current[:liquid_profiler]
end
new() click to toggle source
# File lib/liquid/profiler.rb, line 99
def initialize
  @partial_stack = ["<root>"]

  @root_timing = Timing.new("", current_partial)
  @timing_stack = [@root_timing]

  @render_start_at = Time.now
  @render_end_at = @render_start_at
end
profile_children(template_name) { || ... } click to toggle source
# File lib/liquid/profiler.rb, line 84
def self.profile_children(template_name)
  if Profiler.current_profile
    Profiler.current_profile.push_partial(template_name)
    output = yield
    Profiler.current_profile.pop_partial
    output
  else
    yield
  end
end
profile_node_render(node) { || ... } click to toggle source
# File lib/liquid/profiler.rb, line 73
def self.profile_node_render(node)
  if Profiler.current_profile && node.respond_to?(:render)
    Profiler.current_profile.start_node(node)
    output = yield
    Profiler.current_profile.end_node(node)
    output
  else
    yield
  end
end

Public Instance Methods

[](idx) click to toggle source
# File lib/liquid/profiler.rb, line 127
def [](idx)
  @root_timing.children[idx]
end
current_partial() click to toggle source
# File lib/liquid/profiler.rb, line 146
def current_partial
  @partial_stack.last
end
each(&block) click to toggle source
# File lib/liquid/profiler.rb, line 123
def each(&block)
  @root_timing.children.each(&block)
end
end_node(_node) click to toggle source
# File lib/liquid/profiler.rb, line 139
def end_node(_node)
  timing = @timing_stack.pop
  timing.finish

  @timing_stack.last.children << timing
end
length() click to toggle source
# File lib/liquid/profiler.rb, line 131
def length
  @root_timing.children.length
end
pop_partial() click to toggle source
# File lib/liquid/profiler.rb, line 154
def pop_partial
  @partial_stack.pop
end
push_partial(partial_name) click to toggle source
# File lib/liquid/profiler.rb, line 150
def push_partial(partial_name)
  @partial_stack.push(partial_name)
end
start() click to toggle source
# File lib/liquid/profiler.rb, line 109
def start
  Thread.current[:liquid_profiler] = self
  @render_start_at = Time.now
end
start_node(node) click to toggle source
# File lib/liquid/profiler.rb, line 135
def start_node(node)
  @timing_stack.push(Timing.start(node, current_partial))
end
stop() click to toggle source
# File lib/liquid/profiler.rb, line 114
def stop
  Thread.current[:liquid_profiler] = nil
  @render_end_at = Time.now
end
total_render_time() click to toggle source
# File lib/liquid/profiler.rb, line 119
def total_render_time
  @render_end_at - @render_start_at
end