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

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

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

那么,如果我在生产环境中设置config.assets.compile = true会发生什么?

我不再需要运行precompile了。I 相信将会发生的是当资产第一次被请求时,它将被编译。这将是第一次性能上的打击(这意味着你通常需要在生产中使用js运行时来做这件事)。但除了这些缺点之外,在资产被惰性编译后,我认为所有后续对该资产的访问将有没有性能命中,应用程序的性能将与预编译资产在初始的第一次命中惰性编译后一样为完全一样这是真的吗?

我还遗漏了什么吗?还有其他不在生产环境中设置config.assets.compile = true的原因吗?如果我在生产中有一个JS运行时,并且愿意为了资产的第一个访问而降低性能,以换取不必运行precompile,这有意义吗?

76661 次浏览

来自官方指南:

在第一个请求中,资产按照上面开发中概述的那样被编译和缓存,并且helper中使用的清单名称被更改为包含MD5散列。

Sprockets还将缓存控制HTTP报头设置为max-age=31536000。这表明服务器和客户端浏览器之间的所有缓存都可以缓存1年的内容(所服务的文件)。这样做的效果是减少服务器对该资产的请求数量;资产很有可能位于本地浏览器缓存或某些中间缓存中。

使用内存较多,性能比默认值差,不推荐使用。

此外,如果你使用Capistrano进行部署,预编译步骤一点也不麻烦。它会帮你解决的。你就跑

cap deploy

或者(取决于您的设置)

cap production deploy

一切都准备好了。如果你还没有使用它,我强烈建议你去试试。

它不会和预编译一样,即使是在第一次命中之后:因为文件没有写入文件系统,它们不能直接由web服务器提供。一些ruby代码总是会涉及到,即使它只是读取一个缓存条目。

那部分指南是我写的。

您肯定不希望在生产环境中实时编译。

当你开始编译时,会发生这样的情况:

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

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

这是插件使用的任何供应商/资产文件夹中的资产文件夹而且中的一切

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

这将会影响到资产传输到客户端的速度,并会对站点的页面加载时间产生负面影响。

与默认值比较:

当资产被预编译并且compile关闭时,资产被编译并被指纹识别到public/assets。Sprockets将一个从普通文件名到指纹文件名的映射表返回给Rails, Rails将其写入文件系统。清单文件(在Rails 3中是YML,在Rails 4中是随机命名的JSON)在启动时由Rails加载到内存中,并缓存以供资产帮助器方法使用。

这使得生成具有正确指纹资产的页面非常快,并且文件本身的服务也非常快。两者都比实时编译快得多。

为了获得管道和指纹的最大优势,你需要在你的web服务器上设置远未来的头文件,并为js和css文件启用gzip压缩。Sprockets编写gzip版本的资产,您可以将其设置为服务器使用,从而消除了对每个请求都这样做的需要。

这将以尽可能快的速度将资产发送到客户端,并以尽可能小的尺寸,加快页面的客户端显示,并减少(使用遥远的头)请求。

所以如果你正在编译,它是:

  1. 非常缓慢的
  2. 没有压缩
  3. 会影响页面的渲染时间吗

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

编辑:(回答后续评论)

管道可以可以更改为在第一个请求时预编译,但这样做有一些主要的障碍。首先,必须有一个查找表来查找指纹名称,否则辅助方法太慢了。在按需编译的场景下,当每个新资产被编译或请求时,需要某种方式将其附加到查找表中。

此外,有人将不得不在一段未知的时间内为缓慢的资产交付付出代价,直到所有的资产都被编译并就位。

默认情况下,编译所有内容的代价一次性离线支付,不会影响公共访问者,并确保在内容上线之前一切正常。

问题在于它给生产系统增加了很多复杂性。

[编辑,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” 或“/资产/ web.png”< / p >

对于使用Heroku的用户:

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

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

设置config.asset.compile = false

添加到您的Gemfile

group:assets do 宝石的turbo-sprockets-rails3 结束代码< / > < / p >

安装bundle

运行rake assets:precompile

然后启动服务器

因为它打开了一个目录遍历漏洞——https://blog.heroku.com/rails-asset-pipeline-vulnerability