返回顶部
首页 > 资讯 > 前端开发 > html >jQuery优化失败的示例分析
  • 578
分享到

jQuery优化失败的示例分析

2024-04-02 19:04:59 578人浏览 安东尼
摘要

本篇文章给大家分享的是有关Jquery优化失败的示例分析,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。我经常抱怨jQuery的DOM操作性能并

本篇文章给大家分享的是有关Jquery优化失败的示例分析,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。

我经常抱怨jQuery的DOM操作性能并不优秀,并且经常尝试用一些方法去进行优化,但是越是优化,越是沮丧地发现jQuery其实已经做得很好,从使用者的角度能够进行的优化实在有限(这并不意味着jQuery的性能是优秀的, 反之只能说它是一个相对封闭的库,无法从外部介入进行优化)。这篇文章就记录一次失败的优化经历。

优化思想

这一次优化的思想来自于数据库。在数据库优化的时候,我们常会说将大量的操作放在一个事务中一起提交,能有效提高效率。虽然对数据库不了解的我并不知道其原因,但是事务的思想却为我指明了方向(虽然是错的)。

因此我尝试将事务这一概念引入到jQuery中,通过打开和提交事务,从外部对jQuery进行一些优化,其最重要的在于减少each函数的循环次数。

众所周知,jQuery的DOM操作,以get all, set first为标准,其中用于设置DOM属性/样式的操作,几乎都是对选择出来的元素的一次遍历,jQuery.access函数就是其中最核心的部分,其中用于循环的代码如下:

// Setting one attribute  if ( value !== undefined ) {      // Optionally, function values get executed if exec is true      exec = !pass  exec  jQuery.isFunction(value);   for ( var i = 0; i  length; i++ ) {  fn(  elems[i],  key,  exec ? value.call(elems[i], i, fn(elems[i], key)) : value,  pass  );  }  return elems;

比如jQuery.fn.CSS函数就是这样的:

jQuery.fn.css = function( name, value ) {      // Setting 'undefined' is a no-op      if ( arguments.length === 2  value === undefined ) {          return this;      }   return jQuery.access( this, name, value, true, function( elem, name, value ) {  return value !== undefined ?  jQuery.style( elem, name, value ) :  jQuery.css( elem, name );  });  };

因此,下面这样的代码,假设被选择的div元素有5000个,则要循环访问10000个节点:

jQuery('div').css('height', 300).css('width', 200);

而在我的想法中,在一个事务中,可以如数据库的操作一般,通过保存所有的操作,在提交事务的时候统一进行,将10000次节点访问,减少至5000次,相当于提升了1倍的性能。

简单实现

事务式的jQuery操作中,提供2个函数:

 ◆  begin:打开一个事务,返回一个事务的对象。该对象拥有jQuery的所有函数,但是调用函数并不会立刻生效,只有在提交事务后才会生效。

 ◆ commit:提交一个事务,保证所有事先调用过的函数都生效,交返回原本的jQuery对象。

实现起来也很方便:

 ◆ 创建一个事务对象,复制jQuery.fn上所有函数到该对象中。

 ◆ 当调用某个函数时,在预先准备好的队列中添加调用的函数名和相关参数。

 ◆ 当提交事务时,对被选择的元素进行一次遍历,对遍历中的每个节点应用队列中的所有函数。

简单地代码如下:

var slice = Array.prototype.slice;  jQuery.fn.begin = function() {      var proxy = {              _core: c,              _queue: []          },          key,          func;      //复制jQuery.fn上的函数      for (key in jQuery.fn) {          func = jQuery.fn[key];          if (typeof func == 'function') {              //这里会因为for循环产生key始终是***一个循环值的问题              //因此必须使用一个闭包保证key的有效性(LIFT效应)              (function(key) {                  proxy[key] = function() {                      //将函数调用放到队列中                      this._queue.push([key, slice.call(arguments, 0)]);                      return this;                  };              })(key);          }      }      //避免commit函数也被拦截      proxy.commit = jQuery.fn.commit;      return proxy;  };   jQuery.fn.commit = function() {  var core = this._core,  queue = this._queue;  //仅一个each循环  core.each(function() {  var i = 0,  item,  jq = jQuery(this);  //调用所有函数  for (; item = queue[i]; i++) {  jq[item[0]].apply(jq, item[1]);  }  });  return this.c;  };

测试环境

测试使用以下条件:

 ◆ 5000个div放在一个容器(div id="container"/div)中。

 ◆使用$(#containerdiv)选择这5000个div。

 ◆每个div要求设置一个随机背景色(randomColor函数),和800px以下的随机宽度(randomWidth函数)。

参加测试的调用方法有3个:

 ◆正常使用法:

$('#containerdiv')      .css('background-color', randomColor)      .css('width', randomWidth);

 ◆单次循环法:

$('#containerdiv').each(function() {      $(this).css('background-color', randomColor).css('width', randomWidth);  });

 ◆事务法:

$('#containerdiv')      .begin()          .css('background-color', randomColor)          .css('width', randomWidth)      .commit();

 ◆对象赋值法:

$('#containerdiv').css({      'background-color': randomColor,      'width': randomWidth  });

测试浏览器选择Chrome 8系列(用IE测就直接挂了)。

悲伤的结果

原本的预测结果是,单次循环法的效率远高于正常使用法,同时事务法虽然比单次循环法慢一些,但应该比正常使用法更快,而对象赋值法其实是jQuery内部支持的单次循环法,效率应该是***的。

然而遗憾的是,结果如下:

正常使用法单次循环法事务法对象赋值法
18435ms18233ms18918ms17748ms

从结果上看,事务法成了最慢的一种方法。同时单次循环与正常使用并没有明显的优势,甚至依赖jQuery内部实现的对象赋值法也没有拉开很大的差距。

由于5000个元素的操作已经是非常庞大的循环,如此庞大的循环也没能拉开性能的差距,平时最常用的10个左右的元素操作更不可能有明显的优势,甚至还可能将劣势扩大化。

究其原因,由于本身单次循环法就没有明显的性能提升,因此依赖于单次循环,并是在单次循环之上进行外部构建的事务法,自然是在单次循环的基础上还需要额外增加创建事务对象、保存函数队列、遍历函数队列等开销,结果败给正常使用法也在情理之中。

至此,也算是可以宣布模仿事务的优化之道的失败。但是对这个结果却还能进一步地分析。

性能在哪里

首先,从代码的使用上来分析,将正常使用法和测试中最快的对象赋值法进行比较,可以说两者的差距仅在于循环的元素个数的不同(这里抛开了jQuery的内部问题,事实上jQuery.access的糟糕实现也确实有拖对象赋值法后腿之嫌,好在并不严重),正常使用法是10000个元素,对象赋值法是5000个元素。因此可以简单地认为,18435 17748 = 687ms是循环5000个元素的耗时,这占到整个执行过程的3.5%左右,并不是整个执行过程的主干,其实真的没有优化的必要。

那么另外96.5%的开销去了哪里呢?谨记Doglas的一句话,事实上javascript并不慢,慢的是DOM的操作。其实剩下96.5%的开销中,除去函数调用等基本的消耗,至少有95%的时间是用在了DOM元素的样式被改变后的重新渲染之上。

发现了这个事实之后,其实也就有了更正确的优化方向,也是前端性能中的基本原则之一:在修改大量子元素时,先将根父DOM节点移出DOM树。因此如果使用以下的代码再进行测试:

//没有重用$('#container')已经很糟糕了  $('#container').detach().find('div')      .css('background-color', randomColor)      .css('width', randomWidth);  $('#container').appendTo(document.body);

测试结果始终停留在900ms左右,与前面的数据完全不在一个数量级之上,真正的优化成功。

教训和总结

 ◆千万要找到正确的性能瓶颈再进行优化,盲目的猜测只会导致走上错误而偏激的道路。

 ◆ 数据说话,数据面前谁也别说话!

 ◆不认为事务这个方向是错误的,如果jQuery原生就能支持事务这样的概念,会不会有其他的点可以优化?比如一个事务自动会将父元素脱离出DOM树之类的

以上就是jQuery优化失败的示例分析,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注编程网html频道。

--结束END--

本文标题: jQuery优化失败的示例分析

本文链接: https://lsjlt.com/news/85007.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • jQuery优化失败的示例分析
    本篇文章给大家分享的是有关jQuery优化失败的示例分析,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。我经常抱怨jQuery的DOM操作性能并...
    99+
    2024-04-02
  • workstation-001-snapshot失败的示例分析
    这篇文章的内容主要围绕workstation-001-snapshot失败的示例分析进行讲述,文章内容清晰易懂,条理清晰,非常适合新手学习,值得大家去阅读。感兴趣的朋友可以跟随小编一起阅读吧。希望大家通过这篇文章有所收获!虚拟机运行提示“锁...
    99+
    2023-06-04
  • jQuery基本事件代码优化的示例分析
    这篇文章主要介绍了jQuery基本事件代码优化的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。事件模型说到事件,就要追溯到网景与微软...
    99+
    2024-04-02
  • jQuery图片加载失败替换默认图片的示例分析
    这篇文章将为大家详细讲解有关jQuery图片加载失败替换默认图片的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。重点来了:一定要记住error事件不冒泡。相关的知...
    99+
    2024-04-02
  • Java集合快速失败与安全失败的示例分析
    这篇文章主要介绍了Java集合快速失败与安全失败的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。正文fail-fast与fail-safefail-fast快速失败机...
    99+
    2023-06-25
  • Mysql优化之Zabbix分区优化的示例分析
    这篇文章主要介绍了Mysql优化之Zabbix分区优化的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。使用zabbix最大的瓶颈在于...
    99+
    2024-04-02
  • mysql hint优化的示例分析
    这篇文章将为大家详细讲解有关mysql hint优化的示例分析,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。SELECT t.oldcontract...
    99+
    2024-04-02
  • Oracle优化器的示例分析
    这篇文章主要介绍Oracle优化器的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!一、优化器的模式      优化器的模式用...
    99+
    2024-04-02
  • MySQL大表优化的示例分析
    小编给大家分享一下MySQL大表优化的示例分析,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!背景阿里云RDS FOR MySQL(MySQL5.7版本)数据库业务表每月新增数据量超过千万,...
    99+
    2024-04-02
  • MySQL查询优化的示例分析
    小编给大家分享一下MySQL查询优化的示例分析,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!一、优化的思路和原则有哪些1、 优化更需要优化的查询 2、 定位优化对象的性能瓶颈 3、 明确优...
    99+
    2024-04-02
  • Mysql优化策略的示例分析
    这篇文章主要介绍Mysql优化策略的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!总的来说:1、数据库设计和表创建时就要考虑性能2、sql的编写需要注意优化3、分区、分表、分...
    99+
    2024-04-02
  • mysql中limit优化的示例分析
    小编给大家分享一下mysql中limit优化的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!    ...
    99+
    2024-04-02
  • my.ini与mysql优化的示例分析
    小编给大家分享一下my.ini与mysql优化的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!mysql优化了所以先说说...
    99+
    2024-04-02
  • MySQL中table_cache优化的示例分析
    这篇文章主要介绍MySQL中table_cache优化的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!table_cache指定表高速缓存的大小。每当MySQL访问一个表时,...
    99+
    2024-04-02
  • PHP代码优化的示例分析
    这篇文章主要介绍了PHP代码优化的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。一小段“劣质”的PHP代码优化的过程,请仔细体会优化...
    99+
    2024-04-02
  • Webpack4 Tree Shaking优化的示例分析
    这篇文章将为大家详细讲解有关Webpack4 Tree Shaking优化的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。先说好处在讨论技术细节之前,让我先总结一...
    99+
    2024-04-02
  • Filebeat优化实践的示例分析
    本篇文章给大家分享的是有关Filebeat优化实践的示例分析,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。Filebeat优化实践背景介绍目前比较主流的日志采集系统有ELK(E...
    99+
    2023-06-19
  • SEO优化技术的示例分析
    这篇文章给大家分享的是有关SEO优化技术的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。如何设置SEO关键词当然重要,但SEO优化技术如果只是机械式的说该做什麽不做什麽,而涉及的步骤又非常死板,例如:将焦...
    99+
    2023-06-10
  • SEO标题优化的示例分析
    这篇文章主要介绍了SEO标题优化的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。1、尽量要包含公司名称您所在的公司名称,不止能够将你的结果列表与竞争对手区分开来,与此...
    99+
    2023-06-10
  • Mysql容器启动失败恢复的示例分析
    这篇文章主要介绍了Mysql容器启动失败恢复的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。 Mysql...
    99+
    2024-04-02
软考高级职称资格查询
推荐阅读
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作