如果CSS具有渲染阻止功能,为什么我们会看到FOUC?

时间:2018-11-09 05:20:20

标签: html css dom browser cssom

为了构造渲染树,浏览器需要DOM和CSSOM。一旦下载了CSS,就只能构造CSSOM。本质上,一旦下载了CSS,页面就应该正确显示。但是,为什么我们在页面上看到Flash of Unstyled Content(FOUC)?浏览器在什么时间窗口显示未样式化的内容?

请帮助我理解这一点。

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

3 个答案:

答案 0 :(得分:1)

这应该有所帮助。

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

因此,等待CSS时浏览器显示FOUC。加载CSS后,将DOM和CSSOM合并为一棵树,称为“渲染树”,这是样式化的内容。

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

的原因

我认为,这是有关此主题的最全面的讨论,来自Mozilla的首席工程师David Baron:https://vimeo.com/103108124

答案 1 :(得分:1)

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

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

“如果我们尝试在CSS上呈现不阻塞呈现的典型页面会发生什么?”。 (然后,以《纽约时报FOUC》为例,该行为不阻止呈现。)

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

例如,根据this ancient article,如果某些JS试图访问具有布局/样式信息的属性,我们可能会在Web工具包中遇到FOUC。

Web Kit的行为与之相反,将继续解析页面 即使在遇到样式表指令之后,该样式 工作表和脚本加载可以并行化。这样一切都可以 准备更早显示。

此行为的问题是脚本尝试执行以下操作时该怎么办 访问涉及具有准确布局/样式的属性 要回答的信息。传送Safari当前的行为时, 发生的情况如下:它将继续进行,甚至将其布局 尽管还没有样式表。它还将显示它。 这意味着每当脚本尝试访问属性时,您都会看到FOUC 例如,在加载样式表之前,应使用“ scrollHeight”或“ offsetWidth”。

因此,当我们说“ FOUC发生”时, 在什么情况下以及在什么浏览器中发生,因为它没有 “正义”无处不在。

答案 2 :(得分:0)

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>
  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