码迷,mamicode.com
首页 > Web开发 > 详细

js性能的进阶

时间:2018-10-31 21:43:10      阅读:223      评论:0      收藏:0      [点我收藏+]

标签:列表   很多   OLE   性能   alt   back   attribute   提高   ack   

    为了说明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性能的进阶

标签:列表   很多   OLE   性能   alt   back   attribute   提高   ack   

原文地址:https://www.cnblogs.com/wanshun/p/9886011.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!