可以在application.js中使用我的所有javascript,并使用require_tree吗?

时间:2014-05-04 21:10:20

标签: ruby-on-rails ruby-on-rails-4

我对Rails相当陌生,这更像是一个"最佳实践"题。如果我应该在另一个SE网站上询问,请告诉我。

到目前为止,我一直认为资产管道是理所当然的。随着资产(CSS和JS)变得越来越复杂,我开始意识到,为每一页加载所有资源可能效率不高。我现在拥有的是这样的:

的application.js:

...
//= require_tree .

$(document).ready(function() {

    //page A scripts/handlers
    ...

    //page B scripts/handlers
    ...

    //page C scripts/handlers
    ...
});

我的理解是,由于require_tree,整个代码将加载到页面A,页面B和页面C上。这是对的吗?

我是否应该开始考虑删除require_tree并将这些资产隔离到他们自己的控制器特定资产文件中,而application.js和application.css只包含" shared"脚本/处理程序/样式,然后加载:

<%= javascript_include_tag params[:controller] %>

<%= stylesheet_link_tag params[:controller] %>

还是我在思考呢?我主要担心的是,随着我的应用程序变得越来越复杂,我需要有效地管理复杂性。所以我现在宁愿以正确的方式开始做事,而不是稍后处理头痛。

2 个答案:

答案 0 :(得分:3)

这确实是一个偏好问题。没有对错(取决于你问的是谁)所以真的,你希望你的应用如何运作?

你是绝对正确的,使用application.js中的require_tree会将你的所有js文件合并到一个资产中,并且它将被加载到每个页面上,但是当rails被放入生产模式,你的资产是预编译的,会发生两件事

  • 代码将缩小
  • 您的资产将被指纹识别&#39;用于缓存目的

然后会发生什么,是你的“大”&#39; javascript文件将变得更小。另一件事情是,rails会将此压缩文件移动到public文件夹中,使其成为静态资产。一旦发生这种情况,运行rails的Web服务器可以让您的浏览器知道它可以缓存它,因此即使您的应用程序中的每个页面都会引用它,您的浏览器也只会下载一次(直到指纹发生变化或您清除你的缓存)

作为一个有效性的想法,我最近一直在努力的应用程序有一个非常大的javascript结构,其中未压缩的application.js文件以2MB +下载。在开发模式下,每次重新加载页面时都会下载,所以你可以想象,这非常慢。

一旦我们将rails置于生产模式并编译了我们的资产,js文件就变成了大约500KB,并且下载了一次。好多了!

对于你的CSS文件和图片也是如此,尽管显然图像不会成为一个包含所有内容的大图像文件。

如果你和一些硬核JS人员交谈,使用资产管道并不是最好的选择,因为在JS中处理依赖关系可能会有点难看,此时你应该考虑使用诸如RequireJS或Browserify之类的库。但是鉴于你对rails很陌生,我现在就避免这样做。

所以,在它结束时,它真的是你的选择。如果您想为每个页面添加一个javascript文件,那就去吧!资产管道将按预期工作,它仍然会将它们编译成静态文件,浏览器仍然会缓存它们。但是,您需要做的一件事就是告诉您要编译的不仅仅是一个JS文件。

默认情况下,在生产环境中,rails只会预编译application.js文件。如果您选择拥有多个文件,那么这不是您想要的。您需要对此进行更改以告知您希望它编译资产文件夹中的所有JS文件。您可以在production.rb文件中执行此操作。一个快速的谷歌或堆栈溢出搜索将告诉你如何做到这一点,但它真的很直接。

如果您选择坚持使用require_tree选项,那么您不需要做任何事情,并且已经为您设置了生产中的rails :)

答案 1 :(得分:0)

通常我喜欢在布局上使用content_for。 (例如:application.html.erb)

<% if content_for?(:custom_css) %>
<%= yield(:custom_css) %>
<% end %>

<% if content_for?(:custom_js) %>
<%= yield(:custom_js) %>
<% end %>

并在自定义视图中包含文件:(例如:index.html.erb)

<% content_for :custom_css do %>
<%= stylesheet_link_tag "common/timepicker/jquery.timepicker", :media => 'all', "data-turbolinks-track" => true %>
<% end %>

我不想将所有脚本和样式放在application.js上,因为在一些大型应用程序(没有单页应用程序)中,它会删除许多未在请求中使用的样式和脚本。对于某些具有角色和管理员或默认用户区域的应用程序,可能有些用户不需要加载所有脚本和样式。