前置:
问:为什么DOM操作比较慢?
是因为DOM操纵是跨线程的。
另外,DOM 操作慢,实际上只是比 JS 操作慢,DOM 操作比网络请求还是快很多的
浏览器功能核心有两部分:渲染引擎和JS引擎
渲染引擎负责渲染页面(渲染HTML和CSS),JS引擎负责执行JS代码
两个线程各司其职
跨线程通信
- document.body.appendChild(div1)
- 当浏览器发现JS在 body 里加了一个 div1 对象
- 浏览器会通知渲染引擎在页面里也新增一个 div 元素
- 新增的 div 元素的所有属性都照抄 div1 对象
注意:一个是元素,一个是对象 - 如下图所示:
- 浪费时间的地方:在中间浏览器部分,从发现到通知过程需要时间
标签插入到页面的完整过程
- 在div1放入页面之前
我们对div1的所有操作都只在JS线程里
- 在div1 放入页面之时
浏览器会发现JS的意图,并通知渲染线程在页面中渲染div1对应的元素
- 在div1放入页面之后
对 div1 的操作都有可能会触发新的渲染(修改里面包含CSS样式)
如果你连续对 div1 多次操作,浏览器可能会合并成一次操作,也可能不会
- 阻断浏览器合并操作的机制:在上下操作之间添加node.clientWidth, 表示获取宽度,触发浏览器再次渲染
修改属性
属性同步
在JS进程中修改 div 的所有内容浏览器都会重新渲染 即属性同步
标准属性 & data-* 属性
对 div1 的修改,会被浏览器同步到页面中非标准属性
对非标准属性(自定义属性)的修改,则只会停留在JS线程中,不会同步到页面里启示
自定义属性想实现属性同步,需在html中以data- 作为属性名前缀,如
在js读取时就是test.dataset.x=’yyy’
如下图:
Property V.S. Attribute
property 属性
JS线程中 div1 的所有属性,叫做 div1对象 的 property
也就是内存中 div 那个对象,比如 style、id、classNameproperty 支持字符串、布尔等类型(了解)
attribute 也是属性
渲染引擎中 div1 对应标签的属性,叫做 attributeattribute 只支持字符串