chrome 中的随机高内容下载时间?
Random high content download time in chrome?
我们有一个 API,它在 chrome 中随机占用大量 content download
时间,它在 firefox 中始终运行良好,只占用少数 ms
。响应大小为 20kb 未压缩和 4kb 压缩。同样的请求也可以使用 curl 正常工作。
我们尝试过的事情:
- 禁用
If-None-Match
header 以禁用来自浏览器的缓存响应。
- 尝试各种压缩(gzip、deflate、br)。
- 禁用压缩。
- 正在禁用所有 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
我们有一个 API,它在 chrome 中随机占用大量 content download
时间,它在 firefox 中始终运行良好,只占用少数 ms
。响应大小为 20kb 未压缩和 4kb 压缩。同样的请求也可以使用 curl 正常工作。
我们尝试过的事情:
- 禁用
If-None-Match
header 以禁用来自浏览器的缓存响应。 - 尝试各种压缩(gzip、deflate、br)。
- 禁用压缩。
- 正在禁用所有 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