重绘回流过程

1. 浏览器的渲染过程,DOM 树和渲染树的区别?

xuanran.png

  1. HTML 经过解析生成 DOM树; CSS经过解析生成 Style Rules。 二者一结合生成了Render Tree。
  2. 通过layout计算出DOM要显示的宽高、位置、颜色。
  3. 最后渲染在界面上,用户就看到了

2. 浏览器的渲染过程

  1. 解析 HTML 构建 DOM(DOM 树),并行请求 css/image/js
  2. CSS 文件下载完成,开始构建 CSSOM(CSS 树)
  3. CSSOM 构建结束后,和 DOM 一起生成 Render Tree(渲染树)
  4. 布局(Layout):计算出每个节点在屏幕中的位置
  5. 显示(Painting):通过显卡把页面画到屏幕上

3. DOM 树 和 渲染树 的区别?

  1. DOM 树与 HTML 标签一一对应,包括 head 和隐藏元素
  2. 渲染树不包括 head 和隐藏元素,大段文本的每一个行都是独立节点,每一个节点都有对应的 css 属性

4. CSS会阻塞DOM解析吗?

  1. 对于一个HTML文档来说,不管是内联还是外链的css,都会阻碍后续的dom渲染,但是不会阻碍后续dom的解析。

  2. 当css文件放在<head>中时,虽然css解析也会阻塞后续dom的渲染,但是在解析css的同时也在解析dom,所以等到css解析完毕就会逐步的渲染页面了。

5. 重绘和回流(重排)的区别和关系?

  1. 重绘:当渲染树中的元素外观(如:颜色)发生改变,不影响布局时,产生重绘
  2. 回流:当渲染树中的元素的布局(如:尺寸、位置、隐藏/状态状态)发生改变时,产生重绘回流
  3. 注意:JS 获取 Layout 属性值(如:offsetLeft、scrollTop、getComputedStyle 等)也会引起回流。因为浏览器需要通过回流计算最新值
  4. 回流必将引起重绘,而重绘不一定会引起回流

5.1 触发reflow

  1. width/height/border/margin/padding的修改,如width=778px;
  2. 动画,:hover等伪类引起的元素表现改动,display=none等造成页面回流;
  3. appendChild等DOM元素操作;
  4. font类style的修改;
  5. background的修改,注意着字面上可能以为是重绘,但是浏览器确实回流了,经过浏览器厂家的优化,部分background的修改只触发repaint,当然IE不用考虑;
  6. scroll页面,这个不可避免;
  7. resize页面,桌面版本的进行浏览器大小的缩放,移动端的话,还没玩过能拖动程序,resize程序窗口大小的多窗口操作系统。
  8. 读取元素的属性(这个无法理解,但是技术达人是这么说的,那就把它当做定理吧):读取元素的某些属性(offsetLeft、offsetTop、offsetHeight、offsetWidth、scrollTop/Left/Width/Height、clientTop/Left/Width/Height、getComputedStyle()、currentStyle(in IE));

5.2 触发repaint

  1. color的修改,如color=#ddd;
  2. text-align的修改,如text-align=center;
  3. a:hover也会造成重绘。
  4. :hover引起的颜色等不导致页面回流的style变动。

6. 如何最小化重绘(repaint)和回流(reflow)?

6.1 性能问题

以下操作会导致性能问题:

  1. 改变 window 大小
  2. 改变字体
  3. 添加或删除样式
  4. 文字改变
  5. 定位或者浮动
  6. 盒模型

3.2 解决方法

  1. 需要要对DOM元素进行复杂的操作时,可以先隐藏(display:"none"),操作完成后再显示
  2. 需要创建多个 DOM 节点时,使用 DocumentFragment 创建完后一次性的加入 document,或使用字符串拼接方式构建好对应HTML后再使用innerHTML来修改页面
  3. 缓存 Layout 属性值,如:var left = elem.offsetLeft; 这样,多次使用 left 只产生一次回流
  4. 避免用 table 布局(table 元素一旦触发回流就会导致 table 里所有的其它元素回流)
  5. 避免使用 css 表达式(expression),因为每次调用都会重新计算值(包括加载页面)
  6. 尽量使用 css 属性简写,如:用 border 代替 border-width, border-style, border-color
  7. 批量修改元素样式:elem.className 和 elem.style.cssText 代替 elem.style.xxx

results matching ""

    No results matching ""