在Rails生产中,config.assets.compile = true,为什么不呢?

jro*_*ind 176 ruby-on-rails production-environment asset-pipeline

通过安装在默认的Rails应用程序rails new具有config.assets.compile = false生产.

通常的做法是rake assets:precompile在部署应用程序之前运行,以确保编译所有资产管道资产.

那么如果我config.assets.compile = true投入生产会发生什么?

precompile不再需要跑步了.我认为会发生的是第一次请求资产时,它将被编译.这将是第一次出现性能损失(这意味着您通常需要在生产中使用js运行时才能执行此操作).但除了这些缺点之外,在资产被懒散编译之后,我认为对该资产的所有后续访问都不会受到性能影响,应用程序的性能将与初始首次命中的懒惰编译之后的预编译资产完全相同.这是真的?

有什么我想念的吗?没有投入config.assets.compile = true生产的其他原因?如果我在生产中有一个JS运行时,并且愿意为首次访问资产而采取降级性能的权衡,作为不必运行的回报precompile,这是否有意义?

Ric*_*lse 250

我写了一点指南.

你绝对不想在生产中进行编译.

编译时,会发生以下情况:

/ assets中的每个文件请求都传递给Sprockets.在对每个资产的第一个请求中,它被编译并缓存在Rails用于缓存的任何内容中(通常是文件系统).

在后续请求中,Sprockets接收请求并且必须查找指纹文件名,检查组成资产的文件(图像)或文件(css和js)是否未被修改,然后是否有缓存版本服务.

这是一切的资产文件夹,并通过插件使用的任何供应商/资产的文件夹.

这是一个很大的开销,说实话,代码没有针对速度进行优化.

这将影响资产通过电汇到客户端的速度,并将对您网站的页面加载时间产生负面影响.

与默认值比较:

当资产被预编译并且编译关闭时,资产被编译并指纹识别public/assets.Sprockets将普通指纹文件名的映射表返回给Rails,Rails将其写入文件系统.清单文件(Rails 3中的YML或Rails 4中具有随机名称的JSON)在启动时被Rails加载到Memory中,并被缓存以供资产助手方法使用.

这使得具有正确的指纹资产的页面的生成非常快,并且文件本身的服务是快速的从文件系统的web服务器.两者都比实时编译快得多.

要获得管道和指纹识别的最大优势,您需要在Web服务器上设置远期标头,并为js和css文件启用gzip压缩.Sprockets会编写gzip压缩版本的资产,您可以将服务器设置为使用,从而无需为每个请求执行此操作.

这样可以尽可能快地将资产输出到客户端,并以尽可能小的尺寸加速页面的客户端显示,并减少(使用远期标头)请求.

因此,如果您正在进行实时编译,则:

  1. 非常慢
  2. 缺乏压缩
  3. 会影响页面的渲染时间

  1. 尽可能快地
  2. 压缩
  3. 从服务器中删除压缩无意中听到(可选).
  4. 最小化页面的渲染时间.

编辑:(回复后续评论)

可以在第一次请求时将管道更改为预编译,但这样做有一些主要障碍.首先是必须有一个指纹表的查找表,或者辅助方法太慢.在按需编译的情况下,在编译或请求每个新资产时,需要以某种方式附加到查找表.

此外,有人必须在一段未知的时间内支付缓慢资产交付的价格,直到所有资产都编制完成并到位.

默认情况下,编译所有内容的价格一次性离线支付,不会影响公众访问者,并确保在事情发生之前一切正常.

这个交易破坏者会给生产系统增加很多复杂性.

[编辑,2015年6月]如果您正在阅读此内容,因为您正在寻找部署期间编译速度慢的解决方案,那么您可以考虑在本地预编译资产.有关这方面的信息,请参阅资产管道指南.这允许您仅在存在更改时进行本地预编译,提交,然后在没有预编译阶段的情况下进行快速部署.


dbK*_*per 7

通过预编译来减少开销.

Precompile everything initially with these settings in production.rb
# Precompile *all* assets, except those that start with underscore
config.assets.precompile << /(^[^_\/]|\/[^_])[^\/]*$/
Run Code Online (Sandbox Code Playgroud)

然后你可以简单地使用图像和样式表,如*.html.erb中的"/assets/stylesheet.css"或"/assets/web.png"


Wil*_*iss 5

对于使用Heroku的任何人:

如果部署到Herkou,则如果不包括(即public/assets未提交)已编译的资产(因此不需要config.assets.compile = true或提交预编译的资产),它将在部署期间自动为您进行预编译。

Heroku的文档在这里。建议使用CDN消除dyno资源上的负载。