Rails 各位怎么管理 css 和 javascript assets

tonytonyjan · 2012年09月03日 · 最后由 jonny 回复于 2012年09月05日 · 5845 次阅读

就依照 RESTful 的设计,例如一个 Post resource 就有 new、edit、show 和 index 四个 page,如果我对于这四个页面都有他们各自的 css 和 script,我现在是都写在 app/assets/javascripts/posts.js.coffeeapp/assets/stylesheets/posts.css.scss 里面。

但这样进入各个 page 常会载入用不到的东西(例如进入 show,会载入 posts.js.coffeeposts.css.scss 但只用得到里面的 1/4 的程式码和 style)。

但若把 javascript 和 css 又各分成 4 个,这样会变成 8 个档案。在进行 assets precompile 之前,我要在 config/environments/production.rb 先定义额外的 assets:

config.assets.precompile += %w(posts_new.css posts_edit.css posts_show.css posts_index.css)

这样会变得很冗长,所以想来此请教前辈们该如何管理这些档案比较恰当?

把全网站的 javascript 和 css 档案 precompile 成 1 个档案是好方法吗?

你没理解 assets 的真正意义。。。 assets 就是为了把各个 css 合并到一起,这样只用请求一次,你加那么多 precompile 干啥

理解你这个需求。解决的话需要用到前端的 js 动态加载。

可以看看 requirejs, headjs, yepnopejs 之类的前端模块加载工具。

#1 楼 @ywencn 你也没理解我真正的需求啊 我现在就是一个页面的 css 和 js request 各一个,所以每页也才发送两次请求而已, 而每页 request 的 css、js 档案各有属于自己的就是了。 并不会在同一页中下载一个以上的 css 或 js。

#2 楼 @Saito 感谢你的回应,所以 Rails 对于这个问题没有 Rails 自身的正规解法吗?

#4 楼 @tonytonyjan 本身这种 precompile 的方式就决定了没法按需加载。

如果能做到 require 的 application.js 可以根据页面不同加载不同的话就行了。问题是做不到.( 或者说我不知道有什么办法。

在前端领域近期也有非常多的这样的尝试。让我觉得 asset-pipeline ( sprocket 也许不是问题的最终答案。

匿名 #6 2012年09月03日

@tonytonyjan 我还是比较支持蜗牛的,别问蜗牛是谁,就是这 ywencn 家伙 因为浏览器有缓存~恩,缓存,哈哈

@Saito 我觉得用一个文件好。 如果用户只访问一个页面,你亏了。 但是如果用户访问 2 两个页面或以上,你就赚大了。

#7 楼 @hooopo 第一次打开太慢直接把你关了...

#8 楼 @bhuztez 这要看 css 和 js 到底有多大。假设是 500k 的,开启 gzip 以后也就 100k。现在一个 100k 的图片很普通吧。

我是这样:js 库都打包成一个,个别页面要用的逻辑写在页面里,多个页面共用的才写到独立的 js。

其实只要不用 jqueryui, 全部合在一起还是不大的。

把 CSS+JS 写到压缩后体积大于 500K 是很少的,所以合在一个文件吧。下载时间低于每次 HTTP 请求传输前的延迟。

看了楼上的回复,有两点我不赞同: 一次加载可以利用缓存,难道多次加载就不能利用缓存了吗? asset pipeline 并不是说非要把所有 js 和 css 合并成一个,你可以看下 http://rubyonrails.org 的官网有多少次请求。如果有人找到官方的说明,请附上链接。

#3 楼 @tonytonyjan 同样你的想法,按需加载。我一般是这么做的,在 layout 里加上

= javascript_include_tag "application"
= yield :javascripts

通用的放到 application.js 里,个性的 view 里使用

content_for :javascript do
   #...
end

来加载,如果像你这样命名很规范的,就更简单了,

content_for :javascript do
   javascript_include_tag "controller_name/#{action_name}"
end

另外config.assets.precompile里是可以用正则来匹配文件的,没必要一个个写。

还是 requirejs 或者 seajs 的前端方案看起来舒服一点

#13 楼 @camel 额,这个自己根据实际权衡吧,我是觉得如果加起来不到 100K 就没必要分开。 如果是用了各种 js 合起来很大就像你那样分开蛮好

#13 楼 @camel 这就是简单的小学数学题目啊 假设你有公共的 css 是 akb,你按需加载成 n 份。用户访问了 m 个不同页面。 1.最坏情况多建立了 m-1 次 http 请求 2.最坏情况浪费了 makb 的宽带

#3 楼 @tonytonyjan js 和 css 是有缓存的吧

不能合并在一个文件里啊 如果是上百上千个 action 的大项目 把他们用到的 js 合在一起 什么事情都有可能会发生诶

@hooopo 不一定要每个页面一个啊。我觉得 css 是没必要分了,反正大也大不到哪里去,顶多加一个 admin 后台的文件。js 可以按大的功能块合成几个,比如用户管理部分的 js 可以合成一个,一般浏览网站页面的时候就没必要加载。

#19 楼 @jonny 后台管理的静态文件和前台的分开这是共识吧。。

@hooopo 我说的是用户个人设置,只是打个比喻,观点就是如果觉得 js 一次加载太大,影响用户体验是可以按照功能切分开来的。

#21 楼 @jonny 如果真想做到最优要根据用户访问的历史记录来建模。。综合带宽、静态文件大小等因素,求期望。

@hooopo 这个估计是根据每个网站自己的实际情况来的,前提也是 js 很大的情况才需要。我想的只是简单的划分,没有想的这么细致,呵呵。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号