写点什么

高性能 JavaScriptの笔记(二)

用户头像
空城机
关注
发布于: 2021 年 05 月 15 日
高性能JavaScriptの笔记(二)

DOM 操作

访问 DOM 次数越多,耗费的性能也就越高


通常经验法则是减少访问 DOM 次数,把运算尽量留在 ECMAScript 这一端处理

元素节点

大部分现代浏览器提供的 API 只返回元素节点,如果可用的话推荐使用这些 API


因为这些 API 的执行效率比在 JavaScript 代码中实现过滤的效率要高


比如:使用 children 比 childNodes 效率更高,集合相更少


重绘和重排(回流)

具体可以参考:HTML 回流与重绘


对 DOM 元素进行一系列操作时,可以通过以下步骤减少重绘和重排:


  1. 使元素脱离文档流

  2. 对其应用多重改变

  3. 把元素带回文档中


这三步过程中触发两次重排——第一步和第三步。 但是在第二步操作中将会产生很多次重排


有三种基本方式可以使得 DOM 脱离文档:


  • 隐藏元素。应用修改,重新显示 -- display:none

  • 使用文档片段(docuement fragment)在当前 DOM 之外构建一个子树(createDocumentFragment),再把它拷贝回文档


<script>    const fragment = document.createDocumentFragment();    const fruits = ['Apple', 'Orange', 'Banana', 'Melon'];    fruits.forEach(fruit => {        const li = document.createElement('li');        li.innerHTML = fruit;        fragment.appendChild(li);    });    document.getElementById('a').append(fragment)</script>
复制代码


  • 将原始元素拷贝到一个脱离文档的节点中,修改副本,完成后再替换原始元素

事件委托

当页面存在大量元素,且每个元素都绑定事件处理器(比如 onclick 方法),这种情况会影响性能


每绑定一个事件处理器都是有代价:


  • 要么加重了页面的负担(更多的标签或 JavaScript 代码)

  • 要么增加了运行期的执行时间


DOM 事件要经历三个阶段:


  • 捕获

  • 直到达到目标元素

  • 冒泡

DOM 事件机制

1. 事件流 html 元素触发事件的顺序。

2. 事件捕获(从外向内)

* 网景的事件流叫做事件捕获,从外向内,找监听函数,叫事件捕获;

3. 事件冒泡(从内向外)

* IE 的事件流叫做事件冒泡(event bubbling),从内向外,找监听函数,叫事件冒泡;

4. 取消冒泡

* 捕获不可取消,但是冒泡可取消

* e.stopPropagation() 可中断冒泡,浏览器不在向上走;

事件委托

事件委托就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。

事件委托的原理

事件从最深的节点开始,然后逐步向上传播事件;

事件委托的性能优化

原理: 基于这样一个事实,事件逐层冒泡并能被父级元素捕获。使用事件代理,只需要给外层元素绑定一个处理器,就可以处理在其子元素上触发的所有事件,比如使用 target 判断元素


例子:点击某一行的苹果,这一行的背景颜色改变 orange,文字变成橙子



如果给每一个 li 标签添加 onclick 事件,对性能会造成较大消耗,所以可以给 ul 绑定 onclick 事件代码:

<ul id="a" onclick="aclick()">        <li class="ali"> 苹果 </li>        <li class="ali"> 苹果 </li>        <li class="ali"> 苹果 </li>        <li class="ali"> 苹果 </li>        <li class="ali"> 苹果 </li>        <li class="ali"> 苹果 </li>        <li class="ali"> 苹果 </li>        <li class="ali"> 苹果 </li>        <li class="ali"> 苹果 </li>        <li class="ali"> 苹果 </li>        <li class="ali"> 苹果 </li>        <li class="ali"> 苹果 </li>    </ul>    <script>        function aclick(e) {            var e = e || window.event;            e.target.style.cssText = 'background-color:orange';            e.target.innerText = '橙子';        }    </script>
复制代码


点击效果

小节

平时写代码时可以优化的点①:

减少重绘和回流,要进行多次 DOM 操作时,最好将这部分先从文档流中脱离,然后处理好后放回文档流中


平时写代码时可以优化的点②:

使用事件代理,只需要给外层元素绑定一个处理器,就可以处理在其子元素上触发的所有事件,比如使用 target 判断元素


学习来源:《高性能JavaScript-中文版》(仅供学习使用)


发布于: 2021 年 05 月 15 日阅读数: 15
用户头像

空城机

关注

曾经沧海难为水,只是当时已惘然 2021.03.22 加入

业余作者,在线水文 主要干前端的活,业余会学学python 欢迎各位关注,互相学习,互相进步

评论

发布
暂无评论
高性能JavaScriptの笔记(二)