JS对DOM的操作优化法则
html页面显示过程
- 解析HTML,并生成一棵DOM tree
- 解析各种样式并结合DOM tree生成一棵Render tree
- 对Render tree的各个节点计算布局信息,比如box的位置与尺寸
- 根据Render tree并利用浏览器的UI层进行绘制流程。
其中,第三步,对render tree的各个结点计算布局信息为时间占用较大的一部分,而在这一步中,包含了layout,layout操作,是对render tree中对象的大小、尺寸进行计算,在默认情况下,浏览器的layout为lazy模式,也就是说,并非每次我们对DOM进行修改时都会layout,而是将这些修改存储在一个队列中,在一定的情况下统一提交队列,进而实现layout操作。
1.批量读写
当我们需要获取某一属性,这一属性需要计算才能得到,并且队列中存在尚未提交的DOM修改操作,则此时,DOM修改操作的队列将会被提交。
为了提高效率,减少更新render tree的次数,可以先统一读取属性,然后统一修改DOM,这样,就可以减少更新render tree的次数。
2.虚拟结点
当我们需要对DOM做出大量修改时,可以先创建一个虚拟结点,将所有修改附加在该节点,最后将该虚拟节点一次性提交给在render tree上存在的结点,则相当于只提交了一次修改操作。
3.查找元素的优化
因为ID是唯一的,也有原始的方法,因此使用ID查找元素是最快的,其次的是根据类和类型查找元素,通过属性查找元素是最慢的,因此应该尽可能的通过ID或者类来查找元素,避免通过类来查找元素。
4.改变DOM,包括添加,修改,删除DOM
改变DOM就会引起浏览器渲染,而渲染是相当慢的,因此应该避免不必要的渲染。
5.改变DOM的样式类等
改变DOM元素的样式,类也会导致浏览器渲染,因此也应该减少不必要的操作。
6.减少iframe
iframe需要消耗大量的时间,并阻塞下载,应该少用。
7.样式放在head中,脚本放在关闭标签</body>之前
样式放在head中,可以加快渲染,脚本放在关闭标签</body>之前可以加快下载速度,不免阻塞下载。
1. 批量增加Dom
尽量使用修改innerHTML的方式而不是用appendChild的方式; 因为使用innerHTML开销更小,速度更快,同时也更加内存安全.
有一点需要注意的是,用innerHTML方式添加时,一定不要在循环中使用 innerHTML += 的方式添加,这样反而会使速度减慢; 而是应该中间用array缓存起来,循环结束后调用 xx.innerHTML = array.join(‘’);的方式,或者至少保存到string中再插到innerHTML中.
针对用户列表一块采用这种方式优化后,加载速度提升一倍.
2. 单个增加Dom
这里是指要将新节点加载到一个内容不断变化的节点的情形,对于内容稳定的节点来说,随便怎么加都没有问题. 但是对于有动态内容的节点来说,为其添加子节点尽量使用 dom append的方式.
这是因为,dom append不会影响到其他的节点;而如果修改innerHTML属性的话,该父节点的所有子节点都会从dom树中剥离,再根据新的innerHTML值来重绘子节点dom树;所有注册到原来子节点的事件也会失效.
综上,如果在一个有动态内容的节点上 出现了 innerHTML += 的代码,就该考虑是否有问题了.
3. 创建Dom节点
用 createElement方式创建一个dom节点,有一个很重要的细节: 在执行完createElement代码之后,应该马上append到dom树中; 否则,如果在将这个孤立节点加载到dom树之前所做的赋值它的属性和innerHTML的操作都会引发该dom片段内存无法回收的问题. 这个不起眼细节,一旦遇到大量dom增删操作,就会引发内存的灾难.
4. 删除Dom节点
删除dom节点之前,一定要删除注册在该节点上的事件,不管是用observe方式还是用attachEvent方式注册的事件,否则将会产生无法回收的内存.
另,在removeChild和innerHTML=’’二者之间,尽量选择后者. 因为在sIEve(内存泄露监测工具)中监测的结果是用removeChild无法有效地释放dom节点.
5. 创建事件监听
现有的js库都采用observe方式来创建事件监听,其实现上隔离了dom对象和事件处理函数之间的循环引用,所以应该尽量采用这种方式来创建事件监听.
6. 监听动态元素
Dom 事件默认是向上冒泡的,发生在子节点中的事件,可以由父节点来处理. Event的 target/srcElement 仍是产生事件的最深层子节点. 这样,对于内容动态增加并且子节点都需要相同的事件处理函数的情况,可以把事件注册上提到父节点上,这样就不需要为每个子节点注册事件监听了.
同时,这样做也避免了产生无法回收的内存.即使是用Prototype的observe方式注册事件并在删除节点前调用stopObserving,也会产生出少量无法回收的内存,所以应该尽量少的为dom节点注册事件监听.
所以,当代码中出现在循环里注册事件时,也是我们该考虑事件上提机制的时候了.
JS对DOM的操作优化法则的更多相关文章
- 高效率http页面优化法则一【JS对DOM的操作】
高效http页面优化法则一很多人都认为JS的效率太慢了,都不愿意用js来实现相对困难一点的程序逻辑.在这里我要说的是其实js的效率并不慢,慢的是DOM,如果操作好DOM,你的js效率将提高接近千倍(这 ...
- 原生JS的DOM节点操作
DOM(Document Object Model/文档对象模型)是针对HTML和XML文档的一个API.DOM节点树:在文档中出现的空格.回车.标签.注释.文本.doctype.标签等都属于DOM节 ...
- Js 对Dom的操作
一.DOM的概述 DOM(Document Object Model,文档对象模型)描绘了一个层次化的节点树,允许开发人员添加.移除和修改页面的某一部分.这使得JavaScript操作HTML,不是在 ...
- js的DOM节点操作:创建 ,插入,删除,复制,查找节点
DOM含义:DOM是文档对象模型(Document Object Model,是基于浏览器编程的一套API接口,是W3C出台的推荐标准.其赋予了JS操作节点的能力.当网页被加载时,浏览器就会创建页面的 ...
- JS对DOM节点操作整理
获取节点: //按照ID获取 document.getElementById('element'); //按照节点名称获取,返回类数组对象 document.getElementsByTagName( ...
- js之DOM直接操作
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Js:DOM对象操作常用的方法和属性
- 前端dom元素的操作优化建议
参考自:http://blog.csdn.net/xuexiaodong009/article/details/51810252 其实在web开发中,单纯因为js导致性能问题的很少,主要都是因为DOM ...
- js的dom操作(整理)(转)
js的dom操作整理(整理)(转) 一.总结 一句话总结: dom操作有用原生js的dom操作,也可以用对js封装过的jquery等插件来来更加方便的进行dom操作 1.dom是什么? 对于JavaS ...
随机推荐
- 你,确定了解Java的String字符串?
本文将描述JDK6中String.intern()是如何实现的,以及在JDK7和JDK8中对字符串池化技术做了哪些改变. String池化介绍 String池化就是把一些值相同,但是标识符不同的字符串 ...
- csp-s模拟测试59(10.4)「Reverse」(set)·「Silhouette」(容斥)
A. Reverse 菜鸡wwb又不会了..... 可以线段树优化建边,然而不会所以只能set水了 发现对于k和当前反转点固定的节点x确定奇偶性所到达的节点奇偶性是一定的 那么set维护奇偶点,然后每 ...
- 【题解】Luogu p2016 战略游戏 (最小点覆盖)
题目描述 Bob喜欢玩电脑游戏,特别是战略游戏.但是他经常无法找到快速玩过游戏的办法.现在他有个问题. 他要建立一个古城堡,城堡中的路形成一棵树.他要在这棵树的结点上放置最少数目的士兵,使得这些士兵能 ...
- 使用Spring Data JPA 访问 Mysql 数据库-配置项
jpa操作数据库 注意:数据库采用的是本机数据库,下面是建表语句及初始化数据: SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- ---------- ...
- Pandas高级教程之:category数据类型
目录 简介 创建category 使用Series创建 使用DF创建 创建控制 转换为原始类型 categories的操作 获取category的属性 重命名categories 使用add_cate ...
- 技术实践:教你用Python搭建gRPC服务
摘要:gRPC是一个高性能.通用的开源RPC框架,其由Google主要面向移动应用开发并基于HTTP/2协议标准而设计,基于ProtoBuf序列化协议开发,且支持众多开发语言. 本文分享自华为云社区& ...
- 8、linux常用命令
8.1.pwd: 显示当前的路径: -L:显示逻辑路径,即快捷方式的路径(默认的参数): -P :显示物理路径,真实的路径: 8.2.man: 命令的查看: 8.3.help: 命令的查看: 8.4. ...
- HDU 4821 2013长春现场赛hash
题意: 一个字符串S 问其中有几个子串能满足以下条件: 1.长度为M*L 2.可以被分成M个L长的小串 每个串都不一样 分析: hash方法,一个种子base,打表出nbase[i]表示base的 ...
- 如何获取微信小程序for循环的index
在微信小程序开发中,对于wx:for,可以使用wx:for-index="index"来获取数组中的元素的索引值(下标). <view class="item&qu ...
- centos 8.3安装 一键安装部署gitlab
安装和配置gitlab必须的依赖包 [root@gitlabdev ~]#dnf install -y curl policycoreutils openssh-server perl 设置开机自启s ...