[读书笔记]高性能js-DOM优化

本文深入探讨JavaScript性能优化的多种策略,包括减少DOM访问、优化HTML集合操作、改进样式修改方式及DOM批量更新,同时介绍了事件委托的应用,旨在帮助开发者提升网页应用的运行效率。

我们都知道,在js编程中,很大一部分是和DOM打交道。

DOM是和编程语言无关的一个东西,用来映射html文档的,DOM里面包含一些API。在浏览器中,这些API可以被js调用。但是DOM和ECMA又是不同的2个模块,它们之间的沟通需要跨模块。所以,访问DOM就会比较慢。天生的 。。。

慢就慢把,总能做一些优化吧。

 

 DOM访问和修改。

 

都说访问DOM耗性能,用循环访问更是如此。所以可以减少DOM访问来优化。

比如

for(var i=0;i<1000;i++){

document.getElementById('a').innerHTML+='a';

}

这段代码每次循环都访问了2次DOM,读取innerHTML一次,重写innerHTML里面的内容一次。超级耗性能啊。

改成

var  str='';

for(var i=0;i<1000;i++){

str+='a';

}

document.getElementById('a').innerHTML=str;

for循环的部分不涉及DOM访问,在最后的时候访问一次DOM,重写DOM,ok。

(以上是针对一个DOM元素的,下面要讲一堆DOM元素,也就是HTML集合,原理也一样,就是弄成局部变量)

 

html集合

 

用document.getElementsByTagName之类的dom方法获得的都是类数组。只有length属性和可以通过下标查询元素。没有原生数组的一些方法。

另外由于html集合是和html文档随时绑定的。所以每次需要html集合里面的内容,哪怕是length,都会重复查询html文档。这就造成了低效。。

 

1.缓存length属性,免得每次查询都要遍历HTML文档来获得length。(在没有增删节点的情况下)。

2 利用局部变量访问html集合:

var a=document.getElementByName('a');

var str='';

for(var i=0;i<1000;i++){

  str+=document.getElementByName('a')[i];

}

改成

var a=document.getElementByName('a');

var str='';

for(var i=0;i<1000;i++){

  str+=a[i];

}

 

3 元素节点的获取

一般用childnodes,但这个效率低,还或获得文字节点,这些我们一般用不到,还要写代码删去。麻烦。。。

建议用children属性,直接获得nodelist的元素节点,效率也高。IE6都支持啊。。

另外一些好的节点获取方法,支持性不是很好,就不写了。嘿嘿。

 

4选择器API

超好用的选择器api,document.querySelectorAll('#a .a');

获得的是non-live的nodelist,也就是不是时时链接html文档的。不用担心访问DOM的性能啦。并且这个API比传统的一些获取DOM集合的方法速度快,还有代码短啊,就一句。棒!檫,别忘了做兼容,这个IE8以下不行。。。

 

重排和重绘

 

页面下载完所有的文件之后,(包括html,css,js,img等等),开始绘制2棵树了。一棵是DOM树,另一棵是渲染树。

DOM树就是把html的文档结构映射到一棵树上。(好像是废话)。。。

渲染树用来表示dom怎么在浏览器中显示。

所有的DOM节点都在渲染树中有自己的位置(除了隐藏的节点外)。渲染树中的节点可以看成是一个box。

 

当这2棵树弄好了之后,浏览器就开始绘制啦(painting过程)

但绘制过程并非这么顺利。有时候突然改变了元素的box,比如宽度啊高度啊,这就影响了另外的DOM元素,浏览器就会找出受影响的部分,重新构造渲染树,这个过程就叫重排(reflow回流)。重排完成后,就会进行重绘(repaint)的过程了。

 

重排会发生在很多情况,比如宽高的改变(渲染树重构),增加元素(DOM树和渲染树都重构了),增加滚动条(整个页面都被重排了)。

 

所以我们要尽可能减少重排和重绘

 

有什么方法呢?

 

1 用cssText改变样式。

一般我们改变元素样式都是直接

var ul=document.getElementById('ul');

ul.style.margin=1px;

ul.style.padding=10px;

这样会访问DOM2次,触发2次重排,改成ul.style.cssText='margin:1px;padding:10px'访问一次DOM解决事情了!

//可以缓存ul在ECMA端。读的时候可以在ECMA读,但是写数据的时候还是要访问DOM。

 

2 批量修改DOM

当批量修改DOM的时候,若用传统的方法,每次都会发生重排,但可以通过以下步骤减少重排。

1 元素脱离文档。

2 改变元素。

3 元素添加会文档。

怎么让元素脱离文档呢?有3种方法

1 先隐藏元素,修改完再显示。

2 使用文档碎片。(document fragment)

3 先创建一个文档元素的备份,修改备份,再添加会文档中

 

1的栗子

var ul=document.getElementById('ul');
ul.style.display='none';
ul.appendChild(li);
ul.style.display='block';

2的栗子

var ul = document.getElementsByTagName("ul")[0]; // assuming it exists
var docfrag = document.createDocumentFragment();
var browserList = ["Internet Explorer", "Mozilla Firefox", "Safari", "Chrome", "Opera"];

browserList.forEach(function(e) {
    var li = document.createElement("li");
    li.textContent = e;
    docfrag.appendChild(li);
});

ul.appendChild(docfrag);

3的栗子

var old=document.getElementById('ul');
var clone=document.cloneNode(true);
clone.appendChild(li);
old.parentNode.replaceChild(clone,old);

一般采用第二种方法优化会比较好。

 

事件委托

 

说白了就是直接在父元素上绑定一个事件,其他事件都冒泡到父元素处理。这样子元素就不用绑定事件,程序运行更快了。




 

转载于:https://www.cnblogs.com/wz0107/p/4947027.html

数据集介绍:垃圾分类检测数据集 一、基础信息 数据集名称:垃圾分类检测数据集 图片数量: 训练集:2,817张图片 验证集:621张图片 测试集:317张图片 总计:3,755张图片 分类类别: - 金属:常见的金属垃圾材料。 - 纸板:纸板类垃圾,如包装盒等。 - 塑料:塑料类垃圾,如瓶子、容器等。 标注格式: YOLO格式,包含边界框和类别标签,适用于目标检测任务。 数据格式:图片来源于实际场景,格式为常见图像格式(如JPEG/PNG)。 二、适用场景 智能垃圾回收系统开发: 数据集支持目标检测任务,帮助构建能够自动识别和分类垃圾材料的AI模型,用于自动化废物分类和回收系统。 环境监测与废物管理: 集成至监控系统或机器人中,实时检测垃圾并分类,提升废物处理效率和环保水平。 学术研究与教育: 支持计算机视觉与环保领域的交叉研究,用于教学、实验和论文发表。 三、数据集优势 类别覆盖全面: 包含三种常见垃圾材料类别,覆盖日常生活中主要的可回收物类型,具有实际应用价值。 标注精准可靠: 采用YOLO标注格式,边界框定位精确,类别标签准确,便于模型直接训练和使用。 数据量适中合理: 训练集、验证集和测试集分布均衡,提供足够样本用于模型学习和评估。 任务适配性强: 标注兼容主流深度学习框架(如YOLO等),可直接用于目标检测任务,支持垃圾检测相关应用。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值