渲染:重绘,重排/重新布局,重设样式

2010 update: Lo, the Web Performance Advent Calendar hath moved

2010年更新: Lo, Web Performance Advent Calendar已移动

Dec 17 This post is part of the 2009 performance advent calendar experiment. Stay tuned for the articles to come.

12月17日这篇文章是2009年性能出现日历实验的一部分。 请继续关注未来的文章。

UPDATE: Ukraine translation here.

更新:乌克兰翻译在这里

Nice 5 "R" words in the title, eh? Let's talk about rendering - a phase that comes in the Life of Page 2.0 after, and sometimes during, the waterfall of downloading components.

标题中有5个“ R”字,是吗? 让我们谈谈渲染-在下载组件的瀑布之后,有时是在Page 2.0生命周期中出现的一个阶段。

So how does the browser go about displaying your page on the screen, given a chunk of HTML, CSS and possibly JavaScript.

因此,在给定HTML,CSS和JavaScript的前提下,浏览器如何在屏幕上显示页面。

渲染过程 (The rendering process)

Different browsers work differently, but the following diagram gives a general idea of what happens, more or less consistently across browsers, once they've downloaded the code for your page.

不同的浏览器的工作方式不同,但是下图给出了浏览器为您的页面下载代码后或多或少一致的结果的大致思路。

Rendering process in the browser
  • The browser parses out the HTML source code (tag soup) and constructs a DOM tree - a data representation where every HTML tag has a corresponding node in the tree and the text chunks between tags get a text node representation too. The root node in the DOM tree is the documentElement (the <html> tag)

    浏览器解析HTML源代码(标签汤)并构建DOM树-数据表示,其中每个HTML标签在树中都有一个对应的节点,并且标签之间的文本块也获得文本节点表示。 DOM树中的根节点是documentElement ( <html>标记)

  • The browser parses the CSS code, makes sense of it given the bunch of hacks that could be there and the number of -moz, -webkit and other extensions it doesn't understand and will bravely ignore. The styling information cascades: the basic rules are in the User Agent stylesheets (the browser defaults), then there could be user stylesheets, author (as in author of the page) stylesheets - external, imported, inline, and finally styles that are coded into the style attributes of the HTML tags

    浏览器解析CSS代码,鉴于可能存在的大量hacks,以及-moz-webkit和它不理解并且勇敢忽略的其他扩展的数量,使之有意义。 样式信息级联:基本规则在用户代理样式表中(浏览器默认设置),然后可能有用户样式表,作者样式表(如页面的作者)-外部,导入,内联以及最终编码的样式进入HTML标签的style属性

  • Then comes the interesting part - constructing a render tree. The render tree is sort of like the DOM tree, but doesn't match it exactly. The render tree knows about styles, so if you're hiding a div with display: none, it won't be represented in the render tree. Same for the other invisible elements, like head and everything in it. On the other hand, there might be DOM elements that are represented with more than one node in the render tree - like text nodes for example where every line in a <p> needs a render node. A node in the render tree is called a frame, or a box (as in a CSS box, according to the box model). Each of these nodes has the CSS box properties - width, height, border, margin, etc

    然后是有趣的部分-构造渲染树。 渲染树有点像DOM树,但不完全匹配。 渲染树了解样式,因此,如果您使用display: none隐藏div ,则它将不会在渲染树中表示。 其他不可见元素也一样,例如head和其中的所有内容。 另一方面,在渲染树中可能存在用多个节点表示的DOM元素-例如文本节点,其中<p>中的每一行都需要一个渲染节点。 渲染树中的节点称为framebox (根据box模型,在CSS box)。 这些节点中的每个节点都有CSS框属性-宽度,高度,边框,边距等

  • Once the render tree is constructed, the browser can paint (draw) the render tree nodes on the screen

    构造渲染树后,浏览器可以在屏幕上绘制(绘制)渲染树节点

森林和树木(The forest and the trees)

Let's take an example.

让我们举个例子。

HTML source:

HTML来源

<html>
<head>
  <title>Beautiful page</title>
</head>
<body>
    
  <p>
    Once upon a time there was 
    a looong paragraph...
  </p>
  
  <div style="display: none">
    Secret message
  </div>
  
  <div><img src="..." /></div>
  ...
 
</body>
</html>

The DOM tree that represents this HTML document basically has one node for each tag and one text node for each piece of text between nodes (for simplicity let's ignore the fact that whitespace is text nodes too) :

表示此HTML文档的DOM树基本上在每个标签上都有一个节点,在节点之间的每一段文本中都有一个文本节点(为简单起见,我们也忽略了空白也是文本节点这一事实):

documentElement (html)
    head
        title
    body
        p
            [text node]
		
        div 
            [text node]
		
        div
            img
		
        ...

The render tree would be the visual part of the DOM tree. It is missing some stuff - the head and the hidden div, but it has additional nodes (aka frames, aka boxes) for the lines of text.

渲染树将是DOM树的可视部分。 它缺少一些东西-头部和隐藏的div,但是它具有用于文本行的其他节点(aka框架,aka框)。

root (RenderView)
    body
        p
            line 1
	    line 2
	    line 3
	    ...
	    
	div
	    img
	    
	...

The root node of the render tree is the frame (the box) that contains all other elements. You can think of it as being the inner part of the browser window, as this is the restricted area where the page could spread. Technically WebKit calls the root node RenderView and it corresponds to the CSS initial containing block, which is basically the viewport rectangle from the top of the page (0, 0) to (window.innerWidth, window.innerHeight)

渲染树的根节点是包含所有其他元素的框架(框)。 您可以将其视为浏览器窗口的内部,因为这是页面可能散布的受限区域。 技术上的WebKit调用根节点RenderView和它对应于CSS初始包含块,这基本上是从页面(顶端的视口矩形00 )到( window.innerWidthwindow.innerHeight )

Figuring out what and how exactly to display on the screen involves a recursive walk down (a flow) through the render tree.

弄清楚在屏幕上显示什么以及如何精确显示需要在渲染树中进行递归遍历(流程)。

重涂和重涂 (Repaints and reflows)

There's always at least one initial page layout together with a paint (unless, of course you prefer your pages blank :)). After that, changing the input information which was used to construct the render tree may result in one or both of these:

总是至少有一个初始页面布局和一个油漆(除非,当然,您更喜欢页面空白:))。 之后,更改用于构造渲染树的输入信息可能会导致以下一项或两项:

  1. parts of the render tree (or the whole tree) will need to be revalidated and the node dimensions recalculated. This is called a reflow, or layout, or layouting. (or "relayout" which I made up so I have more "R"s in the title, sorry, my bad). Note that there's at least one reflow - the initial layout of the page

    渲染树的一部分(或整个树)将需要重新验证,并且节点尺寸需要重新计算。 这就是所谓的回流,或布局,布点或。 (或由我组成的“中继”,所以标题中有更多“ R”,对不起,我的错)。 请注意,至少有一个重排-页面的初始布局

  2. parts of the screen will need to be updated, either because of changes in geometric properties of a node or because of stylistic change, such as changing the background color. This screen update is called a repaint, or a redraw.

    由于节点几何属性的更改或样式更改(例如更改背景颜色),因此需要更新屏幕的某些部分。 此屏幕更新称为repaint或redraw。

Repaints and reflows can be expensive, they can hurt the user experience, and make the UI appear sluggish.

重画和重排可能很昂贵,可能会损害用户体验,并使UI显得呆滞。

是什么导致重排或重涂 (What triggers a reflow or a repaint)

Anything that changes input information used to construct the rendering tree can cause a repaint or a reflow, for example:

更改用于构造渲染树的输入信息的任何操作都可能导致重画或重排,例如:

  • Adding, removing, updating DOM nodes

    添加,删除,更新DOM节点
  • Hiding a DOM node with display: none (reflow and repaint) or visibility: hidden (repaint only, because no geometry changes)

    隐藏display: none的DOM节点display: none (重排和重绘)或visibility: hidden (仅重绘,因为几何形状不变)

  • Moving, animating a DOM node on the page

    移动页面上的DOM节点并为其设置动画
  • Adding a stylesheet, tweaking style properties

    添加样式表,调整样式属性
  • User action such as resizing the window, changing the font size, or (oh, OMG, no!) scrolling

    用户操作,例如调整窗口大小,更改字体大小或滚动(哦,天哪,不!)

Let's see a few examples:

让我们看几个例子:

var bstyle = document.body.style; // cache
 
bstyle.padding = "20px"; // reflow, repaint
bstyle.border = "10px solid red"; // another reflow and a repaint
 
bstyle.color = "blue"; // repaint only, no dimensions changed
bstyle.backgroundColor = "#fad"; // repaint
 
bstyle.fontSize = "2em"; // reflow, repaint
 
// new DOM element - reflow, repaint
document.body.appendChild(document.createTextNode('dude!'));

Some reflows may be more expensive than others. Think of the render tree - if you fiddle with a node way down the tree that is a direct descendant of the body, then you're probably not invalidating a lot of other nodes. But what about when you animate and expand a div at the top of the page which then pushes down the rest of the page - that sounds expensive.

某些回流可能比其他回流更昂贵。 想一想渲染树-如果您在树的下方随意摆弄一个节点,该节点是身体的直接后代,那么您可能不会使其他许多节点失效。 但是,当您在页面顶部制作一个div动画并展开然后将其向下推到页面的其余部分时,怎么办?这听起来很昂贵。

浏览器很聪明 (Browsers are smart)

Since the reflows and repaints associated with render tree changes are expensive, the browsers aim at reducing the negative effects. One strategy is to simply not do the work. Or not right now, at least. The browser will setup a queue of the changes your scripts require and perform them in batches. This way several changes that each require a reflow will be combined and only one reflow will be computed. Browsers can add to the queued changes and then flush the queue once a certain amount of time passes or a certain number of changes is reached.

由于与渲染树更改相关的重排和重绘成本很高,因此浏览器旨在减少负面影响。 一种策略是根本不做这项工作。 至少现在还是现在。 浏览器将设置脚本所需的更改队列,并分批执行。 这样,将分别合并多个需要重排的更改,并且仅计算一次重排。 浏览器可以添加到排队的更改中,然后在经过一定时间或达到一定数量的更改后刷新队列。

But sometimes the script may prevent the browser from optimizing the reflows, and cause it to flush the queue and perform all batched changes. This happens when you request style information, such as

但是有时该脚本可能会阻止浏览器优化重排,并导致其刷新队列并执行所有批量更改。 当您请求样式信息(例如,

  1. offsetTop, offsetLeft, offsetWidth, offsetHeight

    offsetTopoffsetLeftoffsetWidthoffsetHeight

  2. scrollTop/Left/Width/Height

    scrollTop /左/宽/高

  3. clientTop/Left/Width/Height

    clientTop /左侧/宽度/高度

  4. getComputedStyle(), or currentStyle in IE

    IE中的getComputedStyle()currentStyle

All of these above are essentially requesting style information about a node, and any time you do it, the browser has to give you the most up-to-date value. In order to do so, it needs to apply all scheduled changes, flush the queue, bite the bullet and do the reflow.

以上所有这些本质上都是在请求有关节点的样式信息,并且每次执行此操作时,浏览器都必须为您提供最新的值。 为此,它需要应用所有计划的更改,冲洗队列,咬住子弹并进行重排。

For example, it's a bad idea to set and get styles in a quick succession (in a loop), like:

例如,快速(连续)设置和获取样式是一个坏主意,例如:

// no-no!
el.style.left = el.offsetLeft + 10 + "px";

尽量减少重涂和重熔 (Minimizing repaints and reflows)

The strategy to reduce the negative effects of reflows/repaints on the user experience is to simply have fewer reflows and repaints and fewer requests for style information, so the browser can optimize reflows. How to go about that?

减少重排/重画对用户体验的负面影响的策略是简单地减少重排和重画以及减少对样式信息的请求,以便浏览器可以优化重排。 怎么办呢?

  • Don't change individual styles, one by one. Best for sanity and maintainability is to change the class names not the styles. But that assumes static styles. If the styles are dynamic, edit the cssText property as opposed to touching the element and its style property for every little change.

    不要一一更改个性风格。 为了保持理智和可维护性,最好的办法是更改类名而不是样式。 但这假定为静态样式。 如果样式是动态的,请编辑cssText属性,而不是对每个小的更改都触摸元素及其样式属性。

    // bad
    var left = 10,
        top = 10;
    el.style.left = left + "px";
    el.style.top  = top  + "px";
     
    // better 
    el.className += " theclassname";
     
    // or when top and left are calculated dynamically...
     
    // better
    el.style.cssText += "; left: " + left + "px; top: " + top + "px;";
    
  • Batch DOM changes and perform them "offline". Offline means not in the live DOM tree. You can:

    批量更改DOM,然后“离线”执行。 脱机意味着不在实时DOM树中。 您可以:

    • use a documentFragment to hold temp changes,

      使用documentFragment来保存临时更改,

    • clone the node you're about to update, work on the copy, then swap the original with the updated clone

      克隆您要更新的节点,进行复制,然后将原始节点与更新的克隆交换
    • hide the element with display: none (1 reflow, repaint), add 100 changes, restore the display (another reflow, repaint). This way you trade 2 reflows for potentially a hundred

      使用display: none隐藏元素display: none (1个重排,重绘),添加100项更改,恢复显示(另一个重排,重绘)。 这样一来,您将2个回流焊换成100

  • Don't ask for computed styles excessively. If you need to work with a computed value, take it once, cache to a local var and work with the local copy. Revisiting the no-no example from above:

    不要过分要求计算样式。 如果需要使用计算值,请取一次,缓存到本地变量并使用本地副本。 从上面回顾“禁止”的例子:

    // no-no!
    for(big; loop; here) {
        el.style.left = el.offsetLeft + 10 + "px";
        el.style.top  = el.offsetTop  + 10 + "px";
    }
     
    // better
    var left = el.offsetLeft,
        top  = el.offsetTop
        esty = el.style;
    for(big; loop; here) {
        left += 10;
        top  += 10;
        esty.left = left + "px";
        esty.top  = top  + "px";
    }
    
  • In general, think about the render tree and how much of it will need revalidation after your change. For example using absolute positioning makes that element a child of the body in the render tree, so it won't affect too many other nodes when you animate it for example. Some of the other nodes may be in the area that needs repainting when you place your element on top of them, but they will not require reflow.

    通常,请考虑一下渲染树,以及更改后需要重新验证其中的多少。 例如,使用绝对定位使该元素成为渲染树中身体的子代,因此,例如,在对其进行动画处理时,它不会影响太多其他节点。 当您将元素放置在其他节点上时,其中一些其他节点可能位于需要重绘的区域中,但它们不需要重排。

工具类 (Tools)

Only about a year ago, there was nothing that can provide any visibility into what's going on in the browser in terms of painting and rendering (not that I am aware of, it's of course absolutely possible that MS had a wicked dev tool no one knew about, buried somewhere in MSDN :P). Now things are different and this is very, very cool.

仅在大约一年前,还没有任何东西可以提供关于绘画和渲染方面浏览器中发生的一切的信息(不是我所知道的,当然,MS绝对有可能拥有一个没人知道的邪恶的开发工具)关于,埋在MSDN中的某个地方:P)。 现在情况有所不同,这非常非常酷。

First, MozAfterPaint event landed in Firefox nightlies, so things like this extension by Kyle Scholz showed up. mozAfterPaint is cool, but only tells you about repaints.

首先,MozAfterPaint事件降落在Firefox Nightlies版,所以像这种扩展凯尔肖尔茨露面。 mozAfterPaint很酷,但是只告诉您有关重新绘制的信息。

DynaTrace Ajax and most recently Google's SpeedTracer (notice two "trace"s :)) are just excellent tools for digging into reflows and repaints - the first is for IE, the second for WebKit.

DynaTrace Ajax和最近的Google的SpeedTracer (注意两个“痕迹” :))都是挖掘重排和重绘的绝佳工具-第一个用于IE,第二个用于WebKit。

Some time last year Douglas Crockford mentioned that we're probably doing some really stupid things in CSS we don't know about. And I can definitely relate to that. I was involved in a project for a bit where increasing the browser font size (in IE6) was causing the CPU go up to 100% and stay like this for 10-15 minutes before finally repainting the page.

去年的某个时候,Douglas Crockford提到我们可能正在用CSS做一些我们不知道的非常愚蠢的事情。 我可以肯定地说一下。 我参与了一个项目,其中浏览器字体大小的增加(在IE6中)导致CPU上升至100%,并保持10-15分钟,直到最终重新绘制页面为止。

Well, the tools are now here, we don't have excuses any more for doing silly things in CSS.

好了,这些工具现在都在这里,我们再也没有理由在CSS中做一些愚蠢的事情了。

Except, maybe, speaking of tools..., wouldn't it be cool if the Firebug-like tools showed the render tree in addition to the DOM tree?

除了,也许说到工具...,如果像Firebug的工具除了显示DOM树之外还显示渲染树,这会很酷吗?

最后的例子 (A final example)

Let's just take a quick look at the tools and demonstrate the difference between restyle (render tree change that doesn't affect the geometry) and reflow (which affects the layout), together with a repaint.

让我们快速浏览一下这些工具,并展示restyle (不影响几何的渲染树更改)和reflow (影响布局)以及repaint之间的区别。

Let's compare two ways of doing the same thing. First, we change some styles (not touching layout) and after every change, we check for a style property, totally unrelated to the one just changed.

让我们比较两种做同一件事的方法。 首先,我们更改一些样式(不改变布局),并且每次更改后,我们都检查一个样式属性,该属性与刚更改的样式完全无关。

bodystyle.color = 'red';
tmp = computed.backgroundColor;
bodystyle.color = 'white';
tmp = computed.backgroundImage;
bodystyle.color = 'green';
tmp = computed.backgroundAttachment;

Then the same thing, but we're touching style properties for information only after all the changes:

然后是同一件事,但是我们仅在所有更改之后才接触样式属性以获取信息:

bodystyle.color = 'yellow';
bodystyle.color = 'pink';
bodystyle.color = 'blue';
 
tmp = computed.backgroundColor;
tmp = computed.backgroundImage;
tmp = computed.backgroundAttachment;

In both cases, these are the definitions of the variables used:

在这两种情况下,这些都是使用的变量的定义:

var bodystyle = document.body.style;
var computed;
if (document.body.currentStyle) {
  computed = document.body.currentStyle;
} else {
  computed = document.defaultView.getComputedStyle(document.body, '');
}

Now, the two example style changes will be executed on click on the document. The test page is actually here - restyle.html (click "dude"). Let's call this restyle test.

现在,将在单击文档时执行两个示例样式更改。 测试页面实际上在这里-restyle.html (单击“花花公子”)。 我们称此为样式测试

The second test is just like the first, but this time we'll also change layout information:

第二个测试与第一个类似,但是这次我们还将更改布局信息:

// touch styles every time
bodystyle.color = 'red';
bodystyle.padding = '1px';
tmp = computed.backgroundColor;
bodystyle.color = 'white';
bodystyle.padding = '2px';
tmp = computed.backgroundImage;
bodystyle.color = 'green';
bodystyle.padding = '3px';
tmp = computed.backgroundAttachment;
 
 
// touch at the end
bodystyle.color = 'yellow';
bodystyle.padding = '4px';
bodystyle.color = 'pink';
bodystyle.padding = '5px';
bodystyle.color = 'blue';
bodystyle.padding = '6px';
tmp = computed.backgroundColor;
tmp = computed.backgroundImage;
tmp = computed.backgroundAttachment;

This test changes the layout so let's called it "relayout test", the source is here.

此测试更改了布局,因此我们将其称为“重新布局测试”,其来源在此处

Here's what type of visualization you get in DynaTrace for the restyle test.

这是您在DynaTrace中获得的用于样式更改测试的可视化类型。

DynaTrace

Basically the page loaded, then I clicked once to execute the first scenario (requests for style info every time, at about 2sec), then clicked again to execute the second scenario (requests for styles delayed till the end, at about 4sec)

基本上是页面加载,然后我单击一次以执行第一个方案(每次请求样式信息,大约在2秒),然后再次单击以执行第二种方案(对样式的请求直到最后大约4sec延迟到最后)

The tool shows how the page loaded and the IE logo shows onload. Then the mouse cursor is over the rendering activity following the click. Zooming into the interesting area (how cool is that!) there's a more detailed view:

该工具显示页面如何加载,IE徽标显示onload。 然后,鼠标光标在单击后的渲染活动上方。 放大到有趣的区域(这有多酷!),有一个更详细的视图:

dynatrace

You can clearly see the blue bar of JavaScript activity and the following green bar of rendering activity. Now, this is a simple example, but still notice the length of the bars - how much more time is spent rendering than executing JavaScript. Often in Ajax/Rich apps, JavaScript is not the bottleneck, it's the DOM access and manipulation and the rendering part.

您可以清楚地看到JavaScript活动的蓝色条和以下呈现活动的绿色条。 现在,这是一个简单的示例,但是仍然注意到条形图的长度-渲染所花的时间比执行JavaScript多得多。 在Ajax / Rich应用程序中,JavaScript通常不是瓶颈,它是DOM访问和操作以及呈现的一部分。

OK, now running the "relayout test", the one that changes the geometry of the body. This time check out this "PurePaths" view. It's a timeline plus more information about each item in the timeline. I've highlighted the first click, which is a JavaScript activity producing a scheduled layout task.

好的,现在运行“继电器测试”,该测试可以更改车身的几何形状。 这次签出此“ PurePaths”视图。 这是一个时间轴,以及有关时间轴中每个项目的更多信息。 我突出显示了第一次单击,这是一个JavaScript活动,它会产生计划的布局任务。

dynatrace

Again, zooming into the interesting part, you can see how now in addition to the "drawing" bar, there's a new one before that - the "calculating flow layout", because in this test we had a reflow in addition to the repaint.

再次,放大到有趣的部分,您可以看到现在除了“绘图”栏之外还有一个新的栏-“计算流布局”,因为在此测试中,我们除了重画外还进行了重排。

dynatrace

Now let's test the same page in Chrome and look at the SpeedTracer results.

现在,让我们在Chrome中测试同一页面,然后查看SpeedTracer结果。

This is the first "restyle" test zoomed into the interesting part (heck, I think I can definitely get cused to all that zooming :)) and this is an overview of what happened.

这是第一个放大到有趣部分的“样式”测试(哎呀,我认为我绝对可以专心于所有缩放工作:)),这是发生的事情的概述。

speedtracer

Overall there's a click and there's a paint. But in the first click, there's also 50% time spent recalculating styles. Why is that? Well, this is because we asked for style information with every change.

总的来说,有一个点击,有一个油漆。 但是在第一次点击中,还有50%的时间花费在重新计算样式上。 这是为什么? 好吧,这是因为我们要求每次更改都提供样式信息。

Expanding the events and showing hidden lines (the gray lines were hidden by Speedtracer because they are not slow) we can see exactly what happened - after the first click, styles were calculated three times. After the second - only once.

展开事件并显示隐藏线(灰色线由于不慢而被Speedtracer隐藏了),我们可以确切地看到发生了什么-第一次单击后,样式计算了3次。 在第二次之后-仅一次。

speedtracer

Now let's run the "relayout test". The overall list of events looks the same:

现在,让我们运行“中继测试”。 事件的总体列表看起来相同:

speedtracer

But the detailed view shows how the first click caused three reflows (because it asked for computed style info) and the second click caused only one reflow. This is just excellent visibility into what's going on.

但是详细视图显示了第一次单击如何导致三次重排(因为它要求提供计算的样式信息),而第二次单击仅引起了一次重排。 这只是对正在发生的事情的极好的可见性。

speedtracer

A few minor differences in the tools - SpeedTracer didn't show when the layout task was scheduled and added to the queue, DynaTrace did. And then DynaTrace didn't show the details of the difference between "restyle" and "reflow/layout", like SpeedTracer did. Maybe simply IE doesn't make a difference between the two? DynaTrace also didn't show three reflows instead of one in the different change-end-touch vs. change-then-touch tests, maybe that's how IE works?

工具上的一些细微差异-SpeedTracer没有显示何时安排布局任务并将其添加到队列中,而DynaTrace却没有显示。 然后,DynaTrace没有像SpeedTracer那样显示“重设样式”和“重排/布局”之间差异的详细信息。 也许仅仅是IE并没有使两者有所区别? DynaTrace也没有在不同的change-end-touch和vs.change-then-touch测试中显示三项重排,而不是一则,也许这就是IE的工作方式?

Running these simple examples hundreds of times also confirms that for IE it doesn't matter if you request style information as you change it.

数百次运行这些简单的示例还可以确认,对于IE而言,更改样式时是否请求样式信息都无关紧要。

Here's some more data points after running the tests with enough repetitions:

经过足够的重复运行测试之后,这里还有一些数据点:

  • In Chrome not touching computed styles while modifying styles is 2.5 times faster when you change styles (restyle test) and 4.42 times faster when you change styles and layout (relayout test)

    在Chrome中,在修改样式时不触摸计算样式(更改样式(重新样式测试)时,速度是2.5倍,而更改样式和布局(重新布局测试)时,速度要快4.42倍。

  • In Firefox - 1.87 times faster to refrain from asking computed styles in restyle test and 1.64 times faster in the relayout test

    在Firefox中-在重新样式测试中避免要求计算样式的速度提高了1.87倍,在重发测试中提高了1.64倍的速度
  • In IE6 and IE8, it doesn't matter

    在IE6和IE8中,没关系

Across all browsers though changing styles only takes half the time it takes to change styles and layout. (Now that I wrote it, I should've compared changing styles only vs. changing layout only). Except in IE6 where changing layout is 4 times more expensive then changing only styles.

在所有浏览器中,更改样式仅花费更改样式布局所需时间的一半。 (现在,我已经写了它,应该比较仅更改样式与仅更改布局)。 IE6除外,更改布局的费用是仅更改样式的费用的4倍。

分词 (Parting words)

Thanks very much for working through this long post. Have fun with the tracers and watch out for those reflows! In summary, let me go over the different terminology once again.

非常感谢您完成这篇冗长的文章。 与示踪剂一起玩耍,并注意那些回流! 总而言之,让我再次讨论不同的术语。

  • render tree - the visual part of the DOM tree

    渲染树-DOM树的可视部分

  • nodes in the render tree are called frames or boxes

    渲染树中的节点称为框架盒子

  • recalculating parts of the render tree is called reflow (in Mozilla), and called layout in every other browser, it seems

    渲染树的重新计算部分被称为回流(在Mozilla),而在所有其他浏览器调用布局,似乎

  • Updating the screen with the results of the recalculated render tree is called repaint, or redraw (in IE/DynaTrace)

    使用重新计算的渲染树的结果更新屏幕称为repaintredraw (在IE / DynaTrace中)

  • SpeedTracer introduces the notion of "style recalculation" (styles without geometry changes) vs. "layout"

    SpeedTracer引入了“样式重新计算”(不改变几何形状的样式)与“布局”的概念

And some more reading if you find this topic fascinating. Note that these reads, especially the first three, are more in depth, closer to the browser, as opposed to closer to the developer which I tried to do here.

如果您发现这个主题很有趣,还可以阅读更多内容。 请注意,这些读物(尤其是前三个读物)的深度更深,更接近浏览器,而不是更接近我在此处尝试的开发人员。

Tell your friends about this post on Facebook and Twitter

FacebookTwitter上告诉您的朋友有关此帖子的信息

翻译自: https://www.phpied.com/rendering-repaint-reflowrelayout-restyle/

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值