浏览器是如何应用CSS,并重新绘制受它的影响? [英] How is CSS applied by the browser, and are repaints affected by it?

查看:154
本文介绍了浏览器是如何应用CSS,并重新绘制受它的影响?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我们说我们有一个HTML页面,一个样式表<链路GT; 。如何在浏览器采取规则这个样式表并将其应用到HTML?我不要求有关如何使其更快,我想知道如何渲染自己的处理方式。

这是否适用于每个规则一个接一个,因为它解析样式表,并逐步呈现的结果?或者说,是在CSS文件的内容完全下载,然后完全评估和然后的适用于所有的HTML一次?还是其他什么东西?

请问这早些时候<一张贴一个答案后, href=\"http://stackoverflow.com/questions/6944190/does-the-order-of-rules-in-a-css-stylesheet-affect-rendering-speed/6945000\">a关于CSS规则的顺序影响渲染速​​度,与假设的风格呈现人的作为问题的样式表加载,所以第一个规则会在最后的前应用,而不是一次全部。我不知道我在哪里捡到的想法,这只是我一直以为。

我想我的服务器上演示的是这样的:

 &LT;!DOCTYPE HTML&GT;
&LT; HTML和GT;
&LT; HEAD&GT;
   &LT;标题&GT;测试与LT; /标题&GT;
   &LT;链接rel =stylesheet属性HREF =test.css/&GT;
&LT; /头&GT;
&LT;身体GT;&LT; /身体GT;
&LT; / HTML&GT;

test.css 内容:

  HTML {背景:绿色}
/ *数千不相干的CSS的行使下载慢* /
HTML {背景:红}

测试在Firefox 5,我期望看到绿色在第一,然后变成红色。它没有发生。我试着用两个独立的样式表与冲突的规则,并得到了相同的结果。很多组合后,我就开始工作的唯一办法是内联&LT;风格&GT; 块中的&LT; HEAD&GT; ,与冲突的规则,从未来一个&LT;链接&GT; &LT;身体GT; (身体本身完全除外链接标记为空)。 HTML&GT; 标记,然后加载这个样式表没有创建闪烁的&LT即使使用内联风格属性我的预期。

在受影响的重新绘制的的CSS任何的方式,或者是最终输出应用一下子整个样式表下载,它的规则计算的,以最后的输出应该是什么之后?不要CSS文件下载paralel与HTML本身或阻止它(如script标签做)?这是如何实际工作?

我不是在寻找的优化建议,我正在寻找关于这个问题的权威参考,这样我可以在将来引用他们。它已经很难搜索此信息,而不调高吨无关的材料。摘要:


  • 是所有的CSS内容的<​​em>它的任何的应用下载过? (请参考)

  • 这是如何影响到像 @import 的东西,多个&LT;链接&GT; S,内嵌样式属性, &LT;风格&GT; 块的头部,而不同的渲染引擎

  • 是否CSS的内容下载阻止HTML文档本身?
  • 的下载

解决方案

  

如何在浏览器采取规则这个样式表,并将其应用到HTML?


典型地,这是在一个流的方式进行。该浏览器读取HTML标记作为流,并将其应用于可的元素它迄今看到什么样的规则。 (显然,这是一个简化。)

这是有趣的相关Q&放大器; A:<一href=\"http://stackoverflow.com/questions/4656975/use-css-selectors-to-collect-html-elements-from-a-streaming-parser-e-g-sax-stre\">Use CSS选择器来收集从流式解析HTML元素(例如SAX流) (一改道,而我搜索的文章我心目中)。


啊,那就是:为什么我们没有一个家长选择


  

我们常常觉得我们这些充满要素和内容的全面和完整的文档页面。然而,浏览器设计用于处理像一个流文件。他们开始从服务器接收文档,并可以使文档之前,它已经完全下载。每个节点被评估并呈现给在其被接收的视


  
  

一个例子文档的主体请看下图:

 &LT;身体GT;
   &LT; D​​IV ID =内容&GT;
      &LT; D​​IV CLASS =模块介绍&GT;
         &所述p为H.; Lorem存有与所述; / P&GT;
      &LT; / DIV&GT;
      &LT; D​​IV CLASS =模块&GT;
         &所述p为H.; Lorem存有与所述; / P&GT;
         &所述p为H.; Lorem存有与所述; / P&GT;
         &所述p为H.; Lorem存有&所述;跨度&GT;试验&下; /跨度&GT;&下; / P&GT;
      &LT; / DIV&GT;
   &LT; / DIV&GT;
&LT; /身体GT;


  
  

浏览器开始在顶部,看到一个元素。在此刻,
  它认为它是空的。它没有计算任何东西。浏览器
  将确定的计算方式是什么,并将其应用到
  元件。什么是字体,颜色,行高?后
  数字了这一点,它是绘制到屏幕上。


  
  

接下来,看到一个 DIV 元素的内容的ID。再次,在这个
  点,它认为它是空的。它没有计算任何东西。该
  浏览器计算出的样式,然后 DIV 被画。该
  浏览器将确定是否需要重画的被检体内做了元件
  获得更宽或更高? (我怀疑还有其他方面的考虑,但
  宽度和高度的变化是最常见的影响子元素
  对他们的父母。)


  
  

此过程继续,直到它到达文件的结尾。


  
  


  
  

CSS被从右到左评估。


  
  

要确定一个CSS规则是否适用于特定的元素,它
  从规则的权利,并开始工作它的方式离开了。


  
  

如果你有这样一个规则 DIV体#内容p {颜色:#003366; } 然后
  每一个元素,因为它被呈现到页面稍后即先问,如果
  这是一个段落元素。如果是,它会工作它的方式和DOM
  问,如果它是一个 DIV 与内容的ID。如果发现什么它看
  对,它会直到它到达身体继续它的方式DOM


  
  

通过工作从右到左,浏览器可以判断是否规则
  适用于这个特定的元素,它正试图描绘的
  视要快得多。以确定哪些规则是或多或少
  高性能,你需要弄清楚多少节点需要进行评估
  以确定样式是否可以应用到的元素




  

那么,为什么样式表的内容不是渐进(绿,再红)应用?


我的认为的答案是,外部样式表的解析<​​/ em>的,因为它们是下载的,但不是的适用的,直到整个样式表已经被解析。当然,在解析样式表,浏览器优化走不必要的和冗余的CSS规则。

我没有任何证据来支持,截至目前,但解释听起来合理的,我和你看到的一致,都与外部和内联样式。

Let's say we have an HTML page with a single stylesheet <link>. How does the browser take the rules in this stylesheet and apply it to the HTML? I'm not asking about how to make it faster, I want to know how the rendering itself is handled.

Does it apply each rule one-by-one as it parses the stylesheet and render the result progressively? Or, are the CSS file's contents completely downloaded, then fully evaluated, and then applied to the HTML all at once? Or something else?

I ask this after posting an answer earlier on a question about CSS rule order affecting rendering speed, with the assumption that the styles were rendered as the stylesheet loaded, so the first rules would be applied before the last ones, and not all at once. I'm not sure where I picked up the idea, it's just something I have always thought.

I tried a demo on my server that looked like this:

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

test.css contents:

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

Testing in Firefox 5, I expected to see green at first, then turn to red. It didn't happen. I tried with two separate stylesheets with conflicting rules and got the same results. After many combinations, the only way I got it to work was an inline <style> block in the <head>, with the conflicting rules coming from a <link> in the <body> (the body itself was completely empty except for the link tag). Even using an inline style attribute on the <html> tag, and then loading this stylesheet did not create the flicker that I expected.

Are repaints affected in any way by the CSS, or is the final output applied all at once after the entire stylesheet is downloaded and it's rules computed to what the final output should be? Do CSS files download in paralel with the HTML itself or block it (like script tags do)? How does this actually work?

I am not looking for optimization tips, I'm looking for authoritative references on the subject, so that I can cite them in the future. It's been very difficult to search for this information without turning up tons of unrelated material. Summary:

  • Is all CSS content downloaded before any of it is applied? (reference please)
  • How is this affected by things like @import, multiple <link>s, inline style attributes, <style> blocks in the head, and different rendering engines?
  • Does the download of CSS content block the downloading of the the HTML document itself?

解决方案

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

Typically this is done in a streaming fashion. The browser reads the HTML tags as a stream, and applies what rules it can to the elements it has seen so far. (Obviously this is a simplification.)

An interesting related Q&A: Use CSS selectors to collect HTML elements from a streaming parser (e.g. SAX stream) (a diversion while I search for the article I have in mind).


Ah, here it is: 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)?

I think the answer is that external stylesheets are parsed as they are downloaded, but not applied until the entire stylesheet has been parsed. Surely, in parsing a stylesheet, the browser optimizes away unnecessary and redundant CSS rules.

I don't have any proof to back that up right now, but that explanation sounds reasonable to me and agrees with what you're seeing, both with external and inline styles.

这篇关于浏览器是如何应用CSS,并重新绘制受它的影响?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆