浏览器的渲染与脚本优化

众所周知,耗时操作是布局 (又名回流),从DOM树 构建渲染树是非常耗费性能的,文末的参考链接才是干货,以下是我的学习笔记:

Rendering

repaint:样式的改变,几何特性的改变
reLayout/reflow: 渲染树节点的距离的重新计算或重新验证

平常需要注意的地方:

不要一个一个去改变,可通过类名、 cssText等一次改变

Batch DOM changes and perform them "offline". Offline means not in the live DOM tree. You can:

  1. use a documentFragment to hold temp changes,
  2. clone the node you're about to update, work on the copy, then swap the original with the updated clone
  3. 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

浏览器打开一个网页发生的事情:

  1. 解析html构建Dom树, 每个标签在树上有一个节点
  2. 解析css文件及style标签样式信息 解析不了的ignore
  3. 构建渲染render树,它和Dom树不完全对应 隐藏元素不会显示 head and in it 都不会显示
  4. 布局渲染树、添加位置和大小
  5. paint绘制渲染树 显示到屏幕上

HTML在浏览器中会被转化为DOM树,DOM树的每一个节点都会转化为RenderObject, 多个RenderObject可能又会对应一个或多个RenderLayer 浏览器渲染的流程如下:

  1. 获取 DOM 并将其分割为多个层(RenderLayer)
  2. 将每个层栅格化,并独立的绘制进位图中
  3. 将这些位图作为纹理上传至 GPU
  4. 复合多个层来生成最终的屏幕图像(终极layer)

关于脚本:

预解析 执行脚本时,另一线程解析剩下文档加载后续资源
样式表 因样式不改变dom树 不影响文档解析 ,但脚本可能请求样式 这就需要阻塞
defer 文档加载结束 只有IE支持
async 只能用于外部脚本 异步执行不会阻塞页面加载 比如alert()

关于setTimeout()和setInterval()

IE8及以下浏览器时间间隔为15.6ms,chrome和IE9以上 4ms ,除此之外也和当前电脑环境是否有电源有关系
同步函数总是优于异步函数
浏览器始终只有一个线程在工作 (可以这么理解,因为js引擎和UI 互斥),改变颜色时,脚本仍在执行无法调用UI线程
网络操作线程 2-6个
Web Worker: 使处理UI线程之外的脚本执行成为可能,可是JS脚本在后台线程运行而不影响UI线程,每一个Web Worker都是相互独立的都在自己的线程中运行。
注意: Web Worker不能操作DOM 可用于处理与UI线程无关的长时间运行脚本

参考:http://zawa.iteye.com/blog/1270502
http://www.phpied.com/rendering-repaint-reflowrelayout-restyle/
http://gent.ilcore.com/2011/03/how-not-to-trigger-layout-in-webkit.html

你可能感兴趣的:(浏览器的渲染与脚本优化)