欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

jQuery優(yōu)化失敗的示例分析

本篇文章給大家分享的是有關(guān)jQuery優(yōu)化失敗的示例分析,小編覺得挺實用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

創(chuàng)新互聯(lián)是一家企業(yè)級云計算解決方案提供商,超15年IDC數(shù)據(jù)中心運營經(jīng)驗。主營GPU顯卡服務(wù)器,站群服務(wù)器,資陽主機托管,海外高防服務(wù)器,成都機柜租用,動態(tài)撥號VPS,海外云手機,海外云服務(wù)器,海外服務(wù)器租用托管等。

我經(jīng)常抱怨jQuery的DOM操作性能并不優(yōu)秀,并且經(jīng)常嘗試用一些方法去進(jìn)行優(yōu)化,但是越是優(yōu)化,越是沮喪地發(fā)現(xiàn)jQuery其實已經(jīng)做得很好,從使用者的角度能夠進(jìn)行的優(yōu)化實在有限(這并不意味著jQuery的性能是優(yōu)秀的, 反之只能說它是一個相對封閉的庫,無法從外部介入進(jìn)行優(yōu)化)。這篇文章就記錄一次失敗的優(yōu)化經(jīng)歷。

優(yōu)化思想

這一次優(yōu)化的思想來自于數(shù)據(jù)庫。在數(shù)據(jù)庫優(yōu)化的時候,我們常會說將大量的操作放在一個事務(wù)中一起提交,能有效提高效率。雖然對數(shù)據(jù)庫不了解的我并不知道其原因,但是事務(wù)的思想?yún)s為我指明了方向(雖然是錯的)。

因此我嘗試將事務(wù)這一概念引入到j(luò)Query中,通過打開和提交事務(wù),從外部對jQuery進(jìn)行一些優(yōu)化,其最重要的在于減少each函數(shù)的循環(huán)次數(shù)。

眾所周知,jQuery的DOM操作,以get all, set first為標(biāo)準(zhǔn),其中用于設(shè)置DOM屬性/樣式的操作,幾乎都是對選擇出來的元素的一次遍歷,jQuery.access函數(shù)就是其中最核心的部分,其中用于循環(huán)的代碼如下:

// 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函數(shù)就是這樣的:

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 );  });  };

因此,下面這樣的代碼,假設(shè)被選擇的div元素有5000個,則要循環(huán)訪問10000個節(jié)點:

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

而在我的想法中,在一個事務(wù)中,可以如數(shù)據(jù)庫的操作一般,通過保存所有的操作,在提交事務(wù)的時候統(tǒng)一進(jìn)行,將10000次節(jié)點訪問,減少至5000次,相當(dāng)于提升了1倍的性能。

簡單實現(xiàn)

事務(wù)式的jQuery操作中,提供2個函數(shù):

 ◆  begin:打開一個事務(wù),返回一個事務(wù)的對象。該對象擁有jQuery的所有函數(shù),但是調(diào)用函數(shù)并不會立刻生效,只有在提交事務(wù)后才會生效。

 ◆commit:提交一個事務(wù),保證所有事先調(diào)用過的函數(shù)都生效,交返回原本的jQuery對象。

實現(xiàn)起來也很方便:

 ◆創(chuàng)建一個事務(wù)對象,復(fù)制jQuery.fn上所有函數(shù)到該對象中。

 ◆ 當(dāng)調(diào)用某個函數(shù)時,在預(yù)先準(zhǔn)備好的隊列中添加調(diào)用的函數(shù)名和相關(guān)參數(shù)。

 ◆ 當(dāng)提交事務(wù)時,對被選擇的元素進(jìn)行一次遍歷,對遍歷中的每個節(jié)點應(yīng)用隊列中的所有函數(shù)。

簡單地代碼如下:

var slice = Array.prototype.slice;  jQuery.fn.begin = function() {      var proxy = {              _core: c,              _queue: []          },          key,          func;      //復(fù)制jQuery.fn上的函數(shù)      for (key in jQuery.fn) {          func = jQuery.fn[key];          if (typeof func == 'function') {              //這里會因為for循環(huán)產(chǎn)生key始終是***一個循環(huán)值的問題              //因此必須使用一個閉包保證key的有效性(LIFT效應(yīng))              (function(key) {                  proxy[key] = function() {                      //將函數(shù)調(diào)用放到隊列中                      this._queue.push([key, slice.call(arguments, 0)]);                      return this;                  };              })(key);          }      }      //避免commit函數(shù)也被攔截      proxy.commit = jQuery.fn.commit;      return proxy;  };   jQuery.fn.commit = function() {  var core = this._core,  queue = this._queue;  //僅一個each循環(huán)  core.each(function() {  var i = 0,  item,  jq = jQuery(this);  //調(diào)用所有函數(shù)  for (; item = queue[i]; i++) {  jq[item[0]].apply(jq, item[1]);  }  });  return this.c;  };

測試環(huán)境

測試使用以下條件:

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

 ◆使用$(#containerdiv)選擇這5000個div。

 ◆每個div要求設(shè)置一個隨機背景色(randomColor函數(shù)),和800px以下的隨機寬度(randomWidth函數(shù))。

參加測試的調(diào)用方法有3個:

 ◆正常使用法:

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

 ◆單次循環(huán)法:

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

 ◆事務(wù)法:

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

 ◆對象賦值法:

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

測試瀏覽器選擇Chrome 8系列(用IE測就直接掛了)。

悲傷的結(jié)果

原本的預(yù)測結(jié)果是,單次循環(huán)法的效率遠(yuǎn)高于正常使用法,同時事務(wù)法雖然比單次循環(huán)法慢一些,但應(yīng)該比正常使用法更快,而對象賦值法其實是jQuery內(nèi)部支持的單次循環(huán)法,效率應(yīng)該是***的。

然而遺憾的是,結(jié)果如下:

正常使用法單次循環(huán)法事務(wù)法對象賦值法
18435ms18233ms18918ms17748ms

從結(jié)果上看,事務(wù)法成了最慢的一種方法。同時單次循環(huán)與正常使用并沒有明顯的優(yōu)勢,甚至依賴jQuery內(nèi)部實現(xiàn)的對象賦值法也沒有拉開很大的差距。

由于5000個元素的操作已經(jīng)是非常龐大的循環(huán),如此龐大的循環(huán)也沒能拉開性能的差距,平時最常用的10個左右的元素操作更不可能有明顯的優(yōu)勢,甚至還可能將劣勢擴大化。

究其原因,由于本身單次循環(huán)法就沒有明顯的性能提升,因此依賴于單次循環(huán),并是在單次循環(huán)之上進(jìn)行外部構(gòu)建的事務(wù)法,自然是在單次循環(huán)的基礎(chǔ)上還需要額外增加創(chuàng)建事務(wù)對象、保存函數(shù)隊列、遍歷函數(shù)隊列等開銷,結(jié)果敗給正常使用法也在情理之中。

至此,也算是可以宣布模仿事務(wù)的優(yōu)化之道的失敗。但是對這個結(jié)果卻還能進(jìn)一步地分析。

性能在哪里

首先,從代碼的使用上來分析,將正常使用法和測試中最快的對象賦值法進(jìn)行比較,可以說兩者的差距僅在于循環(huán)的元素個數(shù)的不同(這里拋開了jQuery的內(nèi)部問題,事實上jQuery.access的糟糕實現(xiàn)也確實有拖對象賦值法后腿之嫌,好在并不嚴(yán)重),正常使用法是10000個元素,對象賦值法是5000個元素。因此可以簡單地認(rèn)為,18435 17748 = 687ms是循環(huán)5000個元素的耗時,這占到整個執(zhí)行過程的3.5%左右,并不是整個執(zhí)行過程的主干,其實真的沒有優(yōu)化的必要。

那么另外96.5%的開銷去了哪里呢?謹(jǐn)記Doglas的一句話,事實上Javascript并不慢,慢的是DOM的操作。其實剩下96.5%的開銷中,除去函數(shù)調(diào)用等基本的消耗,至少有95%的時間是用在了DOM元素的樣式被改變后的重新渲染之上。

發(fā)現(xiàn)了這個事實之后,其實也就有了更正確的優(yōu)化方向,也是前端性能中的基本原則之一:在修改大量子元素時,先將根父DOM節(jié)點移出DOM樹。因此如果使用以下的代碼再進(jìn)行測試:

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

測試結(jié)果始終停留在900ms左右,與前面的數(shù)據(jù)完全不在一個數(shù)量級之上,真正的優(yōu)化成功。

教訓(xùn)和總結(jié)

 ◆千萬要找到正確的性能瓶頸再進(jìn)行優(yōu)化,盲目的猜測只會導(dǎo)致走上錯誤而偏激的道路。

 ◆數(shù)據(jù)說話,數(shù)據(jù)面前誰也別說話!

 ◆不認(rèn)為事務(wù)這個方向是錯誤的,如果jQuery原生就能支持事務(wù)這樣的概念,會不會有其他的點可以優(yōu)化?比如一個事務(wù)自動會將父元素脫離出DOM樹之類的

以上就是jQuery優(yōu)化失敗的示例分析,小編相信有部分知識點可能是我們?nèi)粘9ぷ鲿姷交蛴玫降摹OM隳芡ㄟ^這篇文章學(xué)到更多知識。更多詳情敬請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。

本文題目:jQuery優(yōu)化失敗的示例分析
網(wǎng)頁地址:http://aaarwkj.com/article22/pdepcc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供靜態(tài)網(wǎng)站、ChatGPT、關(guān)鍵詞優(yōu)化、企業(yè)建站、網(wǎng)站建設(shè)搜索引擎優(yōu)化

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)頁設(shè)計公司
美女一区二区三区日本美女在线观看| 成年黄网站免费视频大全| 久久人妻一区二区三区免费密臀| 久久精品一区二区婷婷| 欧美高清一区二区在线观看| 亚洲国际精品女人乱码| 色婷婷国产精品久久包臀| 亚洲精品在线观看第一页| 国产麻豆精品免费喷白浆视频网站| 国产一级二级三级大胆视频| 国产系列在线播放一区二区三区| 国内精品久久大型新型| 欧美日本国产老熟女视频| 亚洲欧美日韩精品二区| 日韩一区二区精品网站| 亚洲国产高清第一第二区| 91手机精品在线视频| 男人的天堂av最新版本| 岛国高清乱码中文字幕| 日本熟妇中文字幕三级久久| 理论三级麻豆国产在线| 精精国产xxxx视频在线不卡| 亚洲永久免费黄色av| 亚洲成av人亚洲av| 亚州无吗一区二区三区| 色呦呦一区二区三区视频| 九九视频在线观看免费观看| 91精品久久久久久| 色综合久久综合香梨网| 国产内射一级一片内射高清视频1| 亚洲国产精品自拍第一页| 中出亚洲精品日韩在线视频| 日韩av有码在线播放| 亚洲成年人黄片在线播放| 亚洲一区二区三区久久精品| 99中文字幕国产精品| 亚洲天堂欧美日韩一区| 国产黄色一区二区三区,| 日韩精品欧美视频久久| 亚洲成人日韩在线播放| 亚洲国模av一区二区三区|