7

为了构建渲染树,浏览器需要 DOM 和 CSSOM。只有在下载 CSS 后才能构建 CSSOM。本质上,一旦 CSS 被下载,页面应该可以正常渲染。但是,为什么我们会在页面上看到 Flash Of Unstyled Content(FOUC)?浏览器在什么时间窗口显示无样式的内容?

请帮助我理解这一点。

参考: https ://developers.google.com/web/fundamentals/performance/critical-rendering-path/render-blocking-css

4

3 回答 3

5

我仍然不同意接受的答案,因为根据关键渲染路径,在正常情况下,在构建渲染树(DOM + CSSOM)之前,无法在屏幕上绘制任何内容。

我发现这篇 Google 文章乍一看有点令人困惑,但如果我们仔细看一下下面的陈述,它就会变得不那么矛盾:

“如果我们尝试在不阻塞CSS 渲染的情况下渲染典型页面会发生什么?”。(然后纽约时报 FOUC 作为不阻塞渲染的行为示例。)

从历史上看,FOUC 在不同的浏览器版本和不同的情况下出于不同的原因而发生。

例如,根据这篇古老的文章,如果某些 JS 试图访问具有布局/样式信息的属性,我们可能会在 web kit 中遇到 FOUC。

Web Kit 具有相反的行为,即使在遇到样式表指令后仍会继续解析页面,以便可以并行化样式表和脚本加载。这样,一切都可以更早地准备好展示。

这种行为的问题是,当脚本尝试访问一个需要准确的布局/样式信息来回答的属性时该怎么办。发生这种情况时,Safari 的当前行为如下:即使它还没有样式表,它也会继续布局它所拥有的内容。它也会显示它。这意味着只要脚本在加载样式表之前尝试访问诸如 scrollHeight 或 offsetWidth 之类的属性,您就会看到 FOUC。

因此,当我们说“FOUC 发生”时,应该说明它在什么情况下发生以及在什么浏览器中发生,因为它不会“只是”在任何地方发生。

于 2020-04-09T13:52:42.660 回答
1

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>
  1. 前 100 个标签被转换为 dom,并借助现有的 cssom(由用户代理样式表解释)形成渲染树,它将被绘制并对用户可见。
  2. 之后解析将被阻止,直到下载 css1 并使用 useragent+css1 样式创建新的 cssom。
  3. 并且使用新的渲染树(通过旧 dom + 新 cssom 形成)html 块 1 将被更新(FOUC)
  4. 然后 html 块 2 被类似地处理,因为它之后被下载。
  5. 现在对块 2 和块 3 重复与步骤 3 相同的操作
  6. 直到文件结束也是如此

学分 - https://medium.com/jspoint/how-the-browser-renders-a-web-page-dom-cssom-and-rendering-df10531c9969

于 2021-03-04T15:00:21.810 回答
0

这应该会有所帮助。

  1. DOM 被构建
  2. 如果我们还在等待 CSSOM 被构建,那么我们会看到 FOUC
  3. CSSOM 已构建
  4. DOM 和 CSSOM 合并到渲染树中,渲染树使用 CSS(样式化内容)渲染 DOM

所以浏览器在等待 CSS 时会显示 FOUC。加载 CSS 后,DOM 和 CSSOM 将合并为一棵树,称为渲染树,这是样式化内容。

HTML 以无样式呈现的事实清楚地证明了 HTML 可以在浏览器中与呈现树分开呈现,从而导致 FOUC。

根据 Google 文章,纽约时报网站显示 FOUC,直到构建 CSSOM,然后渲染渲染树。这表明渲染渲染树不同于渲染 DOM 树。DOM 树被渲染,但未加载的 CSS 阻止渲染树被渲染(注意区别)。这就是为什么 FOUC 在 CSS 未阻塞和渲染树显示之前显示的原因。

在我看来,这是 Mozilla 首席工程师 David Baron 对这个主题最全面的讨论:https ://vimeo.com/103108124

于 2018-11-09T13:03:14.543 回答