众所周知,耗时操作是布局 (又名回流),从DOM树 构建渲染树是非常耗费性能的,文末的参考链接才是干货,以下是我的学习笔记:
Rendering
repaint:样式的改变,几何特性的改变
reLayout/reflow: 渲染树节点的距离的重新计算或重新验证
平常需要注意的地方:
不要一个一个去改变,可通过类名、 cssText等一次改变
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
浏览器打开一个网页发生的事情:
- 解析html构建Dom树, 每个标签在树上有一个节点
- 解析css文件及style标签样式信息 解析不了的ignore
- 构建渲染render树,它和Dom树不完全对应 隐藏元素不会显示 head and in it 都不会显示
- 布局渲染树、添加位置和大小
- paint绘制渲染树 显示到屏幕上
HTML在浏览器中会被转化为DOM树,DOM树的每一个节点都会转化为RenderObject, 多个RenderObject可能又会对应一个或多个RenderLayer 浏览器渲染的流程如下:
- 获取 DOM 并将其分割为多个层(RenderLayer)
- 将每个层栅格化,并独立的绘制进位图中
- 将这些位图作为纹理上传至 GPU
- 复合多个层来生成最终的屏幕图像(终极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
网友评论