html - 浏览器如何应用 CSS,重绘是否受其影响?

标签 html css browser repaint rendering-engine

假设我们有一个带有单个样式表的 HTML 页面 <link> .浏览器如何采用此样式表中的规则并将其应用于 HTML?我不是在问如何让它更快,我想知道渲染本身是如何处理的。

它是否在解析样式表并逐步呈现结果时逐一应用每条规则?或者,是否完全下载了 CSS 文件的内容,然后对其进行了全面评估,然后然后一次性将其应用于 HTML?还是别的?

我在早些时候在 a question about CSS rule order affecting rendering speed 上发布了一个答案后问这个问题,假设样式呈现为 加载的样式表,因此第一个规则将在最后一个规则之前应用,而不是一次全部应用。我不确定我是从哪里得到这个想法的,这只是我一直以来的想法。

我在我的服务器上尝试了一个看起来像这样的演示:

<!DOCTYPE html>
<html>
<head>
   <title>Test</title>
   <link rel="stylesheet" href="test.css" />
</head>
<body></body>
</html>

test.css内容:

html { background:green }
/* thousands of lines of irrelevant CSS to make the download slow */
html { background:red }

在 Firefox 5 中测试,我预计一开始会看到绿色,然后变成红色。它没有发生。我尝试使用两个具有冲突规则的单独样式表并得到相同的结果。经过多次组合,我让它工作的唯一方法是内联 <style> block 在 <head> , 冲突规则来自 <link><body> (主体本身完全是空的,除了链接标签)。即使使用内联 style <html> 上的属性标记,然后加载此样式表并没有产生我预期的闪烁。

CSS 是否以任何方式影响了重绘,或者是在下载了整个样式表并根据最终输出的规则计算后立即应用了最终输出? CSS 文件是与 HTML 本身并行下载还是阻止它(就像脚本标签一样)?这实际上是如何工作的?

我不是在寻找优化技巧,我是在寻找有关该主题的权威引用资料,以便我将来可以引用它们。如果不翻出大量不相关的 Material ,就很难搜索到这些信息。摘要:

  • 是否在应用任何之前下载了所有 CSS 内容? (请引用)
  • 这如何受到 @import 等因素的影响? , 多个 <link> s,内联样式属性,<style>头部 block 和不同的渲染引擎?
  • CSS 内容的下载是否会阻止 HTML 文档本身的下载?

最佳答案

How does the browser take the rules in this stylesheet and apply it to the HTML?

通常这是以流方式完成的。浏览器以流的形式读取 HTML 标签,并将它能应用的规则应用到它目前看到的元素上。 (显然这是一种简化。)

一个有趣的相关问答:Use CSS selectors to collect HTML elements from a streaming parser (e.g. SAX stream) (搜索我想到的文章时的转移)。


啊,这里是:Why we don't have a parent selector .

We often think of our pages as these full and complete documents full of elements and content. However, browsers are designed to handle documents like a stream. They begin to receive the document from the server and can render the document before it has completely downloaded. Each node is evaluated and rendered to the viewport as it is received.

Take a look at the body of an example document:

<body>
   <div id="content">
      <div class="module intro">
         <p>Lorem Ipsum</p>
      </div>
      <div class="module">
         <p>Lorem Ipsum</p>
         <p>Lorem Ipsum</p>
         <p>Lorem Ipsum <span>Test</span></p>
      </div>
   </div>
</body>

The browser starts at the top and sees a body element. At this point, it thinks it's empty. It hasn't evaluated anything else. The browser will determine what the computed styles are and apply them to the element. What is the font, the color, the line height? After it figures this out, it paints it to the screen.

Next, it sees a div element with an ID of content. Again, at this point, it thinks it's empty. It hasn't evaluated anything else. The browser figures out the styles and then the div gets painted. The browser will determine if it needs to repaint the body—did the element get wider or taller? (I suspect there are other considerations but width and height changes are the most common effects child elements have on their parents.)

This process continues on until it reaches the end of the document.

CSS gets evaluated from right to left.

To determine whether a CSS rule applies to a particular element, it starts from the right of the rule and works it's way left.

If you have a rule like body div#content p { color: #003366; } then for every element—as it gets rendered to the page—it'll first ask if it's a paragraph element. If it is, it'll work its way up the DOM and ask if it's a div with an ID of content. If it finds what it's looking for, it'll continue its way up the DOM until it reaches the body.

By working right to left, the browser can determine whether a rule applies to this particular element that it is trying to paint to the viewport much faster. To determine which rule is more or less performant, you need to figure out how many nodes need to be evaluated to determine whether a style can be applied to an element.


So why was the stylesheet content not applied progressively (green first, then red)?

认为答案是外部样式表在下载时被解析,但在整个样式表被解析之前应用。当然,在解析样式表时,浏览器会优化掉不必要和冗余的 CSS 规则。

我现在没有任何证据支持这一点,但这种解释对我来说听起来很合理,并且与您所看到的一致,包括外部样式和内联样式。

关于html - 浏览器如何应用 CSS,重绘是否受其影响?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6951108/

相关文章:

jQuery - 在不刷新的情况下调整窗口大小时根据屏幕大小执行脚本?

C# 捕获 webbrowser 发出的 http 请求

html - Facebook 评论 - wordpress

javascript - 如何居中 Dijit Select 小部件?

javascript - 如何使用JS在CSS文件中编写CSS样式?

html - Windows 上的 Safari 不会尊重父元素的最大高度

javascript - 如何删除按钮中下一个和上一个按钮附近的不同颜色空间

html - 响应式地平铺不同大小的盒子

JavaScript:如何检查文件是否被缓存?

javascript - 如何从 IMG 元素获取图像内容(不是 url)?