首页 > 解决方案 > 服务工作者“内容下载”可以比实际获取时间长吗?

问题描述

我试图了解铬在从服务人员提供内容时实际上在做什么。但我看到了一个非常奇怪的行为。

这是测试用例:我创建了一个非常简单的应用程序,它公开了一个链接。当用户点击链接时,它会获取一个 2MB 的 javascript 文件(之前在 service worker 安装阶段存储在缓存中)。服务工作者拦截获取并使用缓存提供文件。

我在主线程中添加了一个 console.log 来测量获取响应需要多长时间:

function fetchScript() {
    const t = performance.now();
    fetch("portal.js")
    .then((response) => console.log("took", performance.now() - t, response.text()));
}

我将此与 devtools 中的 Network 选项卡进行了比较:

在此处输入图像描述

如果我们在网络选项卡中打开其中一个请求的详细信息,我们将看到时间花费在 上Content Download,在官方规范中指的是The browser is receiving the response

如何Content Download操作可以比实际 fetch 更长?我期望控制台日志显示的时间比网络选项卡中的时间长(或至少相等)。有人真的知道期间发生了什么Content Download吗?

标签: javascriptchromiumservice-worker

解决方案


因此,阶段似乎是Content Download指读取响应正文的时间(从标头可用到正文已被读取)

function fetchScript() {
    const t = performance.now();
    fetch("portal.js")
    .then((response) => console.log("took", performance.now() - t, 
response.text()));
}

获取在标头可用时解决,而不是在读取正文时解决。这就是为什么记录的时间可以小于Content Download网络时间的时间。要将Content Download时间包含在控制台记录的时间中,我们需要读取响应:

function fetchScript() {
    const t = performance.now();
    fetch("portal.js")
    .then(response => response.text())
    .then(response => console.log("took", performance.now() - t));
}

(然而,Content Download时间是一种浏览器度量,它没有考虑事件循环,更具体地说,事件循环处理在读取响应后排队的微任务所花费的时间:response => console.log("took", performance.now() - t)。因此,我们赢了' t 测量网络选项卡和 console.log 之间的相同时间)


推荐阅读