js性能的进阶
为了说明js性能方面的差异用一个简单的例子说明下,
<style>
#ul1{
padding: 5px;
overflow: hidden;
}
#ul1 li{
list-style: none;
width: 15px;
height: 15px;
border-radius: 50%;
background: #ccc;
margin: 3px;
float: left;
cursor: pointer;
}
#ul1 .active{
background: red;
}
</style>
<ul id="ul1">
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
...
</ul>
这样一个很简单的列表。做成一个单选效果,给被点击的li添加一个active的class。
实现的发方法有很多种,我介绍4中,为了能清楚看到性能之间的差异,li元素我复制了2000个。
第一种方法,也是最不可取,性能也是最浪费的一种
console.time("time1");
$("#ul1 li").click(function(event) {
console.time("time2");
$("#ul1 li").removeClass('active');
$(this).addClass('active');
console.timeEnd("time2");
});
console.timeEnd("time1");
这方法可能是初学者最易用到的,他的性能如下

首次事件绑定用了11ms ,之后每次点击0.6ms左右,前几次用的时间比较多。
第二种方案
console.time("time1");
var arrli = $("#ul1 li");
arrli.click(function(event) {
console.time("time2");
arrli.removeClass('active');
$(this).addClass('active');
console.timeEnd("time2");
});
console.timeEnd("time1");

相对第一种情况首次花费时间多了,每次点击花费时间少了,这次把jquery dom做了缓存没有每次都进行dom选择
第三种方案,这种代码量比较多,采用了dom缓存,和虚拟dom的概念。避免没有必要的直接操作dom
同时为了提高性避开使用query的选择器
console.time("time1");
var arrli = [];
var lilist = document.querySelectorAll("#ul1 li");
for(var i=0,len=lilist.length;i<len;i++){
var jsn = {};
jsn._active = false;//代表该元素的选中状态[虚拟dom的概念]
jsn.dom = $(lilist[i]);//把源生对象转为query对象
arrli.push(jsn);
lilist[i].setAttribute("index",i);//添加一个数组中索引的属性
lilist[i].onclick = function(){
console.time("time2");
var index = this.getAttribute("index")*1;
for(var i=0,len=arrli.length;i<len;i++){
if(i === index){
//只有在没有选中的时候进行选中设置
if(!arrli[i]._active){
arrli[i]._active = true;
arrli[i].dom.addClass('active');
};
}else{
if(arrli[i]._active){
arrli[i]._active = false;
arrli[i].dom.removeClass('active');
};
};
};
console.timeEnd("time2");
};
};
console.timeEnd("time1");
看性能

首次耗时4.6ms,使用原生的选择器快了很多。每次点击最多的一次耗时也是0.1ms,所以相对前两种方案性能提高了很多。
第四种方案
基于第三种方案,每次点击的时候会循环下,这种方案避开这种循环
console.time("time1");
var arrli = [];
var lilist = document.querySelectorAll("#ul1 li");
var old = false;
for(var i=0,len=lilist.length;i<len;i++){
var jsn = {};
jsn._active = false;//代表该元素的选中状态[虚拟dom的概念]
jsn.dom = $(lilist[i]);//把源生对象转为query对象
arrli.push(jsn);
lilist[i].setAttribute("index",i);//添加一个数组中索引的属性
lilist[i].onclick = function(){
console.time("time2");
var index = this.getAttribute("index")*1;
//这个方案不需要循环
if(old){
old._active = false;
old.dom.removeClass('active');
};
if(!arrli[index]._active){
arrli[index]._active = true;
arrli[index].dom.addClass('active');
old = arrli[index];
};
console.timeEnd("time2");
};
};
console.timeEnd("time1");
性能

相对第三种代码改变并不多,性能方面每次点击所花费的时间有所提高,缺点是后两种增加了代码量
js性能的进阶的更多相关文章
- js性能优化-事件委托
js性能优化-事件委托 考虑一个列表,在li的数量非常少的时候,为每一个li添加事件侦听当然不会存在太多性能方面的问题,但是当列表非常的长,长到上百上千甚至上万的时候(当然只是一个解释,实际工作中很少 ...
- 客户端JS性能的一些优化的小技巧
下面是一些关于客户端JS性能的一些优化的小技巧:1.[顶]关于JS的循环,循环是一种常用的流程控制.JS提供了三种循环:for(;;). while().for(in).在这三种循环中 for(in) ...
- js 性能基准测试工具-告别可能、也许、大概这样更快更省
平时写js经常遇到这样做是不是更快点?但又没有具体简单可测试的工具,最近也倒序看博客园司徒正美 js分类下的文章 [ps:去年灵光一闪,发现看博客园排名前100的博客.按照文章分类倒序看是学习最快的方 ...
- 你不知道的Node.js性能优化,读了之后水平直线上升
本文由云+社区发表 "当我第一次知道要这篇文章的时候,其实我是拒绝的,因为我觉得,你不能叫我写马上就写,我要有干货才行,写一些老生常谈的然后加上好多特技,那个 Node.js 性能啊好像 D ...
- js 性能优化利器:prepack
1. js 性能优化 js 本身是没有像 python 一样的预编译功能,更没有像 java 一样的编译功能,所以,这里所说的 js 代码预编译 只是通过工具实现的类似功能而已. 这就要提到 prep ...
- 免费的 Vue.js 入门与进阶视频教程
这是我免费发布的高质量超清「Vue.js 入门与进阶视频教程」. 全网最好的.免费的 Vue.js 视频教程,课程基于 Vue.js 2.0,由浅入深,最后结合实际的项目进行了最棒的技术点讲解,此课程 ...
- js 性能优化 篇一
JS性能优化 摘自:http://www.china125.com/design/js/3631.htm 首先,由于JS是一种解释型语言,执行速度要比编译型语言慢得多.(注:,Chrome是第一款内 ...
- js性能优化文章集锦
总结的js性能优化方面的小知识http://www.it165.net/pro/html/201503/35336.html 如何优化你的JS代码http://www.php100.com/html/ ...
- js性能优化--学习笔记
<高性能网站建设进阶指南>: 1.使用局部变量,避免深入作用域查找,局部变量是读写速度最快的:把函数中使用次数超过一次的对象属性和数组存储为局部变量是一个好方法:比如for循环中的.len ...
随机推荐
- 【很好的分享】zookeeper系列
http://blog.csdn.net/tswisdom/article/details/41522069
- 使用apidoc生成项目文档
[1]npm install apidoc -g 全局安装apidoc [2]apidoc -v 查看是否安装成功 [3]apidoc.json apidoc的项目级配置文件,它必须位于整个工程目录顶 ...
- Linux-Jenkins安装部署
Jenkins 安装及插件安装 Jenkins简介: Jenkins只是一个平台,真正运作的都是插件.这就是jenkins流行的原因,因为jenkins什么插件都有 Hudson是Jenkins的前身 ...
- Day053--MySQL
MySQL安装和基本管理https://www.cnblogs.com/majj/p/9160383.html 管理员模式运行cmd 打开终端,输入mysqld,打开服务端. 打开终端,输入mysql ...
- 在IntelliJ IDEA中,注解@Slf4j找不到log
问题: 解决方法:
- 010-3 Socket协议ProtocolType
ProtocolType成员 成员名称 说明 Ggp 网关到网关协议. Icmp Internet 控制消息协议. IcmpV6 IPv6 的 Internet 控制消息协议. Idp Interne ...
- 如何安装 PhoneGap / Cordova (for Win10)
最近需要配置 PhoneGap / Cordova 环境,折腾了一阵子,写篇博客 Mark 一下整个过程. 具体参照了:http://www.assortedgarbage.com/apigee/ 以 ...
- JN_0007:微信昵称设置小数字
请复制下面背景色里面的数字符号 上标: ℡º ¹ ² ³ ⁴ ⁵ ⁶ ⁷ ⁸ ⁹ ⁺ ⁻ ⁼ ⁽ ⁾ ⁿ ′ ½ 下标: ℡.₀ ₁ ₂ ₃ ₄ ₅ ₆ ₇ ₈ ₉ ₊ ₋ ₌ ₍ ₎ 复制上面那串数 ...
- 为什么单片机中既有Flash又有EEPROM
单片机运行时的数据都存在于RAM(随机存储器)中,在掉电后RAM 中的数据是无法保留的,那么怎样使数据在掉电后不丢失呢?这就需要使用EEPROM 或FLASHROM 等存储器来实现. 插播一段:ROM ...
- Linux_解决启动网卡失败 Device eth0 does not seem to be present
Linux_解决启动网卡失败 Device eth0 does not seem to be present 虚拟机克隆 发现service network restart 启动失败 故障现象: ...