前置:
问:为什么DOM操作比较慢
是因为DOM操纵是跨线程的。
另外,DOM 操作慢,实际上只是比 JS 操作慢,DOM 操作比网络请求还是快很多的

浏览器功能核心有两部分:渲染引擎和JS引擎
渲染引擎负责渲染页面(渲染HTML和CSS),JS引擎负责执行JS代码
两个线程各司其职

跨线程通信

  1. document.body.appendChild(div1)
  2. 当浏览器发现JS在 body 里加了一个 div1 对象
  3. 浏览器会通知渲染引擎在页面里也新增一个 div 元素
  4. 新增的 div 元素的所有属性都照抄 div1 对象
    注意:一个是元素,一个是对象
  5. 如下图所示:

image.png

  • 浪费时间的地方:在中间浏览器部分,从发现到通知过程需要时间

标签插入到页面的完整过程

  1. 在div1放入页面之前

我们对div1的所有操作都只在JS线程里

  1. 在div1 放入页面之时

浏览器会发现JS的意图,并通知渲染线程在页面中渲染div1对应的元素

  1. 在div1放入页面之后

对 div1 的操作都有可能会触发新的渲染(修改里面包含CSS样式)
如果你连续对 div1 多次操作,浏览器可能会合并成一次操作,也可能不会

  1. - 阻断浏览器合并操作的机制:在上下操作之间添加node.clientWidth 表示获取宽度,触发浏览器再次渲染

修改属性

属性同步
在JS进程中修改 div 的所有内容浏览器都会重新渲染 即属性同步

  • 标准属性 & data-* 属性
    对 div1 的修改,会被浏览器同步到页面中

  • 非标准属性
    对非标准属性(自定义属性)的修改,则只会停留在JS线程中,不会同步到页面里

  • 启示
    自定义属性想实现属性同步,需在html中以data- 作为属性名前缀,如

在js读取时就是test.dataset.x=’yyy’
如下图:
image.png

Property V.S. Attribute

  • property 属性
    JS线程中 div1 的所有属性,叫做 div1对象 的 property
    也就是内存中 div 那个对象,比如 style、id、className

    property 支持字符串、布尔等类型(了解)

  • attribute 也是属性
    渲染引擎中 div1 对应标签的属性,叫做 attribute

    attribute 只支持字符串