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的操作优化法则的更多相关文章

  1. 高效率http页面优化法则一【JS对DOM的操作】

    高效http页面优化法则一很多人都认为JS的效率太慢了,都不愿意用js来实现相对困难一点的程序逻辑.在这里我要说的是其实js的效率并不慢,慢的是DOM,如果操作好DOM,你的js效率将提高接近千倍(这 ...

  2. 原生JS的DOM节点操作

    DOM(Document Object Model/文档对象模型)是针对HTML和XML文档的一个API.DOM节点树:在文档中出现的空格.回车.标签.注释.文本.doctype.标签等都属于DOM节 ...

  3. Js 对Dom的操作

    一.DOM的概述 DOM(Document Object Model,文档对象模型)描绘了一个层次化的节点树,允许开发人员添加.移除和修改页面的某一部分.这使得JavaScript操作HTML,不是在 ...

  4. js的DOM节点操作:创建 ,插入,删除,复制,查找节点

    DOM含义:DOM是文档对象模型(Document Object Model,是基于浏览器编程的一套API接口,是W3C出台的推荐标准.其赋予了JS操作节点的能力.当网页被加载时,浏览器就会创建页面的 ...

  5. JS对DOM节点操作整理

    获取节点: //按照ID获取 document.getElementById('element'); //按照节点名称获取,返回类数组对象 document.getElementsByTagName( ...

  6. js之DOM直接操作

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. Js:DOM对象操作常用的方法和属性

  8. 前端dom元素的操作优化建议

    参考自:http://blog.csdn.net/xuexiaodong009/article/details/51810252 其实在web开发中,单纯因为js导致性能问题的很少,主要都是因为DOM ...

  9. js的dom操作(整理)(转)

    js的dom操作整理(整理)(转) 一.总结 一句话总结: dom操作有用原生js的dom操作,也可以用对js封装过的jquery等插件来来更加方便的进行dom操作 1.dom是什么? 对于JavaS ...

随机推荐

  1. JAVA微服务应用(1)--SpringBoot中的REST API调用(学习笔记)

    好长时间没有写学习小结了,最近宁正好看了小马哥的微服务系列之<Spring Boot>系列,颇有收获,并且公司也布置一个课题就是关于Spring中的REST API调用.于是乎回归本行,再 ...

  2. k8s-nginx二进制报Illegal instruction (core dumped)

    1.环境 系统:CentOS 7.3 内核:x86 环境:虚拟机 2.问题 收到一个现场问题,k8s环境中nginx的pod都启动异常. #kubectl get pod |grep nginx ng ...

  3. Map类型的Json格式

    示例代码: Map<String, Object> map = new HashMap<>();// boolean 类型 map.put("boolean" ...

  4. C# 位图BitArray 小试牛刀

    前面聊了布隆过滤器,回归认识一下位图BitMap,阅读前文的同学应该发现了布隆过滤器本身就是基于位图,是位图的一种改进. 位图 先看一个问题, 假如有1千万个整数,整数范围在1到1亿之间,如何快速确定 ...

  5. MySQL密码复杂度策略

    前言 MySQL5.6.6版本之后增加了密码强度验证插件validate_password,相关参数设置的较为严格.使用了该插件会检查设置的密码是否符合当前设置的强度规则,若不满足则拒绝设置. 本文采 ...

  6. Vue前端基础学习

    vue-cli vue-cli 官方提供的一个脚手架(预先定义好的目录结构及基础代码,咱们在创建Maven项目的时可以选择创建一个骨架项目,这个骨架项目就是脚手架),用于快速生成一个vue项目模板 主 ...

  7. JDK8安装包的下载安装方式以及环境变量的配置

    前面我们介绍了 <Java是什么?>.<OracleJDK是什么?OracleJDK的版本怎么选择?>.<OpenJDK是什么?>以及<OracleJDK 与 ...

  8. Java核心基础第3篇-Java流程控制

    Java流程控制 本章一起来探讨下Java的流程控制语句.主要从以下几个方面展开: Java分支语句 Java循环语句 Java其实和其他任何的开发语言一样,分支语句和循环语句是必不可少的,有个这两个 ...

  9. XCTF csaw2013reversing2

    题目描述:听说运行就能拿到Flag,不过菜鸡运行的结果不知道为什么是乱码 一.先运行看看. 果然乱码. 二.查壳 三.是pe文件,可以拖入od和ida进行动态和静态分析. 1.对主函数进行反编译一下. ...

  10. muggle_ocr 下载安装

    pip install -i https://pypi.tuna.tsinghua.edu.cn/simple muggle_ocr