为了构建渲染树,浏览器需要DOM和CSSOM。只有在下载了CSS之后,才能构建CSSOM。从本质上讲,一旦下载了CSS,页面就应该可以正常呈现。但是,为什么我们会在页面上看到Flash Of Unstyled Content(FOUC)?浏览器在什么时间窗口中显示未格式化的内容?
请帮我理解这一点。
参考编号:https://developers.google.com/web/fundamentals/performance/critical-rendering-path/render-blocking-css
我仍然不同意接受的答案,因为根据关键的渲染路径,在构建渲染树(DOM+CSOM)之前,在正常情况下无法在屏幕上绘制任何内容。
我发现谷歌的这篇文章乍一看有点令人困惑,但如果我们仔细观察以下声明,它就会变得不那么矛盾:
"如果我们尝试在不阻止CSS上渲染的情况下渲染一个典型的页面,会发生什么?"。(《纽约时报》FOUC作为行为而不阻塞渲染的示例如下。)
从历史上看,FOUC在不同的浏览器版本和不同的环境中由于不同的原因而发生。
例如,根据这篇古老的文章,如果一些JS试图访问具有布局/样式信息的属性,我们可能会在web工具包中遇到FOUC。
WebKit具有相反的行为,将继续解析页面即使在遇到样式表指令之后工作表和脚本加载可以并行化。这样一切都可以早就准备好展示了。
此行为的问题在于当脚本尝试访问涉及精确布局/样式的特性要回答的信息。发送Safari的当前行为时事情是这样的:它会继续进行,并列出它所拥有的尽管它还没有样式表。它也会显示它。这意味着您可以在脚本尝试访问属性时看到FOUC比如scrollHeight或offsetWidth。
因此,当我们说"FOUC发生"时,应该对在什么情况下,在什么浏览器中发生,因为它没有"只是"无处不在。
FOUC的基本原因是->在元素已经绘制在屏幕上之后,新的/不同的样式正在被应用。
现在问题来了->当页面加载时,如果页面标记本身包含外部css的<link>
标记,则会发生FOUC,在高级情况下,这似乎不应该发生,因为css是渲染块,不应该有任何元素可以在没有其计算样式的情况下进行渲染,但在某些条件下,它(FOUC)会在页面加载时发生。
主要原因是dom树的构建是增量的,即在没有完整的html标记的情况下,浏览器可以呈现下载到给定时间点的部分html。
为了理解这一点,让我们以下面的html-为例
<!DOCTYPE html>
<html lang="en">
<body>
<100 html tags block 1 />
<link href="css1" />
<100 html tags block 2 />
<link href="css2" />
<100 html tags block 3 />
<link href="css3" />
</body>
</html>
- 前100个标签被转换为dom,并在现有cssom(根据用户代理样式表解释)的帮助下形成渲染树,该树将被绘制并对用户可见
- 在那之后,解析将被阻止,直到css1被下载,并且使用useragent+cs1样式创建了新的cssom
- 使用新的渲染树(通过旧的dom+新的cssom形成),html块1将被更新(FOUC)
- 然后,html块2在下载之后被类似地处理
- 现在,对块2和块3重复与步骤3相同的事情
- 同样的情况一直持续到文件末尾
学分-https://medium.com/jspoint/how-the-browser-renders-a-web-page-dom-cssom-and-rendering-df10531c9969
这应该会有所帮助。
- 构造DOM
- 如果我们仍在等待CSSOM的建造,那么我们就会看到FOUC
- CSSOM已构建
- DOM和CSSOM合并到渲染树中,该树使用CSS(样式化内容)渲染DOM
因此浏览器在等待CSS时显示FOUC。加载CSS后,DOM和CSSOM将合并为一个树,称为"渲染树",这就是样式化的内容。
HTML呈现为无样式这一事实清楚地证明,HTML可以在浏览器中与呈现树分开呈现,从而导致FOUC
根据谷歌的文章,《纽约时报》网站显示FOUC,直到构建CSSOM,然后渲染树。这表明渲染树与渲染DOM树不同。DOM树被渲染,但卸载的CSS阻止了渲染树的渲染(注意区别)。这就是为什么FOUC在取消阻止CSS和显示渲染树之前显示的原因。
在我看来,这是Mozilla首席工程师David Baron关于这个主题的最全面的演讲:https://vimeo.com/103108124
您需要仔细阅读文章:
上面的例子显示了有和没有CSS的《纽约时报》网站,说明了为什么在CSS可用之前渲染会被阻止——没有CSS,页面相对来说是不可用的
屏幕截图并不是浏览器中实际发生的事情,它是用来演示如果CSS没有呈现阻塞会发生什么。您最初的理解是正确的,FOUC在正常情况下是不可能的。但是,如果您稍后在页面中或通过Javascript应用其他样式,则需要确保在任何受这些样式影响的HTML之前注入这些样式,以防止FOUC。