小编典典

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

all

由 has 安装的默认 Rails 应用程序rails newconfig.assets.compile = false投入生产。

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

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

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

有什么我想念的吗?还有其他不投入config.assets.compile = true生产的理由吗?如果我在生产中有一个 JS 运行时,并且愿意为
首次 访问资产而牺牲性能,以换取不必运行precompile,这有意义吗?


阅读 62

收藏
2022-07-08

共1个答案

小编典典

我写了那一点指南。

您绝对不想在生产中进行实时编译。

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

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

在随后的请求中,Sprockets 收到请求并必须查找指纹文件名,检查构成资产的文件(图像)或文件(css 和
js)是否未被修改,然后如果有缓存版本则提供该文件。

这就是assets 文件夹 插件使用的任何 vendor/assets 文件夹中的所有 内容。 __

这是很多开销,因为老实说,代码没有针对速度进行优化。

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

与默认值比较:

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

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

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

这样可以尽可能快地以尽可能小的尺寸将资产发送到客户端,从而加快页面的客户端显示速度,并减少(带有遥远未来的标头)请求。

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

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

相对

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

编辑:(回答后续评论)

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

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

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

破坏交易的是它给生产系统增加了很多复杂性。

[编辑,2015 年 6 月]
如果您正在阅读本文,因为您正在寻找在部署期间编译时间缓慢的解决方案,那么您可以考虑在本地预编译资产。有关这方面的信息在资产管道指南中。这允许您仅在发生更改时在本地进行预编译,提交该更改,然后进行快速部署,无需预编译阶段。

2022-07-08