提问人:jrochkind 提问时间:1/11/2012 更新时间:12/14/2018 访问量:79363
config.assets.compile=true,为什么不呢?
config.assets.compile=true in Rails production, why not?
问:
安装的默认 Rails 应用程序已在生产环境中。rails new
config.assets.compile = false
通常的方法是在部署应用之前运行,以确保编译所有资产管道资产。rake assets:precompile
那么,如果我开始生产会发生什么?config.assets.compile = true
我不需要再跑了。我相信会发生的是,第一次请求资产时,它将被编译。这将是第一次对性能的影响(这意味着你通常需要在生产环境中有一个 js 运行时来做到这一点)。但除了这些缺点之外,在资产被延迟编译后,我认为对该资产的所有后续访问都不会对性能造成影响,应用程序的性能将与初始首次点击延迟编译后的预编译资产完全相同。这是真的吗?precompile
我错过了什么吗?还有其他原因不投入生产吗?如果我在生产中有一个 JS 运行时,并且愿意在首次访问资产时牺牲性能下降,以换取不必运行,这有意义吗?config.assets.compile = true
precompile
答:
来自官方指南:
在第一个请求中,将按照上面的开发中所述编译和缓存资产,并更改帮助程序中使用的清单名称以包含 MD5 哈希。
Sprockets 还将 Cache-Control HTTP 标头设置为 max-age=31536000。这向服务器和客户端浏览器之间的所有缓存发出信号,表明此内容(提供的文件)可以缓存 1 年。这样做的效果是减少服务器对此资产的请求数量;该资产很有可能位于本地浏览器缓存或某些中间缓存中。
此模式使用更多内存,性能比默认值差,因此不建议使用。
此外,如果您使用 Capistrano 进行部署,预编译步骤一点也不麻烦。它会为你照顾它。你只是运行
cap deploy
或(取决于您的设置)
cap production deploy
你都准备好了。如果您仍然不使用它,我强烈建议您检查一下。
评论
这与预编译不同,即使在第一次点击之后也是如此:因为文件没有写入文件系统,所以它们不能直接由 Web 服务器提供。一些 ruby 代码将始终参与其中,即使它只是读取缓存条目。
评论
precompile=true
tmp/cache
public/assets
我写了那段指南。
您绝对不想在生产环境中进行实时编译。
当您编译时,会发生以下情况:
对 /assets 中文件的每个请求都会传递给 Sprockets。在对每个资产的第一次请求中,它被编译并缓存在 Rails 用于缓存的任何内容(通常是文件系统)中。
在后续请求中,Sprockets 收到请求,必须查找指纹文件名,检查构成资产的文件(图像)或文件(css 和 js)是否未被修改,然后是否有缓存版本。
这是 assets 文件夹和插件使用的任何供应商/assets 文件夹中的所有内容。
这是很大的开销,因为老实说,代码没有针对速度进行优化。
这将影响资产通过网络到达客户端的速度,并将对您网站的页面加载时间产生负面影响。
与默认值比较:
当资产已预编译且编译处于关闭状态时,将编译资产并将其指纹识别到 .Sprockets 将普通文件名到指纹文件名的映射表返回给 Rails,Rails 将其写入文件系统。清单文件(Rails 3 中的 YML 或 Rails 4 中具有随机名称的 JSON)在启动时由 Rails 加载到内存中,并缓存以供资产辅助方法使用。public/assets
这使得使用正确的指纹资产生成页面的速度非常快,并且文件本身的服务速度很快。两者都比实时编译快得多。
为了获得管道和指纹识别的最大优势,您需要在 Web 服务器上设置遥远的未来标头,并为 js 和 css 文件启用 gzip 压缩。Sprockets 会写入资产的 gzip 版本,您可以将服务器设置为使用这些版本,而无需为每个请求执行此操作。
这样可以尽可能快地以尽可能小的尺寸将资产分发给客户端,从而加快页面的客户端显示速度,并减少(使用遥远的未来标头)请求。
因此,如果您正在实时编译,则为:
- 很慢
- 缺乏压缩
- 将影响页面的呈现时间
对
- 越快越好
- 压缩
- 删除从服务器听到的压缩(可选)。
- 最小化页面的呈现时间。
编辑:(回答后续评论)
管道可以更改为在第一个请求时进行预编译,但这样做存在一些主要障碍。首先是必须有一个指纹名称的查找表,否则帮助程序方法太慢。在按需编译的 senario 下,当编译或请求每个新资产时,需要有某种方式附加到查找表中。
此外,在编译并到位之前,有人将不得不在未知的时间内支付缓慢的资产交付的代价。
默认,即一次离线支付编译所有内容的价格,不会影响公众访问者,并确保在上线之前一切正常。
交易破坏者是它给生产系统增加了很多复杂性。
[编辑,2015年6月]如果您阅读本文是因为正在寻找部署期间编译时间慢的解决方案,那么您可以考虑在本地预编译资产。有关此内容的信息,请参阅资产管道指南。这允许您仅在发生更改时在本地进行预编译,提交更改,然后在没有预编译阶段的情况下进行快速部署。
评论
减少预编译的开销。
Precompile everything initially with these settings in production.rb
# Precompile *all* assets, except those that start with underscore
config.assets.precompile << /(^[^_\/]|\/[^_])[^\/]*$/
然后,您可以简单地将图像和样式表用作 *.html.erb 中的“/assets/stylesheet.css” 或“/assets/web.png”
对于使用 Heroku 的任何人:
如果您部署到 Herkou,它将在部署期间自动为您进行预编译,如果未包含已编译的资产(即 not committed),因此不需要 ,或提交预编译的资产。public/assets
config.assets.compile = true
Heroku 的文档在这里。建议使用CDN来消除dyno资源上的负载。
设置config.asset.compile = false
添加到您的 Gemfile
group :assets do
gem 'turbo-sprockets-rails3'
end
安装捆绑包
跑rake assets:precompile
然后启动服务器
评论
config.asset.compile = true in production.rb
turbo-sprockets-rails3
rake assets:precompile
config.asset.compile = false in production.rb
turbo-sprockets-rails3
因为它打开了一个目录遍历漏洞 - https://blog.heroku.com/rails-asset-pipeline-vulnerability
下一个:了解 Rails 真实性令牌
评论