views:

75

answers:

1

For better frontend performance, it's best practice to put your scripts at the very end of your HTML code.

I did that for a pretty big and complex page I'm working on right now and the problem I run into are many inline scripts in the views, mostly generated by Rails' built-in JavaScript helpers. These scripts depend on the libraries that used to be loaded in the head before so a lot of stuff stopped to work.

I know, it would be better to separate the JavaScript code totally from the HTML views, I'm a big fan of that, but this is not an option in this project and I'd like to avoid a discussion about this point here.

I found a pretty easy way to gather all the inline scripts and output them the end of the HTML code as well by overwriting the javascript_tag method.

But as I'm new to rails, I'd like to know if this is a good way to go or if there is a better way.

Here is how my code looks like:

def javascript_tag(content_or_options_with_block = nil, html_options = {}, &block)
  content =
    if block_given?
      html_options = content_or_options_with_block if content_or_options_with_block.is_a?(Hash)
      capture(&block)
    else
      content_or_options_with_block
    end

  javascript_code = content_tag(:script, javascript_cdata_section(content), html_options.merge(:type => Mime::JS))
  @_inline_javascript_code ||= ''
  @_inline_javascript_code << content

  return request.xhr? ? concat(javascript_code) : nil
end

Then I out the @_inline_javascript_code variable right before the closing HTML tag. That feels a little hacky to me, but works.

Any thoughts?

+2  A: 

Are you having problems with the speed of your page load? If not, then I think you are optimizing prematurely at the cost of complicating your project. If you are, then I'd look at various different optimization strategies (minimization, combining scripts, etc.), before I'd look at changes that require modifying the default behavior of the framework.

tvanfosson
Thanks for your reply,Yes, loading speed performance is a big issue for our page. I'm aware of all the different optimization strategies, we've done already the low hanging fruits like minimization and combining scripts, asset hosts will be next and we will also create tons of css sprites.We really need to put the scripts to the bottom as the combined and minimized javascript files are still huge and block other assets from beeing loaded.My question here is if there is a nicer way to achieve the same behavior as my script does?
Gregor
You're looking to defer execution, not loading, of the scripts until after the other scripts have been loaded. The only other way I can think to do this is to wrap anything that would ordinarily be executed inline in a function, then add that function to a set of things that gets executed after the external scripts are loaded. It would require modifying all of your javascript, though, which is definitely more work than modifying the tag. It does have the advantage that it makes the developer explicitly aware of the dependencies.
tvanfosson