working on optimization
This commit is contained in:
parent
fbda6a17f9
commit
d879b80b7a
@ -1,6 +1,50 @@
|
||||
class Layout < LiquidTemplate
|
||||
|
||||
## fields ##
|
||||
# field :blocks, :type => Hash
|
||||
|
||||
# def unmarshalled_blocks
|
||||
# # puts "self.blocks = #{self.blocks.class.inspect}"
|
||||
# @unmarshalled_blocks ||= self.blocks.inject({}) do |b, (name, node)|
|
||||
# # puts "b= #{b.inspect} / name = #{name.inspect} / node = #{node.inspect}"
|
||||
# b[name] = Marshal.load(node)
|
||||
# b
|
||||
# end
|
||||
# end
|
||||
|
||||
protected
|
||||
|
||||
|
||||
|
||||
def after_parse_template
|
||||
blocks = self.find_blocks(self.template.root)
|
||||
self.template.send(:instance_variable_set, :"@parent_blocks", blocks)
|
||||
|
||||
# TODO: include parent blocks in self.template before marshalling it
|
||||
|
||||
# puts "[Layout / blocks] #{self.blocks.inspect}"
|
||||
end
|
||||
|
||||
def find_blocks(node, blocks = {})
|
||||
# puts "[Layout/#{self.slug}] ** find_blocks #{node.class.inspect} / #{blocks.keys.inspect}"
|
||||
if node.respond_to?(:nodelist) && node.nodelist
|
||||
# puts " ==> find_blocks nodelist = #{node.nodelist.inspect}"
|
||||
node.nodelist.inject(blocks) do |b, node|
|
||||
if node.is_a?(Locomotive::Liquid::Tags::Block)
|
||||
# b[node.name] = Marshal.dump(node)
|
||||
b[node.name] = node
|
||||
end
|
||||
# else
|
||||
self.find_blocks(node, b) # FIXME: add nested blocks
|
||||
# end
|
||||
b
|
||||
end
|
||||
end
|
||||
blocks
|
||||
end
|
||||
|
||||
## associations ##
|
||||
|
||||
# references_many :pages
|
||||
# embeds_many :parts, :class_name => 'PagePart'
|
||||
|
||||
|
@ -37,15 +37,25 @@ module Locomotive
|
||||
module InstanceMethods
|
||||
|
||||
def template
|
||||
Marshal.load(read_attribute(:serialized_template).to_s) rescue nil
|
||||
@template ||= Marshal.load(read_attribute(:serialized_template).to_s) rescue nil
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def store_template
|
||||
begin
|
||||
template = ::Liquid::Template.parse(self.liquify_template_source)
|
||||
self.serialized_template = BSON::Binary.new(Marshal.dump(template))
|
||||
@template = ::Liquid::Template.parse(self.liquify_template_source)
|
||||
|
||||
if self.respond_to?(:after_parse_template) # kind of callback
|
||||
self.send(:after_parse_template)
|
||||
end
|
||||
|
||||
self.serialized_template = BSON::Binary.new(Marshal.dump(@template))
|
||||
|
||||
if self.respond_to?(:after_store_template) # kind of callback
|
||||
self.send(:after_store_template)
|
||||
end
|
||||
|
||||
rescue ::Liquid::SyntaxError => error
|
||||
self.errors.add :template, :liquid_syntax_error
|
||||
end
|
||||
|
@ -4,6 +4,8 @@ module Locomotive
|
||||
class Extends < ::Liquid::Block
|
||||
Syntax = /(#{::Liquid::QuotedFragment})/
|
||||
|
||||
# attr_accessor :blocks
|
||||
|
||||
def initialize(tag_name, markup, tokens)
|
||||
if markup =~ Syntax
|
||||
@template_name = $1
|
||||
@ -17,25 +19,35 @@ module Locomotive
|
||||
m[node.name] = node if node.is_a?(Locomotive::Liquid::Tags::Block); m
|
||||
end
|
||||
|
||||
# puts "** Extends #{@template_name} / #{@blocks.inspect} / #{@nodelist.inspect}"
|
||||
# puts "\n** initialize ** Extends #{@template_name} / #{@blocks.inspect}"
|
||||
end
|
||||
|
||||
def parse(tokens)
|
||||
# puts "[#{@template_name}] parsing...#{tokens.inspect}"
|
||||
parse_all(tokens)
|
||||
end
|
||||
|
||||
def render(context)
|
||||
if OPTIMIZATION
|
||||
template, parent_blocks = load_template(context)
|
||||
else
|
||||
template = load_template(context)
|
||||
parent_blocks = find_blocks(template.root)
|
||||
end
|
||||
|
||||
# puts "** [Extends/render] parent_blocks = #{parent_blocks.inspect}"
|
||||
# puts "** [Extends/render] @blocks = #{@blocks.inspect} / @nodelist = #{@nodelist.inspect} / parent_blocks = #{parent_blocks.inspect}"
|
||||
|
||||
# BUG: parent blocks and parent template blocks are disconnected (OPTIMIZATION). need to resync them along with @nodelist
|
||||
@blocks.each do |name, block|
|
||||
# puts "** [Extends/render] #{name}, #{block.inspect}"
|
||||
if pb = parent_blocks[name]
|
||||
# puts "[#{name}]...found parent block ! #{pb.inspect}"
|
||||
pb.parent = block.parent
|
||||
# puts "[#{name}] pb.parent = #{pb.parent.inspect} / block.parent = #{block.parent.inspect}"
|
||||
pb.add_parent(pb.nodelist)
|
||||
# puts "[#{name}] pb.nodelist = #{pb.nodelist.inspect}"
|
||||
pb.nodelist = block.nodelist
|
||||
# puts "[#{name}] block.nodelist = #{block.nodelist.inspect}"
|
||||
else
|
||||
if is_extending?(template)
|
||||
template.root.nodelist << block
|
||||
@ -83,8 +95,13 @@ module Locomotive
|
||||
def load_template(context)
|
||||
# puts "** load_template (#{context[@template_name]})"
|
||||
layout = context.registers[:site].layouts.where(:slug => context[@template_name]).first
|
||||
if OPTIMIZATION
|
||||
# [layout.template, layout.unmarshalled_blocks]
|
||||
[layout.template, layout.template.send(:instance_variable_get, :"@parent_blocks")]
|
||||
else
|
||||
layout.template
|
||||
end
|
||||
end
|
||||
|
||||
def find_blocks(node, blocks={})
|
||||
# puts "** find_blocks #{node.class.inspect} / #{blocks.keys.inspect}"
|
||||
|
@ -9,6 +9,8 @@ require File.dirname(__FILE__) + "/../config/environment" unless defined?(RAILS_
|
||||
# config.master = Mongo::Connection.new.db("locomotive_perf_test")
|
||||
# end
|
||||
|
||||
OPTIMIZATION = false
|
||||
|
||||
%w{sites pages layouts}.each do |collection|
|
||||
Mongoid.master.collection(collection).drop
|
||||
end
|
||||
@ -35,13 +37,15 @@ layout_with_sidebar = site.layouts.create :name => 'with_sidebar', :value => %{
|
||||
</html>
|
||||
}
|
||||
|
||||
# puts layout_with_sidebar.unmarshalled_blocks.inspect
|
||||
|
||||
custom_layout_with_sidebar = site.layouts.create :name => 'custom_with_sidebar', :value => %{
|
||||
\{% extends 'with_sidebar' %\}
|
||||
\{% block sidebar %\}A sidebar here\{% endblock %\}
|
||||
\{% block body %\}<div class="wrapper">\{% block main %\}DEFAULT MAIN CONTENT\{% endblock %\}</div>\{% endblock %\}
|
||||
}
|
||||
|
||||
page = site.pages.create :title => 'Index', :slug => 'index', :layout_template => %{
|
||||
page = site.pages.create :title => 'Benchmark', :slug => 'benchmark', :layout_template => %{
|
||||
\{% extends 'custom_with_sidebar' %\}
|
||||
\{% block sidebar %\}\{\{ block.super \}\} / INDEX sidebar\{% endblock %\}
|
||||
\{% block main %\}Lorem ipsum\{% endblock %\}
|
||||
@ -49,18 +53,21 @@ page = site.pages.create :title => 'Index', :slug => 'index', :layout_template =
|
||||
|
||||
context = Liquid::Context.new({}, { 'site' => site }, { :site => site })
|
||||
|
||||
puts "====> \n#{page.render(context)}"
|
||||
puts "====> OUTPUT \n#{page.render(context)}"
|
||||
|
||||
Benchmark.bm do |bm|
|
||||
bm.report("Rendering page 10k times") do
|
||||
10000.times do
|
||||
Page.first.render(context)
|
||||
Page.last.render(context)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# without liquify (macbook white): User System Total Real
|
||||
# Rendering page 10k times 22.650000 6.220000 28.870000 ( 30.294338)
|
||||
# # empty page (imac 27'): User System Total Real
|
||||
# # Rendering page 10k times 13.390000 1.700000 15.090000 ( 15.654966)
|
||||
|
||||
# without liquify (imac 27'): User System Total Real
|
||||
# Rendering page 10k times 13.390000 1.700000 15.090000 ( 15.654966)
|
||||
# # page with inherited template (imac 27'): User System Total Real
|
||||
# Rendering page 10k times 85.840000 7.600000 93.440000 ( 97.841248)
|
||||
|
||||
# # with optimization (imac 27'): User System Total Real
|
||||
# Rendering page 10k times 84.240000 7.280000 91.520000 ( 95.475565)
|
||||
|
Loading…
Reference in New Issue
Block a user