由 has 安装的默认 Rails 应用程序rails new已config.assets.compile = false投入生产。
rails new
config.assets.compile = false
做事的普通方法是rake assets:precompile在部署您的应用程序之前运行,以确保所有资产管道资产都已编译。
rake assets:precompile
那么如果我config.assets.compile = true在生产中设置会发生什么?
config.assets.compile = true
我不再需要跑步precompile了。我 相信 会发生的是第一次请求资产时,它将被编译。这将是第一次对性能产生影响(这意味着您通常需要在生产环境中使用 js 运行时来执行此操作)。但除了这些缺点之外,在懒惰编译资产之后,我 认为 对该资产的所有后续访问都 不会 影响性能,应用程序的性能将与初始首次点击延迟编译后的预编译资产 完全相同。 这是真的?
precompile
有什么我想念的吗?还有其他不投入config.assets.compile = true生产的理由吗?如果我在生产中有一个 JS 运行时,并且愿意为 首次 访问资产而牺牲性能,以换取不必运行precompile,这有意义吗?
我写了那一点指南。
您绝对不想在生产中进行实时编译。
编译后,会发生以下情况:
对 /assets 中文件的每个请求都会传递给 Sprockets。在对每个资产的 第一次请求时,它会被编译并缓存在 Rails 用于缓存的任何地方(通常是文件系统)中。
在随后的请求中,Sprockets 收到请求并必须查找指纹文件名,检查构成资产的文件(图像)或文件(css 和 js)是否未被修改,然后如果有缓存版本则提供该文件。
这就是assets 文件夹 和 插件使用的任何 vendor/assets 文件夹中的所有 内容。 __
这是很多开销,因为老实说,代码没有针对速度进行优化。
这将影响资产通过网络传输到客户端的速度,并对您网站的页面加载时间产生负面影响。
与默认值比较:
当资产被预编译并且编译关闭时,资产被编译并指纹识别到public/assets. Sprockets 将普通文件名到指纹文件名的映射表返回给 Rails,Rails 将其写入文件系统。清单文件(Rails 3 中的 YML 或 Rails 4 中具有随机名称的 JSON)在启动时由 Rails 加载到内存中,并缓存以供资产辅助方法使用。
public/assets
这使得具有正确指纹资产的页面的生成速度非常快,并且文件本身的服务是来自文件系统的网络服务器快速。两者都比实时编译快得多。
要获得管道和指纹识别的最大优势,您需要在 Web 服务器上设置远期标头,并为 js 和 css 文件启用 gzip 压缩。Sprockets 编写压缩版本的资产,您可以将其设置为服务器使用,从而无需为每个请求都这样做。
这样可以尽可能快地以尽可能小的尺寸将资产发送到客户端,从而加快页面的客户端显示速度,并减少(带有遥远未来的标头)请求。
因此,如果您正在进行实时编译,则它是:
相对
编辑:(回答后续评论)
管道 可以 更改为在第一次请求时进行预编译,但这样做有一些主要障碍。首先是指纹名称必须有一个查找表,否则辅助方法太慢了。在按需编译的情况下,在编译或请求每个新资产时,需要某种方式来附加到查找表。
此外,在所有资产都编译并到位之前,有人将不得不为未知的时间段内缓慢的资产交付付出代价。
默认情况下,编译所有内容的价格一次离线支付,不会影响公共访问者,并确保一切在上线之前都能正常运行。
破坏交易的是它给生产系统增加了很多复杂性。
[编辑,2015 年 6 月] 如果您正在阅读本文,因为您正在寻找在部署期间编译时间缓慢的解决方案,那么您可以考虑在本地预编译资产。有关这方面的信息在资产管道指南中。这允许您仅在发生更改时在本地进行预编译,提交该更改,然后进行快速部署,无需预编译阶段。