Class: Liquid::Profiler
- Inherits:
-
Object
- Object
- Liquid::Profiler
- Includes:
- Enumerable
- Defined in:
- lib/liquid/profiler.rb
Overview
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.
Defined Under Namespace
Classes: Timing
Class Method Summary collapse
- .current_profile ⇒ Object
- .profile_children(template_name) ⇒ Object
- .profile_node_render(node) ⇒ Object
Instance Method Summary collapse
- #[](idx) ⇒ Object
- #current_partial ⇒ Object
- #each(&block) ⇒ Object
- #end_node(_node) ⇒ Object
-
#initialize ⇒ Profiler
constructor
A new instance of Profiler.
- #length ⇒ Object
- #pop_partial ⇒ Object
- #push_partial(partial_name) ⇒ Object
- #start ⇒ Object
- #start_node(node) ⇒ Object
- #stop ⇒ Object
- #total_render_time ⇒ Object
Constructor Details
#initialize ⇒ Profiler
Returns a new instance of Profiler.
99 100 101 102 103 104 105 106 107 |
# 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 |
Class Method Details
.current_profile ⇒ Object
95 96 97 |
# File 'lib/liquid/profiler.rb', line 95 def self.current_profile Thread.current[:liquid_profiler] end |
.profile_children(template_name) ⇒ Object
84 85 86 87 88 89 90 91 92 93 |
# 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) ⇒ Object
73 74 75 76 77 78 79 80 81 82 |
# 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 |
Instance Method Details
#[](idx) ⇒ Object
127 128 129 |
# File 'lib/liquid/profiler.rb', line 127 def [](idx) @root_timing.children[idx] end |
#current_partial ⇒ Object
146 147 148 |
# File 'lib/liquid/profiler.rb', line 146 def current_partial @partial_stack.last end |
#each(&block) ⇒ Object
123 124 125 |
# File 'lib/liquid/profiler.rb', line 123 def each(&block) @root_timing.children.each(&block) end |
#end_node(_node) ⇒ Object
139 140 141 142 143 144 |
# File 'lib/liquid/profiler.rb', line 139 def end_node(_node) timing = @timing_stack.pop timing.finish @timing_stack.last.children << timing end |
#length ⇒ Object
131 132 133 |
# File 'lib/liquid/profiler.rb', line 131 def length @root_timing.children.length end |
#pop_partial ⇒ Object
154 155 156 |
# File 'lib/liquid/profiler.rb', line 154 def pop_partial @partial_stack.pop end |
#push_partial(partial_name) ⇒ Object
150 151 152 |
# File 'lib/liquid/profiler.rb', line 150 def push_partial(partial_name) @partial_stack.push(partial_name) end |
#start ⇒ Object
109 110 111 112 |
# File 'lib/liquid/profiler.rb', line 109 def start Thread.current[:liquid_profiler] = self @render_start_at = Time.now end |
#start_node(node) ⇒ Object
135 136 137 |
# File 'lib/liquid/profiler.rb', line 135 def start_node(node) @timing_stack.push(Timing.start(node, current_partial)) end |
#stop ⇒ Object
114 115 116 117 |
# File 'lib/liquid/profiler.rb', line 114 def stop Thread.current[:liquid_profiler] = nil @render_end_at = Time.now end |
#total_render_time ⇒ Object
119 120 121 |
# File 'lib/liquid/profiler.rb', line 119 def total_render_time @render_end_at - @render_start_at end |