DOM操作的真正问题在于 每次操作都会出发布局的改变、DOM树的修改和渲染。

React解决了大面积的DOM操作的性能问题,实现了一个虚拟DOM,即virtual DOM,这个我们一条条讲。

所以关于DOM操作的性能优化主要包括:

1.查找元素的优化

2.尽量避免或减少改变DOM(比如添加,修改,删除DOM)

3.减少改变DOM的样式类

4.批量修改DOM

5.减少Iframe

6.样式放在header中,脚本放在关闭标签</body>之前

7.就是我刚才所说的大名鼎鼎的Virtual DOM

1.查找元素的优化

查找元素尽量使用ID,因为ID是唯一的,查找起来也是最快的。其次是根据类和类型查找元素,通过属性查找元素是最慢的。

2.尽量避免或减少改变DOM(比如添加,修改,删除DOM)

改变DOM就会引起浏览器渲染,而且渲染是相当慢的,应米面不必要的渲染

例如:

divUpdate.innerHTML = "";
for ( var i=0; i<100; i++ )
{
divUpdate.innerHTML += "<SPAN>This is a slower method! </SPAN>";
}

改为

var str="";
for ( var i=0; i<100; i++ )
{
str += "<SPAN>This is faster because it uses a string! </SPAN>";
}
divUpdate.innerHTML = str;

3.减少改变DOM的样式类

 改变DOM元素的样式,类也会导致浏览器渲染,因此也应该减少不必要的操作

例如:

 var el = document.getElementById('mydiv');
el.style.borderLeft = '1px';
el.style.borderRight = '2px';
el.style.padding = '5px';

改为:

var el = document.getElementById('mydiv');
l.style.cssText = 'border-left: 1px; border-right: 2px; padding: 5px;';

4.批量修改DOM

从文档流中先摘除该元素,对其应用多重改变,再将元素带回文档中,这样可以最小化重绘和重排。

具体方法:

1、隐藏元素,集中修改,然后再显示它

2、讲原始元素拷贝到一个脱离文档流的结点中,修改副本,然后覆盖原始元素

5.减少Iframe

iframe需要消耗大量的时间,并阻塞下载,建议少用

据说动态地给iframe添加url可以改善性能,未做测试

6.样式放在header中,脚本放在关闭标签</body>之前

样式放在header中,可以加快渲染,脚本放在关闭标签</body>之前可以加快下载速度,避免阻塞下载。

7.大名鼎鼎的Virtual DOM

Virtual DOM的核心思想是:批量操作DOM和作用最少的diff

你一个接一个地去修改30个节点的时候,就会引起30次(潜在的)布局重算,30次(潜在的)重绘,等等。

之后,一旦你要把这些改动传递给真实DOM,之前所有的改动就会整合成一次DOM操作。这一次DOM操作引起的布局计算和重绘可能会更大,但是相比而言,整合起来的改动只做一次,减少了(多次)计算。

这就是所谓的Virtual DOM算法,包括几个步骤:

1.用javascript对象结构表示DOM树的结构,然后用这个树构建一个真正的DOM树,插入到文档流中

2.当文档变更时,重新构造一颗新的对象树,然后用新的对象树和旧的对象树对比,记录两棵树的差异

3.把2所记录的差异应用到1所构建的真正的DOM树上,就实现变更了

Virtual DOM本质上就是在JS和DOM之间做了一个缓存。可以类比CPU和硬盘,既然硬盘这么慢,我们就在他们之间加一个缓存。既然JS这么慢,我们就在JS和DOM之间加一个缓存。CPU只操作内存,最后把变更写入硬盘。JS只操作Virtual DOM,最后把变更写入DOM。

其思想的关键是:

1.相对于 DOM 对象,原生的JS对象处理起来更快更简单。

2.比较两棵DOM树的差异是 Virtual DOM算法最核心的部分,这也是所谓的Vritual DOM的diff算法。

为什么快很多?

当然如果真的这样大面积的操作 DOM,性能会是一个很大的问题,所以 React 实现了一个虚拟 DOM,组件 DOM 结构就是映射到这个虚拟 DOM 上,React 在这个虚拟 DOM 上实现了一个 diff 算法,当要更新组件的时候,会通过 diff 寻找到要变更的 DOM 节点,再把这个修改更新到浏览器实际的 DOM 节点上,所以实际上不是真的渲染整个 DOM 树。这个虚拟 DOM 是一个纯粹的 JS 数据结构,所以性能会比原生 DOM 快很多

DOM操作的性能优化的更多相关文章

  1. 关于DOM操作的性能优化

    最著名的有关用js操作dom的观点是:js和dom是独立的小岛,用桥实现两者的联系,但桥很窄,要过路费,所以我们要尽最大可能减少过桥的次数.下面代码演示了用js操作dom的innerHTML,且一下修 ...

  2. 前端性能优化--为什么DOM操作慢? 浅谈DOM的操作以及性能优化问题-重绘重排 为什么要减少DOM操作 为什么要减少操作DOM

    前端性能优化--为什么DOM操作慢?   作为一个前端,不能不考虑性能问题.对于大多数前端来说,性能优化的方法可能包括以下这些: 减少HTTP请求(合并css.js,雪碧图/base64图片) 压缩( ...

  3. DOM操作的性能问题

    造成DOM操作性能差的原因:1.DOM操作的实现和ECMAscript的实现是两个独立的部分,之间通过接口来完成相应的DOM操作. 2.实时查询文档得到HTML集合,重复执行查询操作.特别是lengt ...

  4. 关于DOM的操作以及性能优化问题-重绘重排

     写在前面: 大家都知道DOM的操作很昂贵. 然后贵在什么地方呢? 一.访问DOM元素 二.修改DOM引起的重绘重排 一.访问DOM 像书上的比喻:把DOM和JavaScript(这里指ECMScri ...

  5. 学习 CLR 源码:连续内存块数据操作的性能优化

    目录 C# 原语类型 1,利用 Buffer 优化数组性能 2,BinaryPrimitives 细粒度操作字节数组 提高代码安全性 3,BitConverter.MemoryMarshal 4,Ma ...

  6. Attribute操作的性能优化方式

    Attribute是.NET平台上提供的一种元编程能力,可以通过标记的方式来修饰各种成员.无论是组件设计,语言之间互通,还是最普通的框架使 用,现在已经都离不开Attribute了.迫于Attribu ...

  7. 【redis常用的键值操作及性能优化】

    服务端 启动redis服务 { // -a:指定密码 -h:指定主机 -p:指定端口 } //让redis 服务中断崩溃 //保存和关闭 //后台备份 //设置登录密码 //redis-benchma ...

  8. 前端页面卡顿?或是DOM操作惹的祸,需优化代码

    文档对象模型(DOM)是一个独立 于特定语言的应用程序接口.在浏览器中,DOM接口是以JavaScript语言实现的,通过JavaScript来操作浏览器页面中的元素,这使得 DOM成为了JavaSc ...

  9. DOM操作优化

    文档对象模型(DOM)是一个独立 于特定语言的应用程序接口.在浏览器中,DOM接口是以JavaScript语言实现的,通过JavaScript来操作浏览器页面中的元素,这使得 DOM成为了JavaSc ...

随机推荐

  1. System performance tools

    System performance tools ============ End

  2. 配置UOJ数据的正确姿势

    最近瞎搞用开源UOJ搭了个OJ,在题目配置方面搞了挺久,一开始看vfleaking的文档还折腾了SVN,特意写下这篇文章为后来人少走弯路 Step 1 拥有管理权限并设置好题面,支持\(LaTex\) ...

  3. luogu P5023 填数游戏

    luogu loj 被这道题送退役了 题是挺有趣的,然而可能讨论比较麻烦,肝了2h 又自闭了,鉴于CSP在即,就只能先写个打表题解了 下面令\(n<m\),首先\(n=1\)时答案为\(2^m\ ...

  4. js之数据类型(对象类型——单体内置对象——Math)

    Math是一个内置对象,它具有数学常数和函数的属性和方法.Math对象用于执行数学任务,和其它对象不同,Math只是一个静态对象并没有Math()构造函数,实际上,Math()只是一个由js设置的对象 ...

  5. mysql启动失败“MySQL Daemon failed to start”

    CentOS上,用命令:service mysqld restart 启动mysql报错: # service mysqld restart Stopping mysqld: [ OK ] MySQL ...

  6. Shell中比较判断

    一.shell判断数组中是否包含某个元素:ary=(1 2 3)a=2if [[ "${ary[@]}" =~ "$a" ]] ; then    echo & ...

  7. HTML插入地图

    方法/步骤 1.打开“百度地图生成器”的网址:http://api.map.baidu.com/lbsapi/creatmap/index.html 如下图: 2.在“1.定位中心点”中,切换城市,并 ...

  8. 十:Razor语法

    1.Razor简介 不是一种代码语言,而是视图中使用的代码引擎. 它以简洁的类似客户端的语法结构,呈现网页服务端代码功能 它替代了ASPX页面的“<%...%>”代码块语法. 在编写时使用 ...

  9. Centos7.4安装RabbitMQ

    1.1 安装RabbitMQ 1.1.1 系统环境 [root@rabbitmq ~]# cat /etc/redhat-release CentOS Linux release 7.4.1708 ( ...

  10. 修改IDEA关闭标签页的快捷键

    IDEA原先关闭标签页的快捷键是Ctrl + F4 ,操作起来很不方便,而我们通常习惯于用 Ctrl + W 关闭浏览器的标签页,所以,也可以将关闭IDEA标签页的快捷键修改为Ctrl + W,具体步 ...