摘要:在內(nèi)存中操作元素由于操作會(huì)導(dǎo)致瀏覽器的回流,回流需要花費(fèi)大量的時(shí)間進(jìn)行樣式計(jì)算和節(jié)點(diǎn)重繪與渲染,所以應(yīng)當(dāng)盡量減少回流次數(shù)。
正巧看到在送書,于是乎找了找自己博客上記錄過的一些東西來及其無恥的蹭書了~~~
小廣告:更多內(nèi)容可以看我的博客
緩存DOM對(duì)象JavaScript的DOM操作可以說是JavaScript最重要的功能,我們經(jīng)常要根據(jù)用戶的操作來動(dòng)態(tài)的增加和刪除元素,或是通過AJAX返回的數(shù)據(jù)動(dòng)態(tài)生成元素。比如我們獲得了一個(gè)很多元素的數(shù)組data[],需要將其每個(gè)值生成一個(gè)li元素插入到一個(gè)id為container的ul元素中,最簡(jiǎn)單(最慢)的方式是:
var liNode, i, m; for (i = 0, m = data.length; i < m; i++) { liNode = document.createElement("li"); liNode.innerText = data[i]; document.getElementById("container").appendChild(liNode); }
這里每一次循環(huán)都會(huì)去查找id為container的元素,效率自然非常低,所以我們需要將元素在循環(huán)前查詢完畢,在循環(huán)中僅僅是引用就行了,修改代碼為:
var ulNode = document.getElementById("container"); var liNode, i, m; for (i = 0, m = data.length; i < m; i++) { liNode = document.createElement("li"); liNode.innerText = data[i]; ulNode.appendChild(liNode); }
緩存DOM對(duì)象的方式也經(jīng)常被用在元素的查找中,查找元素應(yīng)該是DOM操作中最頻繁的操作了,其效率優(yōu)化也是大頭。在一般情況下,我們會(huì)根據(jù)需要,將一些頻繁被查找的元素緩存起來,在查找它或查找它的子孫元素時(shí),以它為起點(diǎn)進(jìn)行查找,就能提高查找效率了。
在內(nèi)存中操作元素由于DOM操作會(huì)導(dǎo)致瀏覽器的回流,回流需要花費(fèi)大量的時(shí)間進(jìn)行樣式計(jì)算和節(jié)點(diǎn)重繪與渲染,所以應(yīng)當(dāng)盡量減少回流次數(shù)。一種可靠的方法就是加入元素時(shí)不要修改頁面上已經(jīng)存在的元素,而是在內(nèi)存中的節(jié)點(diǎn)進(jìn)行大量的操作,最后再一并將修改運(yùn)用到頁面上。DOM操作本身提供一個(gè)創(chuàng)建內(nèi)存節(jié)點(diǎn)片段的功能:document.createDocumentFragment(),我們可以將其運(yùn)用于上述代碼中:
var ulNode = document.getElementById("container"); var liNode, i, m; var fragment = document.createDocumentFragment(); for (i = 0, m = data.length; i < m; i++) { liNode = document.createElement("li"); liNode.innerText = data[i]; fragment.appendChild(liNode); } ulNode.appendChild(fragment);
這樣就只會(huì)觸發(fā)一次回流,效率會(huì)得到很大的提升。如果需要對(duì)一個(gè)元素進(jìn)行復(fù)雜的操作(刪減、添加子節(jié)點(diǎn)),那么我們應(yīng)當(dāng)先將元素從頁面中移除,然后再對(duì)其進(jìn)行操作,或者將其復(fù)制一個(gè)(cloneNode()),在內(nèi)存中進(jìn)行操作后再替換原來的節(jié)點(diǎn)
一次性DOM節(jié)點(diǎn)生成在這里我們每次都需要生成節(jié)點(diǎn)(document.createElement("li")),然后將其加入到內(nèi)存片段中,我們可以通過innerHTML屬性來一次性生成節(jié)點(diǎn),具體的思路就是使用字符串拼接的方式,先生成相應(yīng)的HTML字符串,最后一次性寫入到ul的innerHTML中。修改代碼為:
var ulNode = document.getElementById("container"); var fragmentHtml = "", i, m; for (i = 0, m = data.length; i < m; i++) { fragmentHtml += "
這樣效率也會(huì)有提升,不過手動(dòng)拼寫字符串是相當(dāng)麻煩的一件事
通過類修改樣式有時(shí)候我們需要通過JavaScript給元素增加樣式,比如如下代碼:
element.style.fontWeight = "bold"; element.style.backgroundImage = "url(back.gif)"; element.style.backgroundColor = "white"; element.style.color = "white"; //...
這樣效率很低,每次修改style屬性后都會(huì)觸發(fā)元素的重繪,如果修改了的屬性涉及大小和位置,將會(huì)導(dǎo)致回流。所以我們應(yīng)當(dāng)盡量避免多次為一個(gè)元素設(shè)置style屬性,應(yīng)當(dāng)通過給其添加新的CSS類,來修改其CSS
.element { background-image: url(back.gif); background-color: #fff; color: #fff; font-weight: "bold"; /*...*/ }
element.className += " element";通過事件代理批量操作事件
還是之前那個(gè)ul和添加li,如果我們需要給每個(gè)li都綁定一個(gè)click事件,就可能寫出類似如下代碼:
var ulNode = document.getElementById("container"); var fragment = document.createDocumentFragment(); var liNode, i, m; var liFnCb = function(evt){ //do something }; for (i = 0, m = data.length; i < m; i++) { liNode = document.createElement("li"); liNode.innerText = data[i]; liNode.addEventListener("click", liFnCb, false); fragment.appendChild(liNode); } ulNode.appendChild(fragment);
這里每個(gè)li元素都需要執(zhí)行一次addEventListener()方法,如果li元素?cái)?shù)量一多,就會(huì)降低效率。所以我們可以通過事件代理的方式,將事件綁定在ul上,然后通過event.target來確定被點(diǎn)擊的元素是否是li元素,同時(shí)我們也可以使用innerHTML屬性一次性創(chuàng)建節(jié)點(diǎn)了,修改代碼為:
var ulNode = document.getElementById("container"); var fragmentHtml = "", i, m; var liFnCb = function(evt){ //do something }; for (i = 0, m = data.length; i < m; i++) { fragmentHtml += "
這樣事件綁定的代碼就只要執(zhí)行一次,可以監(jiān)聽所有l(wèi)i元素的事件了。當(dāng)然如果需要移除事件回調(diào)函數(shù),我們也不需要循環(huán)遍歷所有的li元素,只需要移除ul元素上的事件處理就行了
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/78070.html
摘要:優(yōu)化策略跟上面的大同小異,就是用局部變量緩存集合以及集合的長(zhǎng)度,我就不進(jìn)行實(shí)際測(cè)試了。例如錯(cuò)誤的做法使用修改來進(jìn)行優(yōu)化如果需要?jiǎng)討B(tài)修改,那么就使用批量處理操作并且讓元素脫離文檔流,等操作結(jié)束后再放回文檔流中。 上篇我介紹了Javascript標(biāo)識(shí)符查找方面的優(yōu)化,可以看出在這方面的優(yōu)化給性能帶來的提升并不明顯,甚至可以說基本沒有影響。但是,我今天要分享的是前端Javascript優(yōu)化的...
摘要:在內(nèi)存中操作元素由于操作會(huì)導(dǎo)致瀏覽器的回流,回流需要花費(fèi)大量的時(shí)間進(jìn)行樣式計(jì)算和節(jié)點(diǎn)重繪與渲染,所以應(yīng)當(dāng)盡量減少回流次數(shù)。 正巧看到在送書,于是乎找了找自己博客上記錄過的一些東西來及其無恥的蹭書了~~~ 小廣告:更多內(nèi)容可以看我的博客 緩存DOM對(duì)象 JavaScript的DOM操作可以說是JavaScript最重要的功能,我們經(jīng)常要根據(jù)用戶的操作來動(dòng)態(tài)的增加和刪除元素,或是通過...
摘要:摘要想稍微系統(tǒng)的說說對(duì)于的操作把和常用操作的內(nèi)容歸納成思維導(dǎo)圖方便閱讀同時(shí)加入性能上的一些問題前言在前端開發(fā)的過程中極為重要的一個(gè)功能就是對(duì)對(duì)象的操作無論增刪改查在前端頁面操作這一范圍內(nèi)都是比較消耗性能的如何高效率的便捷的操作這就是本文要講 摘要 想稍微系統(tǒng)的說說對(duì)于DOM的操作,把Javascript和jQuery常用操作DOM的內(nèi)容歸納成思維導(dǎo)圖方便閱讀,同時(shí)加入性能上的一些問題....
摘要:雖然有著各種各樣的不同,但是相同的是,他們前端優(yōu)化不完全指南前端掘金篇幅可能有點(diǎn)長(zhǎng),我想先聊一聊閱讀的方式,我希望你閱讀的時(shí)候,能夠把我當(dāng)作你的競(jìng)爭(zhēng)對(duì)手,你的夢(mèng)想是超越我。 如何提升頁面渲染效率 - 前端 - 掘金Web頁面的性能 我們每天都會(huì)瀏覽很多的Web頁面,使用很多基于Web的應(yīng)用。這些站點(diǎn)看起來既不一樣,用途也都各有不同,有在線視頻,Social Media,新聞,郵件客戶端...
摘要:淺談網(wǎng)站性能之前端性能優(yōu)化性能優(yōu)化的目的無非是減少用戶流量消耗,提升用戶首屏體驗(yàn),提升用戶訪問速度,讓用戶專注內(nèi)容本身。前端性能優(yōu)化減少請(qǐng)求數(shù)量基本原理在瀏覽器與服務(wù)器進(jìn)行通信時(shí),主要是通過進(jìn)行通信。 最近項(xiàng)目慢慢走上正軌,需求趨于平穩(wěn),這才想起需要對(duì)整站進(jìn)行性能優(yōu)化。經(jīng)過一段時(shí)間的學(xué)習(xí),結(jié)合現(xiàn)在項(xiàng)目的實(shí)際性能情況,發(fā)現(xiàn)確實(shí)有許多地方可以進(jìn)行優(yōu)化。于是就開始了我的前端性能優(yōu)化之旅。以下...
閱讀 1368·2021-11-24 09:39
閱讀 1358·2021-11-04 16:12
閱讀 2701·2021-09-24 09:47
閱讀 3346·2021-09-01 10:50
閱讀 1487·2019-08-30 15:55
閱讀 1432·2019-08-30 15:43
閱讀 652·2019-08-30 11:08
閱讀 3588·2019-08-23 18:33