【问题标题】:How to download a JavaScript file without parsing it?如何在不解析的情况下下载 JavaScript 文件?
【发布时间】:2015-01-23 20:52:13
【问题描述】:

为了提高性能,我想在我的登录页面上预取一个 1.2 MB 的旧版 JavaScript 库。仅在用户登录后才需要此库。WebPageTest 向我显示 Chrome 下载后需要大约 700 毫秒的 CPU 来处理文件。是否可以在用户的​​浏览器上缓存文件,但不执行/解析 JavaScript?

我的理想流程:

  • 加载登录页面
  • 使用脚本标签的asyncdefer属性异步加载js库
    • 不解析,直到用户登录后才真正使用该库
  • 用户登录
  • 加载用户主页并从缓存中加载 js 库(如果存在,否则从服务器获取 - 非异步)并解析
    • 我只想在这里支付 700 毫秒的解析时间

我研究过可能将脚本属性的“类型”更改为text/plain,但似乎this is not possible。即使这确实有效,在我看来,我也会面临某种eval 邪恶。

我为什么要这样做?我有一个很小的时间窗口,当用户键入他们的凭据时,浏览器基本上是空闲的。我想利用这段时间下载这个大库,以便抢先加载下一页。我可以通过在后台下载文件来补充浏览器的缓存,但是在浏览器接收到库并解析/执行文件后,CPU 会出现 700 毫秒的峰值。我想避免登录页面出现这种 CPU 峰值。

您可以在此 WPT 屏幕截图的右下方看到 CPU 峰值:

【问题讨论】:

  • 将文件的内容包装在一个函数中,以通常的方式包含</body>之前的文件。当用户登录时,执行该函数。
  • 你为什么要这样做?如果您将<script> 放在<body> 的底部(就像您应该为JS 所做的那样),您将不会延迟渲染,这听起来像是您的问题。
  • @PlantTheIdea - 渲染效果很好 - 大约需要 1.3 秒才能完成。 CPU 峰值使浏览器在峰值期间对用户交互的响应降低 - 我添加了一个屏幕截图来说明问题。
  • @adeneo 如果我内联文件,它不会被缓存,这是我的目标......
  • 为什么你认为在</body>之前添加它不会像任何其他文件一样被缓存?

标签: javascript performance webpagetest


【解决方案1】:

尝试使用XMLHttpRequest

var req = new XMLHttpRequest();
req.open("GET", "/path/to/your/script.js");
req.send(); // This line fetches the file

如果你想对这个文件的内容做点什么, 在.send() 行之前设置req.onload

var req = new XMLHttpRequest();
req.open("GET", "/path/to/your/script.js");
req.onload = function()
{
    console.log(this.response);
}
req.send(); // This line fetches the file

最后,在服务器端,确保文件是可缓存的。

【讨论】:

  • 你是完全正确的 - 使用 XHR 水合缓存但不执行 JS。我使用来自quirksmode.org/js/xmlhttp.html 的代码片段来完善这种方法。
  • 另一种方法是使用浏览器资源提示 。这有很好的浏览器支持。 browser support
猜你喜欢
  • 2018-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-20
  • 1970-01-01
  • 2019-08-18
  • 2021-05-20
  • 2012-08-01
相关资源
最近更新 更多