为了构建渲染树,浏览器需要 DOM 和 CSSOM。只有在下载 CSS 后才能构建 CSSOM。本质上,一旦 CSS 被下载,页面应该可以正常渲染。但是,为什么我们会在页面上看到 Flash Of Unstyled Content(FOUC)?浏览器在什么时间窗口显示无样式的内容?
请帮助我理解这一点。
我仍然不同意接受的答案,因为根据关键渲染路径,在正常情况下,在构建渲染树(DOM + CSSOM)之前,无法在屏幕上绘制任何内容。
我发现这篇 Google 文章乍一看有点令人困惑,但如果我们仔细看一下下面的陈述,它就会变得不那么矛盾:
“如果我们尝试在不阻塞CSS 渲染的情况下渲染典型页面会发生什么?”。(然后纽约时报 FOUC 作为不阻塞渲染的行为示例。)
从历史上看,FOUC 在不同的浏览器版本和不同的情况下出于不同的原因而发生。
例如,根据这篇古老的文章,如果某些 JS 试图访问具有布局/样式信息的属性,我们可能会在 web kit 中遇到 FOUC。
Web Kit 具有相反的行为,即使在遇到样式表指令后仍会继续解析页面,以便可以并行化样式表和脚本加载。这样,一切都可以更早地准备好展示。
这种行为的问题是,当脚本尝试访问一个需要准确的布局/样式信息来回答的属性时该怎么办。发生这种情况时,Safari 的当前行为如下:即使它还没有样式表,它也会继续布局它所拥有的内容。它也会显示它。这意味着只要脚本在加载样式表之前尝试访问诸如 scrollHeight 或 offsetWidth 之类的属性,您就会看到 FOUC。
因此,当我们说“FOUC 发生”时,应该说明它在什么情况下发生以及在什么浏览器中发生,因为它不会“只是”在任何地方发生。
FOUC 的基本原因是 -> 在元素已经在屏幕上绘制之后应用新的/不同的样式。
现在问题来了-> FOUC 是否会在页面加载时发生,并且页面标记本身包含<link>
外部 css 的标签,从高层次上看,这似乎不应该发生,因为 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>
学分 - https://medium.com/jspoint/how-the-browser-renders-a-web-page-dom-cssom-and-rendering-df10531c9969
这应该会有所帮助。
所以浏览器在等待 CSS 时会显示 FOUC。加载 CSS 后,DOM 和 CSSOM 将合并为一棵树,称为渲染树,这是样式化内容。
HTML 以无样式呈现的事实清楚地证明了 HTML 可以在浏览器中与呈现树分开呈现,从而导致 FOUC。
根据 Google 文章,纽约时报网站显示 FOUC,直到构建 CSSOM,然后渲染渲染树。这表明渲染渲染树不同于渲染 DOM 树。DOM 树被渲染,但未加载的 CSS 阻止渲染树被渲染(注意区别)。这就是为什么 FOUC 在 CSS 未阻塞和渲染树显示之前显示的原因。
在我看来,这是 Mozilla 首席工程师 David Baron 对这个主题最全面的讨论:https ://vimeo.com/103108124