浏览器具有不同位置的脚本和链接标记的不同渲染行为

Bhu*_*van 6 javascript html5 dom rendering css3

我试图了解HTML在浏览器中的屏幕上呈现的时间.

我读了这个SO答案,并尝试了一些用例,我观察到一些不适合链接中共享的模型的东西,
我似乎也找不到一致的观察思维模型.

什么是适合所讨论案例的浏览器呈现顺序?


案例A: 图像A. 在此输入图像描述

  1. 当HTML解析器到达M1时,显示M1.
  2. 然后解析器到达脚本标记它等待js文件下载和解析.
  3. 然后解析器到达M3,显示M3.

案例A与大多数答案中描述的顺序不一致.Huray!让我们继续.

案例B: 图像-B 在此输入图像描述

  1. HTML解析器到达M1,M1不显示在CASE A中
  2. HTML解析器到达链接标记,它等待css下载和解析.
  3. 显示M1和M2,因此在渲染M1之前等待样式表下载.
  4. 然后解析器到达脚本标记它等待js文件下载和解析.
  5. 然后解析器到达M3,显示M3.

所以Case-B显示它没有呈现M1,它在渲染之前等待CSS下载. 因此渲染器可能需要在渲染之前知道CSS.

案例:C 图像C.

在此输入图像描述

所以从案例B开始,我们假设渲染器可能需要知道CSS.
让我们看看案例C:

  1. HTML解析器到达M1,显示M1.它不应该显示,因为我们在B的情况下看到它应该等待css加载.
  2. 现在解析器到达脚本,它等待js下载和解析器.
  3. 显示M2,M3

编辑: 提出的思维模型解释了上述行为..(但需要审查/改进)

  1. Script 不是渲染器阻止标记
  2. link 是一个渲染器阻止标记
  3. 考虑到渲染器和HTML解析器是两个线程.
  4. HTML解析器可以将内容发送到渲染器进行渲染.
  5. HTML解析器可以发送块信号renderer..to块渲染器来渲染的处理不当被渲染ATLEAST一次任何HTML.
  6. HTML解析器可以向渲染器发送解除阻塞信号.以解除渲染任何未呈现一次的HTML的渲染器.

通过上面的模型我们可以解释CASE B和CASE C:
CASE B说明:

  1. HTML解析器到达M1,M1被发送到渲染器.
  2. HTML解析器到达链接标记,解析器向渲染器发送阻塞信号.
  3. 渲染器在渲染M1之前,它有一个阻塞信号,因此M1不显示.
  4. HTML解析器完成链接标记解析(下载)并向呈现器发送解除阻塞信号,一旦接收到解锁信号,它就呈现M1.
  5. HTML解析器到达M2,M2发送到渲染器.
  6. HTML解析器到达脚本标记,因为脚本标记不是渲染器阻塞标记,渲染器可以自由渲染html.
  7. HTML解析器完成脚本标记的解析(下载).
  8. HTML解析器到达M3,M3发送到渲染器.

同样我们可以干运行CASE C,它完全适合上述模型.

我的模型是正确的还是有问题的?

She*_*epy 3

你几乎是对的。除了它更简单之外 - 渲染器是被动的并且不接收“阻塞信号”。在有人要求它之前,它不会渲染(更新显示以反映 dom 树)。

  1. 您的 HTML 无效 - 您不能放入<link rel=...>正文中。(实时 HTML 4.2.4)

  2. 正如您所想的,样式表是一种渲染阻塞资源 - 它将阻止渲染内容,而脚本则会暂停并渲染已解析的内容。

我将这样解释:

情况B:M1 - stylesheet - M2 - script - M3

  1. 浏览器获取 HTML。M1进入DOM树。M1 尚未显示,渲染器尚未被要求工作。
  2. 样式表加载。(实际上它阻止了 M1 渲染)
  3. 样式表完成。M1仍然没有显示。(还有两步)
  4. M2进入DOM树。M1和M2尚未显示。
  5. 脚本触发渲染,从而显示 M1 和 M2,然后加载。
  6. 脚本完成。没有任何改变(就本案而言)。
  7. M3进入DOM树,尚未显示。
  8. 文档完成,页面渲染,从而显示M3。

这些行为都是故意的。曾几何时,js 速度很慢,脚本需要很长时间才能运行,而样式表对于默认隐藏元素来说过去(现在仍然)很重要。时间可能已经改变,但这些行为不太可能改变。

情况C:M1 - script - M2 - link - M3

  1. 浏览器获取 HTML。M1进入DOM树。M1 尚未显示。
  2. 脚本触发渲染,从而显示 M1,然后加载。
  3. 脚本完成。没变化。
  4. M2进入DOM树。尚未显示。
  5. 样式表加载,实际上阻止了 M2。
  6. 样式表完成。M2仍然没有显示。
  7. M3进入DOM树,尚未显示。
  8. 文档已完成,页面已呈现,M2 和 M3 已显示。

实际的显示过程,就线程而言,是非常 复杂的,并且在某种意义上,不同浏览器的差异很大。例如,DOM 不是线程 安全 的。想想这意味着什么。

为了简单起见,您可以将浏览器处理想象为数据和事件在各个模块之间流动。以下是一些 Firefox 渲染子系统:

显示与 HTML 渲染相关的 10 个相互链接的模块的图表