jQuery高級(jí)技巧——性能優(yōu)化篇

作者:Lyzh
原文地址:http://blog.linjiajun.com/2015/08/23/jQuery高級(jí)技巧——性能優(yōu)化篇/

通過(guò)CDN(Content Delivery Network)引入jQuery庫(kù)

要提升網(wǎng)站中javascript的性能漓糙,最簡(jiǎn)單的一步就是引入最新版本的jQuery庫(kù)徐紧。新發(fā)布的版本族跛,通常在性能上會(huì)有更好的提升喊暖,而且也修復(fù)了一下bug田绑∈薹撸或者通過(guò)CDN引入,也是很好的選擇屡律。通過(guò)CDN引入能夠減少網(wǎng)站的加載時(shí)間腌逢。以下是一些CDN服務(wù):

<!– Case 1 - jQuery CDN –>
<script src=”http://code.jquery.com/jquery-1.10.2.min.js“ ></script>
<!– Case 2 - requesting jQuery from Googles CDN (notice the protocol) –>
<script src=”//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js” ></script>
<!– Case 3 - requesting the latest minor 1.10.x version (only cached for an hour) –>
<script src=”//ajax.googleapis.com/ajax/libs/jquery/1.10/jquery.min.js” ></script>
<!– Case 4 - requesting the absolute latest jQuery version (use with caution) –>
<script src=”http://code.jquery.com/jquery.min.js“ ></script>

一些國(guó)內(nèi)的CDN服務(wù):

<!–新浪 CDN–>
<script src=”http://lib.sinaapp.com/js/jquery/1.9.1/jquery-1.9.1.min.js“></script>

<!–百度 CDN–>
<script src=”http://libs.baidu.com/jquery/1.9.1/jquery.min.js“></script>

<!–Bootstrap CDN–>
http://www.bootcdn.cn/jquery/

減少DOM操作

雖然javascript性能上有了很大的提升,但是DOM操作還是很耗費(fèi)資源的超埋,需要減少對(duì)DOM操作上忍。當(dāng)在一個(gè)頁(yè)面中插入大量的元素的時(shí)候,尤其重要纳本。例如:

<div id=”elem” ></div>
// 不好的方式
//var elem = $(‘#elem’);
//for(var i = 0; i < 100; i++){
// elem.append(‘<li>element ‘+i+’</li>’);
//}

// 好的方式
var elem = $(‘#elem’ ),
arr = [];
for(var i = 0;  i < 100;  i++){
arr. push(‘<li>element ‘ +i+’</li>’ );
}
elem. append(arr. join(‘’ ));

將所有的元素緩存起來(lái)窍蓝,一次插入性能上會(huì)有所提升,因?yàn)橹挥|發(fā)頁(yè)面一次重繪繁成。對(duì)于CSS樣式屬性也是同樣的道理吓笙。

更多閱讀: 前端頁(yè)面卡頓?可能是DOM操作惹的禍巾腕,你需要優(yōu)化代碼

適當(dāng)使用原生JS

創(chuàng)建jQuery對(duì)象會(huì)帶來(lái)一些開(kāi)銷面睛。所以,如果比較注重性能的話尊搬,盡可能使用原生的javascript叁鉴。在某些方面可能會(huì)更容易理解和寫更少的代碼。

例如:

// 打印list中的li的id
$(‘#colors li’ ). each(function(){
//將$(this).attr(‘id’)方法替換為直接通過(guò)ID屬性訪問(wèn)
console. log(this. id);
})

選擇器優(yōu)化

如果你需要更好的性能佛寿,但是仍然要用到j(luò)Query幌墓,你可以在jQuery選擇器優(yōu)化做一些嘗試。以下是一個(gè)測(cè)試程序冀泻,通過(guò)瀏覽器的控制臺(tái)console.timeconsole.timeEnd方法來(lái)記錄不同選擇器執(zhí)行時(shí)間常侣。

HTML:

<div id=”peanutButter” >
<div id=”jelly” class=”.jellyTime” ></div>
</div>

JS:

//測(cè)試程序
var iterations = 10000,
    i;

//——————————————–
//Case 1: 很慢
console.time(‘Fancy’);
for (i = 0; i < iterations; i++) {
    
    $(‘#peanutButter div:first’);
}
console.timeEnd(‘Fancy’);

//——————————————–
//Case 2: 比較好,但仍然很慢
console.time(‘Parent-child’);
for (i = 0; i < iterations; i++) {

    $(‘#peanutButter div’);
}
console.timeEnd(‘Parent-child’);

//——————————————–
//Case 3: 一些瀏覽器會(huì)比較快
console.time(‘Parent-child by class’);
for (i = 0; i < iterations; i++) {
    // 通過(guò)后代Class選擇器
    $(‘#peanutButter .jellyTime’);
}
console.timeEnd(‘Parent-child by class’);

//——————————————–
//Case 4: 更好的方式 
console.time(‘By class name’);
21
for (i = 0; i < iterations; i++) {
    // 直接通過(guò)Class選擇器
    $(‘.jellyTime’);
}
console.timeEnd(‘By class name’);

//——————————————–
//Case 5: 推薦的方式 ID選擇器
console.time(‘By id’);
for (i = 0; i < iterations; i++) {
   
    $(‘#jelly’);
}
console.timeEnd(‘By id’);

執(zhí)行結(jié)果:

緩存jQuery對(duì)象

每次通過(guò)選擇器弹渔,構(gòu)建一個(gè)新的jQuery對(duì)象時(shí)胳施,jQuery的核心部分的Sizzle引擎會(huì)遍歷DOM,然后通過(guò)對(duì)應(yīng)的選擇器來(lái)匹配真正的dom元素肢专。這種方式比較低效舞肆。在現(xiàn)代瀏覽器中,可以通過(guò)document.querySelector方法博杖,通過(guò)傳入對(duì)應(yīng)的Class參數(shù)來(lái)匹配對(duì)應(yīng)的元素椿胯。不過(guò)IE8以下版本不支持此方法。

一個(gè)提高性能的實(shí)踐是通過(guò)變量緩存jQuery對(duì)象欧募。例如:

<ul id=”pancakes” >
         <li>first</li>
         <li>second</li>
         <li>third</li>
         <li>fourth</li>
         <li>fifth</li>
</ul>

JS:

// 不好的方式:
// $(‘#pancakes li’).eq(0).remove();
// $(‘#pancakes li’).eq(1).remove();
// $(‘#pancakes li’).eq(2).remove();
// ————————————
// 推薦的方式:
var pancakes = $(‘#pancakes li’);
pancakes.eq(0).remove();
pancakes.eq(1).remove();
pancakes.eq(2).remove();
// ————————————
// 或者:
// pancakes.eq(0).remove().end()
//  .eq(1).remove().end()
//  .eq(2).remove().end();

定義一個(gè)可以復(fù)用的函數(shù)

直接上例子:

HTML:

<button id=”menuButton” >Show Menu!</button>
<a href=”#” id=”menuLink” >Show Menu!</a>

JS:

//Bad: 
//這個(gè)會(huì)導(dǎo)致多個(gè)回調(diào)函數(shù)的副本占用內(nèi)存
$(‘#menuButton, #menuLink’ ). click(function(){
// …
});

//———————————————-
//Better
function showMenu(){
alert(‘Showing menu!’ );
// Doing something complex here
}

$(‘#menuButton’ ). click(showMenu);
$(‘#menuLink’ ). click(showMenu);

如果定義一個(gè)內(nèi)聯(lián)(inline)回調(diào)函數(shù)压状,同時(shí)這個(gè)包含多個(gè)元素的jQuery對(duì)象(正如上面所說(shuō)的第一個(gè)例子),對(duì)于這個(gè)集合中的每個(gè)元素,都會(huì)在內(nèi)存中保存一個(gè)回調(diào)函數(shù)的副本种冬。

用數(shù)組方式來(lái)遍歷jQuery 對(duì)象集合

你或許沒(méi)有注意到镣丑,但是在性能方面,對(duì)于jQuery each方法這種優(yōu)雅實(shí)現(xiàn)是有代價(jià)的娱两。有一個(gè)辦法能夠更快地遍歷一個(gè)jQuery對(duì)象莺匠,就是通過(guò)數(shù)組來(lái)實(shí)現(xiàn)。jQuery對(duì)象集合就是一個(gè)類數(shù)組十兢,具有lengthvalue屬性趣竣。可以通過(guò)程序來(lái)測(cè)試一下性能:

HTML:

<ul id=”testList” >
   <li>Item</li>
   <li>Item</li>
   <li>Item</li>
   <li>Item</li>
   <li>Item</li>
   <li>Item</li>
   <li>Item</li>
   <li>Item</li>
   <li>Item</li>
   <!– add 50 more –>
</ul>

JS:

var arr = $(‘li’),
    iterations = 100000;
//——————————
// Array實(shí)現(xiàn):    
console.time(‘Native Loop’);
for (var z = 0; z < iterations; z++) {
    var length = arr.length;
    for (var i = 0; i < length; i++) {
        arr[i];
    }
}
console.timeEnd(‘Native Loop’);

//——————————
// each實(shí)現(xiàn):    
console.time(‘jQuery Each’);
for (z = 0; z < iterations; z++) {
    arr.each(function(i, val) {
        this;
    });
}
console.timeEnd(‘jQuery Each’);

結(jié)果:

可以看到通過(guò)數(shù)組實(shí)現(xiàn)方式遍歷旱物,執(zhí)行效率更高遥缕。

以上是一些搜集知識(shí)的總結(jié),如有任何建議或疑問(wèn)宵呛,歡迎留言討論单匣。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市宝穗,隨后出現(xiàn)的幾起案子户秤,更是在濱河造成了極大的恐慌,老刑警劉巖逮矛,帶你破解...
    沈念sama閱讀 218,682評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鸡号,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡须鼎,警方通過(guò)查閱死者的電腦和手機(jī)鲸伴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)莉兰,“玉大人挑围,你說(shuō)我怎么就攤上這事√腔模” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 165,083評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵模捂,是天一觀的道長(zhǎng)捶朵。 經(jīng)常有香客問(wèn)我,道長(zhǎng)狂男,這世上最難降的妖魔是什么综看? 我笑而不...
    開(kāi)封第一講書人閱讀 58,763評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮岖食,結(jié)果婚禮上红碑,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好析珊,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,785評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布羡鸥。 她就那樣靜靜地躺著,像睡著了一般忠寻。 火紅的嫁衣襯著肌膚如雪惧浴。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 51,624評(píng)論 1 305
  • 那天奕剃,我揣著相機(jī)與錄音衷旅,去河邊找鬼。 笑死纵朋,一個(gè)胖子當(dāng)著我的面吹牛柿顶,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播操软,決...
    沈念sama閱讀 40,358評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼九串,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了寺鸥?” 一聲冷哼從身側(cè)響起猪钮,我...
    開(kāi)封第一講書人閱讀 39,261評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎胆建,沒(méi)想到半個(gè)月后烤低,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,722評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡笆载,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年扑馁,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片凉驻。...
    茶點(diǎn)故事閱讀 40,030評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡腻要,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出涝登,到底是詐尸還是另有隱情雄家,我是刑警寧澤,帶...
    沈念sama閱讀 35,737評(píng)論 5 346
  • 正文 年R本政府宣布胀滚,位于F島的核電站趟济,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏咽笼。R本人自食惡果不足惜顷编,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,360評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望剑刑。 院中可真熱鬧媳纬,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,941評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至米死,卻和暖如春贮庞,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背物喷。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,057評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工峦失, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留术吗,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,237評(píng)論 3 371
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像隘蝎,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子狮含,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,976評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容