additional perf work
This commit is contained in:
parent
e0818e2118
commit
b8c0fd34e7
9 changed files with 99 additions and 53 deletions
|
@ -52,7 +52,7 @@ module Middleman::Cli
|
||||||
|
|
||||||
::Middleman::Logger.singleton(verbose, instrument)
|
::Middleman::Logger.singleton(verbose, instrument)
|
||||||
|
|
||||||
::Middleman::Util.instrument 'builder_setup' do
|
::Middleman::Util.instrument 'builder.setup' do
|
||||||
@app = ::Middleman::Application.new do
|
@app = ::Middleman::Application.new do
|
||||||
config[:mode] = :build
|
config[:mode] = :build
|
||||||
config[:environment] = env
|
config[:environment] = env
|
||||||
|
@ -67,7 +67,7 @@ module Middleman::Cli
|
||||||
builder.on_build_event(&method(:on_event))
|
builder.on_build_event(&method(:on_event))
|
||||||
end
|
end
|
||||||
|
|
||||||
::Middleman::Util.instrument 'builder_run' do
|
::Middleman::Util.instrument 'builder.run' do
|
||||||
if builder.run!
|
if builder.run!
|
||||||
clean_directories! if options['clean']
|
clean_directories! if options['clean']
|
||||||
shell.say 'Project built successfully.'
|
shell.say 'Project built successfully.'
|
||||||
|
|
|
@ -51,18 +51,31 @@ module Middleman
|
||||||
@has_error = false
|
@has_error = false
|
||||||
@events = {}
|
@events = {}
|
||||||
|
|
||||||
@app.execute_callbacks(:before_build, [self])
|
::Middleman::Util.instrument 'builder.before' do
|
||||||
|
@app.execute_callbacks(:before_build, [self])
|
||||||
|
end
|
||||||
|
|
||||||
queue_current_paths if @cleaning
|
::Middleman::Util.instrument 'builder.queue' do
|
||||||
|
queue_current_paths if @cleaning
|
||||||
|
end
|
||||||
|
|
||||||
prerender_css
|
::Middleman::Util.instrument 'builder.prerender' do
|
||||||
output_files
|
prerender_css
|
||||||
|
end
|
||||||
|
|
||||||
clean! if @cleaning
|
::Middleman::Util.instrument 'builder.output' do
|
||||||
|
output_files
|
||||||
|
end
|
||||||
|
|
||||||
|
::Middleman::Util.instrument 'builder.clean' do
|
||||||
|
clean! if @cleaning
|
||||||
|
end
|
||||||
|
|
||||||
::Middleman::Profiling.report('build')
|
::Middleman::Profiling.report('build')
|
||||||
|
|
||||||
@app.execute_callbacks(:after_build, [self])
|
::Middleman::Util.instrument 'builder.after' do
|
||||||
|
@app.execute_callbacks(:after_build, [self])
|
||||||
|
end
|
||||||
|
|
||||||
!@has_error
|
!@has_error
|
||||||
end
|
end
|
||||||
|
@ -73,14 +86,18 @@ module Middleman
|
||||||
def prerender_css
|
def prerender_css
|
||||||
logger.debug '== Prerendering CSS'
|
logger.debug '== Prerendering CSS'
|
||||||
|
|
||||||
css_files = @app.sitemap.resources
|
css_files = ::Middleman::Util.instrument 'builder.prerender.output' do
|
||||||
.select { |resource| resource.ext == '.css' }
|
@app.sitemap.resources
|
||||||
.each(&method(:output_resource))
|
.select { |resource| resource.ext == '.css' }
|
||||||
|
.each(&method(:output_resource))
|
||||||
|
end
|
||||||
|
|
||||||
# Double-check for compass sprites
|
::Middleman::Util.instrument 'builder.prerender.check-files' do
|
||||||
if @app.files.find_new_files!.length > 0
|
# Double-check for compass sprites
|
||||||
logger.debug '== Checking for Compass sprites'
|
if @app.files.find_new_files!.length > 0
|
||||||
@app.sitemap.ensure_resource_list_updated!
|
logger.debug '== Checking for Compass sprites'
|
||||||
|
@app.sitemap.ensure_resource_list_updated!
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
css_files
|
css_files
|
||||||
|
@ -92,11 +109,15 @@ module Middleman
|
||||||
def output_files
|
def output_files
|
||||||
logger.debug '== Building files'
|
logger.debug '== Building files'
|
||||||
|
|
||||||
@app.sitemap.resources
|
resources = @app.sitemap.resources
|
||||||
.sort_by { |resource| SORT_ORDER.index(resource.ext) || 100 }
|
|
||||||
.reject { |resource| resource.ext == '.css' }
|
.reject { |resource| resource.ext == '.css' }
|
||||||
.select { |resource| !@glob || File.fnmatch(@glob, resource.destination_path) }
|
.sort_by { |resource| SORT_ORDER.index(resource.ext) || 100 }
|
||||||
.each(&method(:output_resource))
|
|
||||||
|
if @glob
|
||||||
|
resources = resources.select { |resource| File.fnmatch(@glob, resource.destination_path) }
|
||||||
|
end
|
||||||
|
|
||||||
|
resources.each(&method(:output_resource))
|
||||||
end
|
end
|
||||||
|
|
||||||
# Figure out the correct event mode.
|
# Figure out the correct event mode.
|
||||||
|
@ -162,25 +183,29 @@ module Middleman
|
||||||
# @return [void]
|
# @return [void]
|
||||||
Contract IsA['Middleman::Sitemap::Resource'] => Any
|
Contract IsA['Middleman::Sitemap::Resource'] => Any
|
||||||
def output_resource(resource)
|
def output_resource(resource)
|
||||||
output_file = @build_dir + resource.destination_path.gsub('%20', ' ')
|
output_file = nil
|
||||||
|
|
||||||
begin
|
::Middleman::Util.instrument "builder.output.resource", path: File.basename(resource.destination_path) do
|
||||||
if resource.binary?
|
output_file = @build_dir + resource.destination_path.gsub('%20', ' ')
|
||||||
export_file!(output_file, resource.file_descriptor[:full_path])
|
|
||||||
else
|
|
||||||
response = @rack.get(::URI.escape(resource.request_path))
|
|
||||||
|
|
||||||
# If we get a response, save it to a tempfile.
|
begin
|
||||||
if response.status == 200
|
if resource.binary?
|
||||||
export_file!(output_file, binary_encode(response.body))
|
export_file!(output_file, resource.file_descriptor[:full_path])
|
||||||
else
|
else
|
||||||
@has_error = true
|
response = @rack.get(::URI.escape(resource.request_path))
|
||||||
trigger(:error, output_file, response.body)
|
|
||||||
|
# If we get a response, save it to a tempfile.
|
||||||
|
if response.status == 200
|
||||||
|
export_file!(output_file, binary_encode(response.body))
|
||||||
|
else
|
||||||
|
@has_error = true
|
||||||
|
trigger(:error, output_file, response.body)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
rescue => e
|
||||||
|
@has_error = true
|
||||||
|
trigger(:error, output_file, "#{e}\n#{e.backtrace.join("\n")}")
|
||||||
end
|
end
|
||||||
rescue => e
|
|
||||||
@has_error = true
|
|
||||||
trigger(:error, output_file, "#{e}\n#{e.backtrace.join("\n")}")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return unless @cleaning
|
return unless @cleaning
|
||||||
|
|
|
@ -57,6 +57,7 @@ module Middleman
|
||||||
@app = app
|
@app = app
|
||||||
@data_file_matcher = data_file_matcher
|
@data_file_matcher = data_file_matcher
|
||||||
@local_data = {}
|
@local_data = {}
|
||||||
|
@local_data_enhanced = nil
|
||||||
@local_sources = {}
|
@local_sources = {}
|
||||||
@callback_sources = {}
|
@callback_sources = {}
|
||||||
end
|
end
|
||||||
|
@ -117,6 +118,8 @@ module Middleman
|
||||||
end
|
end
|
||||||
|
|
||||||
data_branch[basename] = data
|
data_branch[basename] = data
|
||||||
|
|
||||||
|
@local_data_enhanced = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
# Remove a given file from the internal cache
|
# Remove a given file from the internal cache
|
||||||
|
@ -137,6 +140,8 @@ module Middleman
|
||||||
end
|
end
|
||||||
|
|
||||||
data_branch.delete(basename) if data_branch.key?(basename)
|
data_branch.delete(basename) if data_branch.key?(basename)
|
||||||
|
|
||||||
|
@local_data_enhanced = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
# Get a hash from either internal static data or a callback
|
# Get a hash from either internal static data or a callback
|
||||||
|
@ -151,8 +156,7 @@ module Middleman
|
||||||
callbacks[path.to_s].call
|
callbacks[path.to_s].call
|
||||||
end
|
end
|
||||||
|
|
||||||
response = ::Middleman::Util.recursively_enhance(response)
|
::Middleman::Util.recursively_enhance(response)
|
||||||
response
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# "Magically" find namespaces of data if they exist
|
# "Magically" find namespaces of data if they exist
|
||||||
|
@ -162,7 +166,8 @@ module Middleman
|
||||||
def method_missing(path)
|
def method_missing(path)
|
||||||
if @local_data.key?(path.to_s)
|
if @local_data.key?(path.to_s)
|
||||||
# Any way to cache this?
|
# Any way to cache this?
|
||||||
return ::Middleman::Util.recursively_enhance(@local_data[path.to_s])
|
@local_data_enhanced ||= ::Middleman::Util.recursively_enhance(@local_data)
|
||||||
|
return @local_data_enhanced[path.to_s]
|
||||||
else
|
else
|
||||||
result = data_for_path(path)
|
result = data_for_path(path)
|
||||||
return result if result
|
return result if result
|
||||||
|
|
|
@ -73,9 +73,10 @@ module Middleman
|
||||||
# end
|
# end
|
||||||
|
|
||||||
# Render using Tilt
|
# Render using Tilt
|
||||||
content = ::Middleman::Util.instrument 'render.tilt', path: path do
|
# content = ::Middleman::Util.instrument 'render.tilt', path: path do
|
||||||
template.render(context, locs, &block)
|
# template.render(context, locs, &block)
|
||||||
end
|
# end
|
||||||
|
content = template.render(context, locs, &block)
|
||||||
|
|
||||||
# Allow hooks to manipulate the result after render
|
# Allow hooks to manipulate the result after render
|
||||||
content = @app.callbacks_for(:after_render).reduce(content) do |sum, callback|
|
content = @app.callbacks_for(:after_render).reduce(content) do |sum, callback|
|
||||||
|
|
|
@ -40,6 +40,7 @@ module Middleman
|
||||||
return if @instrumenting.is_a?(String) && @instrumenting != 'instrument' && !message.include?(@instrumenting)
|
return if @instrumenting.is_a?(String) && @instrumenting != 'instrument' && !message.include?(@instrumenting)
|
||||||
|
|
||||||
evt = ::ActiveSupport::Notifications::Event.new(message, *args)
|
evt = ::ActiveSupport::Notifications::Event.new(message, *args)
|
||||||
|
return unless evt.duration > 30
|
||||||
info "== Instrument (#{evt.name.sub(/.middleman$/, '')}): #{evt.duration}ms\n#{args.last}"
|
info "== Instrument (#{evt.name.sub(/.middleman$/, '')}): #{evt.duration}ms\n#{args.last}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -66,6 +66,8 @@ module Middleman
|
||||||
# Page are data that is exposed through this resource's data member.
|
# Page are data that is exposed through this resource's data member.
|
||||||
# Note: It is named 'page' for backwards compatibility with older MM.
|
# Note: It is named 'page' for backwards compatibility with older MM.
|
||||||
@metadata = { options: {}, locals: {}, page: {} }
|
@metadata = { options: {}, locals: {}, page: {} }
|
||||||
|
|
||||||
|
@page_data = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
# Whether this resource has a template file
|
# Whether this resource has a template file
|
||||||
|
@ -91,6 +93,7 @@ module Middleman
|
||||||
# Note: It is named 'page' for backwards compatibility with older MM.
|
# Note: It is named 'page' for backwards compatibility with older MM.
|
||||||
Contract METADATA_HASH => METADATA_HASH
|
Contract METADATA_HASH => METADATA_HASH
|
||||||
def add_metadata(meta={})
|
def add_metadata(meta={})
|
||||||
|
@page_data = nil
|
||||||
@metadata.deep_merge!(meta)
|
@metadata.deep_merge!(meta)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -98,7 +101,7 @@ module Middleman
|
||||||
# @return [Hash]
|
# @return [Hash]
|
||||||
Contract RespondTo[:indifferent_access?]
|
Contract RespondTo[:indifferent_access?]
|
||||||
def data
|
def data
|
||||||
::Middleman::Util.recursively_enhance(metadata[:page])
|
@page_data ||= ::Middleman::Util.recursively_enhance(metadata[:page])
|
||||||
end
|
end
|
||||||
|
|
||||||
# Options about how this resource is rendered, such as its :layout,
|
# Options about how this resource is rendered, such as its :layout,
|
||||||
|
@ -129,7 +132,6 @@ module Middleman
|
||||||
def render(opts={}, locs={})
|
def render(opts={}, locs={})
|
||||||
return ::Middleman::FileRenderer.new(@app, file_descriptor[:full_path].to_s).template_data_for_file unless template?
|
return ::Middleman::FileRenderer.new(@app, file_descriptor[:full_path].to_s).template_data_for_file unless template?
|
||||||
|
|
||||||
# ::Middleman::Util.instrument 'render.resource', path: file_descriptor[:full_path].to_s, destination_path: destination_path do
|
|
||||||
md = metadata
|
md = metadata
|
||||||
opts = md[:options].deep_merge(opts)
|
opts = md[:options].deep_merge(opts)
|
||||||
locs = md[:locals].deep_merge(locs)
|
locs = md[:locals].deep_merge(locs)
|
||||||
|
@ -140,7 +142,6 @@ module Middleman
|
||||||
|
|
||||||
renderer = ::Middleman::TemplateRenderer.new(@app, file_descriptor[:full_path].to_s)
|
renderer = ::Middleman::TemplateRenderer.new(@app, file_descriptor[:full_path].to_s)
|
||||||
renderer.render(locs, opts)
|
renderer.render(locs, opts)
|
||||||
# end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# A path without the directory index - so foo/index.html becomes
|
# A path without the directory index - so foo/index.html becomes
|
||||||
|
|
|
@ -185,9 +185,7 @@ module Middleman
|
||||||
new_files = ::Middleman::Util.all_files_under(@directory.to_s)
|
new_files = ::Middleman::Util.all_files_under(@directory.to_s)
|
||||||
.reject { |p| @files.key?(p) }
|
.reject { |p| @files.key?(p) }
|
||||||
|
|
||||||
update(new_files, [])
|
update(new_files, []).flatten.map { |s| s[:full_path] }
|
||||||
|
|
||||||
new_files
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Manually trigger update events.
|
# Manually trigger update events.
|
||||||
|
@ -198,14 +196,14 @@ module Middleman
|
||||||
updated = ::Middleman::Util.all_files_under(@directory.to_s)
|
updated = ::Middleman::Util.all_files_under(@directory.to_s)
|
||||||
removed = @files.keys.reject { |p| updated.include?(p) }
|
removed = @files.keys.reject { |p| updated.include?(p) }
|
||||||
|
|
||||||
update(updated, removed)
|
result = update(updated, removed)
|
||||||
|
|
||||||
if @waiting_for_existence && @directory.exist?
|
if @waiting_for_existence && @directory.exist?
|
||||||
@waiting_for_existence = false
|
@waiting_for_existence = false
|
||||||
listen!
|
listen!
|
||||||
end
|
end
|
||||||
|
|
||||||
updated + removed
|
result.flatten.map { |s| s[:full_path] }
|
||||||
end
|
end
|
||||||
|
|
||||||
# Work around this bug: http://bugs.ruby-lang.org/issues/4521
|
# Work around this bug: http://bugs.ruby-lang.org/issues/4521
|
||||||
|
@ -238,7 +236,7 @@ module Middleman
|
||||||
#
|
#
|
||||||
# @param [String, Pathname] path The updated file path.
|
# @param [String, Pathname] path The updated file path.
|
||||||
# @return [void]
|
# @return [void]
|
||||||
Contract ArrayOf[Pathname], ArrayOf[Pathname] => Any
|
Contract ArrayOf[Pathname], ArrayOf[Pathname] => ArrayOf[ArrayOf[IsA['Middleman::SourceFile']]]
|
||||||
def update(updated_paths, removed_paths)
|
def update(updated_paths, removed_paths)
|
||||||
valid_updates = updated_paths
|
valid_updates = updated_paths
|
||||||
.map { |p| @files[p] || path_to_source_file(p, @directory, @type, @options[:destination_dir]) }
|
.map { |p| @files[p] || path_to_source_file(p, @directory, @type, @options[:destination_dir]) }
|
||||||
|
@ -271,6 +269,8 @@ module Middleman
|
||||||
valid_removes,
|
valid_removes,
|
||||||
self
|
self
|
||||||
]) unless valid_updates.empty? && valid_removes.empty?
|
]) unless valid_updates.empty? && valid_removes.empty?
|
||||||
|
|
||||||
|
[valid_updates, valid_removes]
|
||||||
end
|
end
|
||||||
|
|
||||||
# Convert a path to a file resprentation.
|
# Convert a path to a file resprentation.
|
||||||
|
|
|
@ -133,12 +133,21 @@ module Middleman
|
||||||
# Add extension helpers to context.
|
# Add extension helpers to context.
|
||||||
@app.extensions.add_exposed_to_context(context)
|
@app.extensions.add_exposed_to_context(context)
|
||||||
|
|
||||||
content = _render_with_all_renderers(path, locs, context, opts, &block)
|
content = ::Middleman::Util.instrument 'builder.output.resource.render-template', path: File.basename(path) do
|
||||||
|
_render_with_all_renderers(path, locs, context, opts, &block)
|
||||||
|
end
|
||||||
|
|
||||||
# If we need a layout and have a layout, use it
|
# If we need a layout and have a layout, use it
|
||||||
if layout_file = fetch_layout(engine, options)
|
layout_file = fetch_layout(engine, options)
|
||||||
layout_renderer = ::Middleman::FileRenderer.new(@app, layout_file[:relative_path].to_s)
|
if layout_file
|
||||||
content = layout_renderer.render(locals, options, context) { content }
|
content = ::Middleman::Util.instrument 'builder.output.resource.render-layout', path: File.basename(layout_file[:relative_path].to_s) do
|
||||||
|
if layout_file = fetch_layout(engine, options)
|
||||||
|
layout_renderer = ::Middleman::FileRenderer.new(@app, layout_file[:relative_path].to_s)
|
||||||
|
layout_renderer.render(locals, options, context) { content }
|
||||||
|
else
|
||||||
|
content
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Return result
|
# Return result
|
||||||
|
|
|
@ -98,7 +98,7 @@ module Middleman
|
||||||
# @private
|
# @private
|
||||||
# @param [Hash] data Normal hash
|
# @param [Hash] data Normal hash
|
||||||
# @return [Hash]
|
# @return [Hash]
|
||||||
Contract Maybe[Hash] => Maybe[Or[Array, EnhancedHash]]
|
Contract Any => Maybe[Or[Array, EnhancedHash]]
|
||||||
def recursively_enhance(obj)
|
def recursively_enhance(obj)
|
||||||
if obj.is_a? ::Array
|
if obj.is_a? ::Array
|
||||||
obj.map { |e| recursively_enhance(e) }
|
obj.map { |e| recursively_enhance(e) }
|
||||||
|
@ -480,6 +480,8 @@ module Middleman
|
||||||
# @return [String]
|
# @return [String]
|
||||||
Contract String => ArrayOf[String]
|
Contract String => ArrayOf[String]
|
||||||
def collect_extensions(path)
|
def collect_extensions(path)
|
||||||
|
return [] if File.basename(path).start_with?('.')
|
||||||
|
|
||||||
result = []
|
result = []
|
||||||
|
|
||||||
step_through_extensions(path) { |e| result << e }
|
step_through_extensions(path) { |e| result << e }
|
||||||
|
@ -495,6 +497,8 @@ module Middleman
|
||||||
# @return [Middleman::SourceFile] All related file paths, not including the source file paths.
|
# @return [Middleman::SourceFile] All related file paths, not including the source file paths.
|
||||||
Contract ::Middleman::Application, ArrayOf[Pathname] => ArrayOf[::Middleman::SourceFile]
|
Contract ::Middleman::Application, ArrayOf[Pathname] => ArrayOf[::Middleman::SourceFile]
|
||||||
def find_related_files(app, files)
|
def find_related_files(app, files)
|
||||||
|
return [] if files.empty?
|
||||||
|
|
||||||
all_extensions = files.flat_map { |f| collect_extensions(f.to_s) }
|
all_extensions = files.flat_map { |f| collect_extensions(f.to_s) }
|
||||||
|
|
||||||
sass_type_aliasing = ['.scss', '.sass']
|
sass_type_aliasing = ['.scss', '.sass']
|
||||||
|
|
Loading…
Add table
Reference in a new issue