chrome 中的随机高内容下载时间?

Random high content download time in chrome?

我们有一个 API,它在 chrome 中随机占用大量 content download 时间,它在 firefox 中始终运行良好,只占用少数 ms。响应大小为 20kb 未压缩和 4kb 压缩。同样的请求也可以使用 curl 正常工作。

我们尝试过的事情:

  1. 禁用 If-None-Match header 以禁用来自浏览器的缓存响应。
  2. 尝试各种压缩(gzip、deflate、br)。
  3. 禁用压缩。
  4. 正在禁用所有 chrome 扩展程序。

相同的请求有时在 chrome 上工作正常,但随机 returns 非常长的内容下载时间。

我们无法理解此问题的根本原因。这次我们可以尽量减少哪些其他事情?

我在这里提出了三个请求,第三个花费了最多的时间(在最后一个峰值之前)。 CPU 似乎不会在较长时间内达到极限。大部分时间都是空闲时间。

此外,当使用 Replay XHR 菜单重播通话时,内容下载周期从 2 秒下降到 200 毫秒。

我想你可能做错了。™

从根本上说,如果这真的只发生在 Chrome 上,那么可能是客户端代码造成的,您没有透露任何细节。

否则,您正在尝试使用前端工具调试呈现为后端条件的内容(基于 nginx 标记上的选择):

  • 您是否尝试过使用 tcpdump(8) 来解决问题?什么数据包在什么时间交换?

  • 您是否尝试记录 nginx 接收和处理请求的时间?例如,$request_time?

  • 服务器在哪里?也许您正在经历数据包丢失,这可能需要超时并重新传输某些 TCP 数据包,这总是会引入随机延迟?

最后,最后一种可能性是该字段并不像您认为的那样 - 听起来它可能会受到 CPU 负载的影响,因为这是 XMLHTTPRequest (XHR) 处理——也许你 运行 一些随机消耗大量 CPU 用户跟踪的广告会降低你的指标?

您是否偶然尝试实现无限滚动?如果是,请尝试拖动滚动条而不是使用鼠标滚轮。出于某种原因,Chrome 似乎在处理鼠标滚动事件。如果滚动条工作正常,请继续阅读。

此 post 提供了经历类似事情的人的详细演练 - https://github.com/TryGhost/Ghost/issues/7934

我在 scroll 事件上附加了一个观察者,它会触发 AJAX 请求。我限制了请求,可以看到只发送了 1 个。我观察了我的开发服务器 return 几毫秒内的响应,但 chrome 会有 2 秒的延迟。没有渲染,没有 api 调用,没有脚本执行。但是 "Content Download" 对于 14kb 需要 3 秒。其他浏览器没有这个问题。

我偶然发现使用 requestAnimationFrame 而不是 setTimeout 可以解决问题的建议。这种方法似乎在 "Waiting" 或绿色很重要时有效,而对于 "Content Download" 或蓝色则不太有效。

经过数小时的挖掘,我尝试在 mousewheel 事件中有条件地调用 e.preventDefault(),令我惊讶的是,它成功了。

注意几点:

1) 我没有使用 mousewheel 事件进行 api 调用。我将 scroll 事件与节流一起使用。

2) mousewheel 事件是非标准事件,不应使用。参见 https://developer.mozilla.org/en-US/docs/Web/Events/mousewheel

3) 但是在这种情况下,由于 chrome,您必须观察和处理 mousewheel 事件。如果其他浏览器不支持该事件,则会忽略该事件,我还没有看到它在其他浏览器中引起问题。

4) 你不想每次都调用 preventDefault() 因为这样会禁用鼠标滚动 :) 如果你使用垂直滚动,你只想在 deltaY 为 1 时调用它.从附图中可以看出,当你基本上不能再滚动时,deltaY 为 1。即使页面无法滚动,mousewheel 事件也会被触发。作为旁注,当您垂直滚动时 deltaX 为 -0,水平滚动时 deltaY 为 -0。

我的解决方案:

window.addEventListener("mousewheel", (e) => {
    if (e.deltaY === 1) {
        e.preventDefault();
    }
})

这是我见过的唯一可行的解​​决方案,我还没有在其他地方看到它被提及或讨论过。希望对您有所帮助。

console log of mousewheel event