为什么在 chrome 开发工具中重新计算样式之前评估了 js?
js evaluated before recalculating style in chrome dev tools why?
article 表示 CSS 是渲染阻塞,因此 js 将在构建 CSSOM 后进行评估(a.k.a。在开发工具中重新计算样式)
但是,在 Chrome 开发工具中。好像js在CSSOM之前被求值了,为什么?我误解了吗?
如果你想看我的例子=> here
调用树
事件日志
<html>
<head>
<style>
h1 {color:red;}
p>p {color:blue;}
p>p>p {color:blue;}
p>p>p>p {color:blue;}
p>p>p>p>p {color:blue;}
p>p>p>p>p>p {color:blue;}
p>p>p>p>p>p>p {color:blue;}
p>p>P>p>p>p>p>p {color:blue;}
</style>
</head>
<body>
<h1>A heading</h1>
<p>A paragraph.</p>
<p>Hello <span>web performance</span> students!</p>
<div><img src="awesome-photo.jpg"></div>
<script>
var span = document.getElementsByTagName('span')[0];
span.textContent = 'interactive'; // change DOM text content
span.style.display = 'inline'; // change CSSOM property
// create a new element, style it, and append it to the DOM
var loadTime = document.createElement('div');
loadTime.textContent = 'You loaded this page on: ' + new Date();
loadTime.style.color = 'blue';
document.body.appendChild(loadTime);
var cnt=0
while(cnt++ <=9999999){}
</script>
</body>
</html>
本文的作者关注的是 domContentLoaded
事件或页面准备好呈现给用户的那一刻,不再有白屏。蓝色垂直线何时出现在时间轴上很重要。这是了解页面对用户可用的速度的重要事件。在内容出现之前,用户必须盯着白屏多长时间?
由于单页应用的出现,几乎所有的内容都只有在主脚本加载后才能使用。这就是为什么如此多的顶级 Web 应用程序首先使用服务器端呈现的页面,然后 javascript 控制单页应用程序。他们甚至使用代码拆分来加载当前页面所需的内容。
本文深入探讨了包含外部 CSS 和 js 文件的效果。这些文件的加载和解析如何推动 domContentLoaded
事件,这意味着将白屏更改为内容会有更多延迟,即使内容 (HTML) 已经被解析并准备好呈现。
性能事件日志确实显示了正在发生的事情的详细信息,但如果您进一步向下滚动,您可以找到 Event:readystatechange
和 Event:pageshow
,代表内容呈现给的时间戳用户。这些事件发生在脚本和样式计算之后。 <script>
行阻塞 domContentLoaded
事件,直到他完成他的事情。
这就是为什么建议对脚本标签使用 async
属性,这样它就不会阻塞白屏。想象一下,如果我们添加到网页的所有外部脚本也阻止了页面呈现。延迟对用户来说会变得非常明显,以至于 he/she 可能会决定离开。
希望这能解释您的查询。
回答
我认为在 Chrome 和 IE11
中有内联或解析器阻塞脚本时会有一些优化
下面我测试的时候HTML
<html>
<head>
<style>
h1 {color:red;}
p>p {color:blue;}
p>p>p {color:blue;}
p>p>p>p {color:blue;}
p>p>p>p>p {color:blue;}
p>p>p>p>p>p {color:blue;}
p>p>p>p>p>p>p {color:blue;}
p>p>P>p>p>p>p>p {color:blue;}
</style>
</head>
<body>
<h1>A heading</h1>
<p>A paragraph.</p>
<p>Hello <span>web performance</span> students!</p>
<div><img src="awesome-photo.jpg"></div>
<script>
var span = document.getElementsByTagName('span')[0];
span.textContent = 'interactive'; // change DOM text content
span.style.display = 'inline'; // change CSSOM property
// create a new element, style it, and append it to the DOM
var loadTime = document.createElement('div');
loadTime.textContent = 'You loaded this page on: ' + new Date();
loadTime.style.color = 'blue';
document.body.appendChild(loadTime);
var cnt=0
while(cnt++ <=9999999){}
</script>
</body>
</html>
IE11 显示预期顺序,但并行执行。 HTML 解析 => CSSOM => 评估脚本
另一方面,Chrome 显示意外顺序 HTML 解析 => 评估脚本 => CSSOM
所以我将内联脚本更改为外部脚本,现在 Chrome 按预期顺序工作 HTML 解析 => CSSOM => 评估脚本
<html>
<head>
<style>
h1 {color:red;}
p>p {color:blue;}
p>p>p {color:blue;}
p>p>p>p {color:blue;}
p>p>p>p>p {color:blue;}
p>p>p>p>p>p {color:blue;}
p>p>p>p>p>p>p {color:blue;}
p>p>P>p>p>p>p>p {color:blue;}
</style>
</head>
<body>
<h1>A heading</h1>
<p>A paragraph.</p>
<p>Hello <span>web performance</span> students!</p>
<div><img src="awesome-photo.jpg"></div>
</body>
<script src="test.js"></script>
</html>
优化的工作原理
当你有内联脚本时,即使它不操纵你的 DOM 或 CSSOM,它也会比重新计算样式执行得更快,然后重新计算样式将在 HTML 解析完成后再执行一次Chrome 和 IE11.
<html>
<head>
<style>
h1 {color:red;}
p>p {color:blue;}
p>p>p {color:blue;}
p>p>p>p {color:blue;}
p>p>p>p>p {color:blue;}
p>p>p>p>p>p {color:blue;}
p>p>p>p>p>p>p {color:blue;}
p>p>P>p>p>p>p>p {color:blue;}
</style>
</head>
<body>
<h1>A heading</h1>
<p>A paragraph.</p>
<p>Hello <span>web performance</span> students!</p>
<div><img src="awesome-photo.jpg"></div>
<script>
var cnt=0
while(cnt++ <=9999999){}
</script>
</body>
<!-- <script src="test.js"></script> -->
</html>
article 表示 CSS 是渲染阻塞,因此 js 将在构建 CSSOM 后进行评估(a.k.a。在开发工具中重新计算样式)
但是,在 Chrome 开发工具中。好像js在CSSOM之前被求值了,为什么?我误解了吗?
如果你想看我的例子=> here
调用树
事件日志
<html>
<head>
<style>
h1 {color:red;}
p>p {color:blue;}
p>p>p {color:blue;}
p>p>p>p {color:blue;}
p>p>p>p>p {color:blue;}
p>p>p>p>p>p {color:blue;}
p>p>p>p>p>p>p {color:blue;}
p>p>P>p>p>p>p>p {color:blue;}
</style>
</head>
<body>
<h1>A heading</h1>
<p>A paragraph.</p>
<p>Hello <span>web performance</span> students!</p>
<div><img src="awesome-photo.jpg"></div>
<script>
var span = document.getElementsByTagName('span')[0];
span.textContent = 'interactive'; // change DOM text content
span.style.display = 'inline'; // change CSSOM property
// create a new element, style it, and append it to the DOM
var loadTime = document.createElement('div');
loadTime.textContent = 'You loaded this page on: ' + new Date();
loadTime.style.color = 'blue';
document.body.appendChild(loadTime);
var cnt=0
while(cnt++ <=9999999){}
</script>
</body>
</html>
本文的作者关注的是 domContentLoaded
事件或页面准备好呈现给用户的那一刻,不再有白屏。蓝色垂直线何时出现在时间轴上很重要。这是了解页面对用户可用的速度的重要事件。在内容出现之前,用户必须盯着白屏多长时间?
由于单页应用的出现,几乎所有的内容都只有在主脚本加载后才能使用。这就是为什么如此多的顶级 Web 应用程序首先使用服务器端呈现的页面,然后 javascript 控制单页应用程序。他们甚至使用代码拆分来加载当前页面所需的内容。
本文深入探讨了包含外部 CSS 和 js 文件的效果。这些文件的加载和解析如何推动 domContentLoaded
事件,这意味着将白屏更改为内容会有更多延迟,即使内容 (HTML) 已经被解析并准备好呈现。
性能事件日志确实显示了正在发生的事情的详细信息,但如果您进一步向下滚动,您可以找到 Event:readystatechange
和 Event:pageshow
,代表内容呈现给的时间戳用户。这些事件发生在脚本和样式计算之后。 <script>
行阻塞 domContentLoaded
事件,直到他完成他的事情。
这就是为什么建议对脚本标签使用 async
属性,这样它就不会阻塞白屏。想象一下,如果我们添加到网页的所有外部脚本也阻止了页面呈现。延迟对用户来说会变得非常明显,以至于 he/she 可能会决定离开。
希望这能解释您的查询。
回答
我认为在 Chrome 和 IE11
中有内联或解析器阻塞脚本时会有一些优化下面我测试的时候HTML
<html>
<head>
<style>
h1 {color:red;}
p>p {color:blue;}
p>p>p {color:blue;}
p>p>p>p {color:blue;}
p>p>p>p>p {color:blue;}
p>p>p>p>p>p {color:blue;}
p>p>p>p>p>p>p {color:blue;}
p>p>P>p>p>p>p>p {color:blue;}
</style>
</head>
<body>
<h1>A heading</h1>
<p>A paragraph.</p>
<p>Hello <span>web performance</span> students!</p>
<div><img src="awesome-photo.jpg"></div>
<script>
var span = document.getElementsByTagName('span')[0];
span.textContent = 'interactive'; // change DOM text content
span.style.display = 'inline'; // change CSSOM property
// create a new element, style it, and append it to the DOM
var loadTime = document.createElement('div');
loadTime.textContent = 'You loaded this page on: ' + new Date();
loadTime.style.color = 'blue';
document.body.appendChild(loadTime);
var cnt=0
while(cnt++ <=9999999){}
</script>
</body>
</html>
IE11 显示预期顺序,但并行执行。 HTML 解析 => CSSOM => 评估脚本
另一方面,Chrome 显示意外顺序 HTML 解析 => 评估脚本 => CSSOM
所以我将内联脚本更改为外部脚本,现在 Chrome 按预期顺序工作 HTML 解析 => CSSOM => 评估脚本
<html>
<head>
<style>
h1 {color:red;}
p>p {color:blue;}
p>p>p {color:blue;}
p>p>p>p {color:blue;}
p>p>p>p>p {color:blue;}
p>p>p>p>p>p {color:blue;}
p>p>p>p>p>p>p {color:blue;}
p>p>P>p>p>p>p>p {color:blue;}
</style>
</head>
<body>
<h1>A heading</h1>
<p>A paragraph.</p>
<p>Hello <span>web performance</span> students!</p>
<div><img src="awesome-photo.jpg"></div>
</body>
<script src="test.js"></script>
</html>
优化的工作原理
当你有内联脚本时,即使它不操纵你的 DOM 或 CSSOM,它也会比重新计算样式执行得更快,然后重新计算样式将在 HTML 解析完成后再执行一次Chrome 和 IE11.
<html>
<head>
<style>
h1 {color:red;}
p>p {color:blue;}
p>p>p {color:blue;}
p>p>p>p {color:blue;}
p>p>p>p>p {color:blue;}
p>p>p>p>p>p {color:blue;}
p>p>p>p>p>p>p {color:blue;}
p>p>P>p>p>p>p>p {color:blue;}
</style>
</head>
<body>
<h1>A heading</h1>
<p>A paragraph.</p>
<p>Hello <span>web performance</span> students!</p>
<div><img src="awesome-photo.jpg"></div>
<script>
var cnt=0
while(cnt++ <=9999999){}
</script>
</body>
<!-- <script src="test.js"></script> -->
</html>