任务队列真的有优先级排序系统吗?

Is there really a prioritization system for the task-queues?(任务队列真的有优先级排序系统吗?)
本文介绍了任务队列真的有优先级排序系统吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定以下脚本: 数据-lang="js"数据-隐藏="假"数据-控制台="真"数据-巴贝尔="假">

console.log("start of hard script");
const start = performance.now();
setTimeout(() => console.log('setTimeout'),0);
document.addEventListener("DOMContentLoaded", () => {
  console.log('fired event DOMContentLoaded')
});
document.addEventListener("click" , () => {
  console.log("fired event click")
});
while(start + 1000 > performance.now());
console.log("end of hard script")

我确信我在某处读到用户交互队列将比计时器队列具有更高的优先级。

我想看看优先级是如何定义的,但看到in the specs:

让taskQueue是事件循环的任务队列之一,在 实现定义的方式,所选的约束 任务队列必须至少包含一个可运行的任务。如果没有 这样的任务队列,然后跳到下面的微任务步骤。
如果WHATWG没有定义具体的队列顺序,我想知道实现者运行的标准是什么?他们如何评价排队的重要性?最后,我希望看到一个例子,说明这些队列的顺序,如果可能的话。

推荐答案

我想知道实现者运行的标准是什么?他们如何评估队列的重要程度?

这基本上是他们的决定,是根据多年的经验做出的设计选择,这些经验考虑了他们的工具是如何使用的,以及应该优先考虑什么(可能也是常识的很大一部分)。

WHATWG实际上根本没有定义这个任务的优先顺序应该如何实现。它们所做的只是定义各种任务源(甚至不是任务队列),以确保在同一个源中排队的两个任务将以正确的顺序执行。

我们最接近于定义某种优先级的是传入的Prioritized Task SchedulingAPI,它将为我们Web作者提供发布优先级任务的平均值,具有三个优先级:"user-blocking""user-visible""background"

要检查浏览器实际实现了什么,您必须仔细检查它们的源代码并进行彻底检查。
我自己已经在那里呆了几个小时,我所能告诉你的是,如果你想全面了解情况,你最好有动力。
您可能会感兴趣的几点:

  • 所有浏览器根本不公开相同的行为。
  • 在Chrome中,setTimeout()的最小延迟仍为1ms(https://crbug.com/402694)
  • 在Firefox中,因为Chrome的1ms延迟会在一些网页上产生不同的结果,所以他们只为页面加载之前计划的定时器创建了一个特殊的极低优先级任务队列,而在加载页面之前计划的定时器则在普通优先级任务队列中排队。(https://bugzil.la/1270059)
  • 至少在Chrome中,每个任务队列has a "starvation" protection,通过在一段时间(不确定有多少时间)之后,让优先级较低的队列也执行它们的一些任务,从而防止所述队列用自己的任务淹没事件循环。

最后,如果可能的话,我希望看到一个显示这些队列顺序的示例。

如前所述,这相当复杂,因为没有一个订单。

您自己的示例非常是一个很好的测试,它在我的Chrome浏览器中确实正确地显示了UI任务队列比计时器任务队列具有更高的优先级(While循环负责我所说的1ms的最小延迟)。但是,对于DOMContent Loaded,我必须承认我不能完全确定它显示了什么重要的东西:HTML解析器也被While循环阻塞,因此只有在整个脚本执行之后才会发布触发事件的任务。

但鉴于此任务发布在DOM Manipulation task source上,我们可以通过强制使用此任务源的其他任务(例如script.onerror)来检查其优先级。 下面是您的代码片段的更新,还有几个任务源,它们的调用顺序与我的Chrome的优先级顺序相反:

数据-lang="js"数据-隐藏="真"数据-控制台="真"数据-巴贝尔="假">
const queueOnDOMManipulationTaskSource = (cb) => {
  const script = document.createElement("script");
  script.onerror = (evt) => {
    script.remove();
    cb();
  };
  script.src = "";
  document.head.append(script);
};
const queueOnTimerTaskSource = (cb) => {
  setTimeout(cb, 0);
}
const queueOnMessageTaskSource = (cb) => {
  const { port1, port2 } = new MessageChannel();
  port1.onmessage = (evt) => {
    port1.close();
    cb();
  };
  port2.postMessage("");
};
const queueOnHistoryTraversalTaskSource = (cb) => {
  history.pushState("", "", location.href);
  addEventListener("popstate", (evt) => {
    cb();
  }, { once: true });
  history.back();
}
const queueOnNetworkingTaskSource = (cb) => {
  const link = document.createElement("link");
  link.onerror = (evt) => {
    link.remove();
    cb();
  };
  link.href = ".foo";
  link.rel = "stylesheet";
  document.head.append(link);
};
const makeCB = (log) => () => console.log(log);
console.log("The page will freeze for 3 seconds, try to click on this frame to queue an UI task");
// let the message show 
setTimeout(() => {
  window.scheduler?.postTask(makeCB("queueTask background"), {
    priority: "background"
  });
  queueOnHistoryTraversalTaskSource(makeCB("History Traversal"));
  queueOnNetworkingTaskSource(makeCB("Networking"));
  queueOnTimerTaskSource(makeCB("Timer"));
  // the next three are a tie in current Chrome
  queueOnMessageTaskSource(makeCB("Message"));
  window.scheduler?.postTask(makeCB("queueTask user-visible"), {
    priority: "user-visible"
  });
  queueOnDOMManipulationTaskSource(makeCB("DOM Manipulation"));

  window.scheduler?.postTask(makeCB("queueTask user-blocking with delay"), {
    priority: "user-blocking",
    delay: 1
  });
  window.scheduler?.postTask(makeCB("queueTask user-blocking"), {
    priority: "user-blocking"
  });
  document.addEventListener("click", makeCB("UI task source"), {
    once: true
  });
  const start = performance.now();
  while (start + 3000 > performance.now());
}, 1000);

这篇关于任务队列真的有优先级排序系统吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

file对象转blob对象进行预览的实例代码: //获取到 file文件var reader = new FileReader();reader.readAsArrayBuffer(file);reader.onload = function (event) { let blob = new Blob([event.target.result], { type: file.type }); //{ type: file.type } 预览blob发现乱码可能是type不对 要获取file文件的
本文给大家介绍Javascript js中实现和PHP一样的时间戳格式化函数的方法,具有一定的参考借鉴价值,需要的朋友可以参考下,我们知道在php中有一个date()函数,可以方便的把时间戳格式化为时间字符串。可是在js中,我们要想实现这种效果,要写好
需求是模板字符串中不允许出现script 标签、不允许有javascript: 和 .js 文件引用,主要方法如下: clearScriptTag (str) { const reg = /script[^]*([\S\s]*?)\/script/gim; // 清除标签内 相关 xss 安全代码 const reg1 = /javascript:/gim; const reg2 = / *.js/gim; if (reg.test(str)) { str
javascript中Replace全部替换字符用法实例代码,替换1次和多次,主要是正则表达式 var r= "1\n2\n3\n";//将字母\n替换成分号alert(r.replace("\n",";"));//结果:1;2\n3\n 只替换了第一个var r= "1\n2\n3\n";//将字母\n替换成分号alert(r.replace(/\n/g, ";"));//结果:1;2;3; replac
js输出当前日期和时间的实例代码,具体实例代码如下,有兴趣的朋友可以尝试运行下。 !doctype htmlhtml lang="en" head meta charset="UTF-8" title获取当前时间/title /head body script type="text/javascript" /** *获取当前时间 *format=1精确到天 *format=2精确到秒 */ function
p5.js WebGL 3d graphics covered by 2d background when rotated(P5.js旋转时被2D背景覆盖的WebGL 3D图形)