repaint:屏幕的一部分重画,不影响整体布局,比如背景色变了,但元素的几何尺寸和位置不变。
reflow:元件的几何尺寸变了,需要重新验证并计算Render Tree。是Render Tree的一部分或全部发生了变化,这就是Reflow,或Layout。
reference: https://gist.github.com/faressoft/36cdd64faae21ed22948b458e6bf04d5
- Receives the data (bytes) from the server.
- Parses and converts into tokens (<, TagName, Attribute, AttributeValue, >).
- Turns tokens into nodes.
- Turns nodes into the DOM tree.
- Builds CSSOM tree from the css rules.
- CSSOM and DOM trees are combined into a Render Tree.
Computes which elements are visible and their computed styles.
Starting from the root of the DOM tree.
Not visible elements like (meta, script, link) and display: none are omitted from the Render Tree.
For each visible node, find the appropriate matching CSSOM rules and apply them.
-Reflow: compute the layout of each visible element (position and size).
-Repaint: renders the pixels to screen.
reflow:
it involves changes that affect the layout of a portion of the page (or the whole page).
- adding or removing content,
- explicitly or implicitly changing width, height, font-family, font-size, position, float.
- Recalculate of positions and dimensions.
- Has a bigger impact, changing a single element can affect all children, ancestors, and siblings or the whole document.
- Triggers (change DOM or css, scrolling, user actions like focus).
Reflow only has a cost if the document has changed and invalidated the layout.
Something Invalidates + Something Triggers = Costly Reflow.
当Render Tree中的一部分(或全部)因为元素的尺寸,布局,隐藏等改变而需要重新构建
每个页面至少需要一次回流,即页面第一次加载的时候。在回流时,浏览器会使render tree中受到影响的部分失效,并重新构造这部分render tree。完成回流后,浏览器会重新绘制受影响的部分到屏幕中,该过程为重绘repaint。
repaint:
A repaint occurs when changes are made to an elements skin that changes visibly, but do not affect its layout.
Examples of this include outline, opacity, visibility, background, or color.
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:
1. Adding, removing, updating DOM nodes
2. Hiding a DOM node with display: none (reflow and repaint) or visibility: hidden (repaint only, because no geometry changes)
3. Moving, animating a DOM node on the page
4. Adding a stylesheet, tweaking style properties
5. User action such as resizing the window, changing the font size, or 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
document.body.appendChild(document.createTextNode('dude!')); //new DOM element reflow, repaint
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
- offsetTop, offsetLeft, offsetWidth, offsetHeight
- scrollTop/Left/Width/Height
- clientTop/Left/Width/Height
- getComputedStyle(), or currentStyle in IE
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:
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?
1. 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.
// 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;";
2. Batch DOM changes and perform them "offline". Offline means not in the live DOM tree. You can:
- use a documentFragment to hold temp changes,
- 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
3. 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";
}
4. 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.
简述浏览器渲染页面的过程,给出下方script中对哪些CSS属性的修改会触发重绘(repaint)和重排(reflow)?
.sg-container {
padding: 10px;
margin-bottom: 10px;
width: 100px;
height: 100px;
}
2019搜狗校园招聘
document.querySelector('p').style.cssText +='height:10px; line-height:24px;font-size:20px;visibility:hidden;background-color:#00f;border:1px solid #f00';
浏览器渲染过程因不同内核可能会有差异,以webkit为例:
第一阶段:
1. 输入URL,webkit依赖网络模块加载网页或资源数据
2. 网页交给HTML解释器转变成一系列的词语
3. 解释器根据词语构建节点并形成DOM树
4. 如果节点是CSS、图片、视频等资源,调用资源加载器加载,因该类资源加载是异步的,不会阻塞当前DOM树的继续创建
5. 如果节点是javascript,停止当前DOM树的创建,直到javascript资源加载完成并被javascript引擎执行后才继续进行DOM的创建
第二阶段:
1. CSS解释器解析CSS文件成内部表示结构,并在DOM树上附加样式信息形成RenderObject树
2. RenderObject节点在创建的同时,webkit会根据网页的层次结构创建RenderLayer树,同时创建一个虚拟的绘图上下文
第三阶段:
1.根据生成的绘图上下文和2D或3D图形库生成最终的图像
对于包含动画和用户交互的动态网页,浏览器的渲染过程会重复的执行,可能会触发不同程度的重排和重绘。
reflow属性:height, line-height, font-size, border
repaint属性:height, line-height, font-size, border, background-color, visibility
css3里哪些属性能避免回流
结合浏览器的渲染过程解释回流浪费性能的原因
有一些回调事件在16.7ms内渲染不完,怎么办?为什么是16.7ms?
服务器想要获取一个元素的宽高,重排还是重绘?分情况。