Script Relocator: Anything wrong with this?

20 views
Skip to first unread message

Uwe Kubosch

unread,
Nov 11, 2015, 5:38:22 AM11/11/15
to Ruby on Rails: Talk
Hi!

For a faster initial render of my pages, I have added a script relocator initializer that scans the page and moves all script tags to the bottom of the body tag.  Order is kept, and the script tags in the `head` tag are marked with data-turbolinks-eval="false" so they are not executed again on new pages when using turbolinks.

It seems to work well and do exactly what I want.  Can anybody see anything wrong with it?  Any reason NOT to use it?  What can it break?

# cat config/initializers/rack-script_relocator.rb
require 'nokogiri'

module Rack
 
class ScriptRelocator
   
def initialize(app)
     
@app = app
   
end

   
def call(env)
      status
, headers, response = @app.call(env)
     
if headers['Content-Type'] !~ %r{^text/html}
       
return status, headers, response
     
end
      response_body
= ''
      response
.each { |part| response_body << part }
      doc
= Nokogiri::HTML(response_body)
      scripts
= doc.css('script')
     
return status, headers, response if scripts.empty?
      scripts
.each do |s|
        s
['data-turbolinks-eval'] = 'false' if s.parent.name == 'head'
        s
.remove
        doc
.at('body') << s
     
end
      transformed_body
= doc.to_html
     
if headers.key?('Content-Length') &&
          headers
['Content-Length'].to_i != transformed_body.length
        headers
['Content-Length'] = transformed_body.length.to_s
     
end
     
return status, headers, [transformed_body]
   
end
 
end
end

Rails.application.config.middleware.use Rack::ScriptRelocator



Frederick Cheung

unread,
Nov 11, 2015, 5:45:36 AM11/11/15
to Ruby on Rails: Talk


On Wednesday, November 11, 2015 at 10:38:22 AM UTC, Uwe Kubosch wrote:
Hi!

For a faster initial render of my pages, I have added a script relocator initializer that scans the page and moves all script tags to the bottom of the body tag.  Order is kept, and the script tags in the `head` tag are marked with data-turbolinks-eval="false" so they are not executed again on new pages when using turbolinks.


Off the top of my head, it seems like it would not work with http://api.rubyonrails.org/classes/ActionController/Streaming.html - which may or may not be a concern.

Fred 

Uwe Kubosch

unread,
Nov 11, 2015, 7:54:49 AM11/11/15
to Ruby on Rails: Talk
Yeah, thanks for the tip.  I will disable it for streaming responses.  For my specific app it is not a concern since I don't stream HTML responses, and the script relocator is only active for text/html responses.  I will add detection for streaming and leave the response alone if it is a streaming response so I don't have to worry about it if I later decide to stream text/html responses (like from a document archive).
Reply all
Reply to author
Forward
0 new messages