當(dāng)前位置:
首頁(yè) >
前端技术
> javascript
>内容正文
javascript
提高JS性能注意事项(转载)
生活随笔
收集整理的這篇文章主要介紹了
提高JS性能注意事项(转载)
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
一.執(zhí)行效率
1. DOM
1.1 使用DocumentFragment優(yōu)化多次append
說明:添加多個(gè)dom元素時(shí),先將元素append到DocumentFragment中,最后統(tǒng)一將DocumentFragment添加到頁(yè)面。
該做法可以減少頁(yè)面渲染dom元素的次數(shù)。經(jīng)IE和Fx下測(cè)試,在append1000個(gè)元素時(shí),效率能提高10%-30%,Fx下提升較為明顯。
服用前:
for (var i = 0; i < 1000; i++) {
??? var el = document.createElement('p');
??? el.innerHTML = i;
??? document.body.appendChild(el);
}
服用后:
var frag = document.createDocumentFragment();
for (var i = 0; i < 1000; i++) {
??? var el = document.createElement('p');
??? el.innerHTML = i;
??? frag.appendChild(el);
}
document.body.appendChild(frag);
1.2 通過模板元素clone,替代createElement
說明:通過一個(gè)模板dom對(duì)象cloneNode,效率比直接創(chuàng)建element高。
性能提高不明顯,約為10%左右。在低于100個(gè)元素create和append操作時(shí),沒有優(yōu)勢(shì)。
服用前:
var frag = document.createDocumentFragment();
for (var i = 0; i < 1000; i++) {
??? var el = document.createElement('p');
??? el.innerHTML = i;
??? frag.appendChild(el);
}
document.body.appendChild(frag);????
服用后:
var frag = document.createDocumentFragment();
var pEl = document.getElementsByTagName('p')[0];
for (var i = 0; i < 1000; i++) {
??? var el = pEl.cloneNode(false);
??? el.innerHTML = i;
??? frag.appendChild(el);
}
document.body.appendChild(frag);
1.3 使用一次innerHTML賦值代替構(gòu)建dom元素
說明:根據(jù)數(shù)據(jù)構(gòu)建列表樣式的時(shí)候,使用設(shè)置列表容器innerHTML的方式,比構(gòu)建dom元素并append到頁(yè)面中的方式,效率有數(shù)量級(jí)上的提高。?
服用前:
var frag = document.createDocumentFragment();
for (var i = 0; i < 1000; i++) {
??? var el = document.createElement('p');
??? el.innerHTML = i;
??? frag.appendChild(el);
}
document.body.appendChild(frag);
服用后:
var html = [];
for (var i = 0; i < 1000; i++) {
??? html.push('<p>' + i + '</p>');
}
document.body.innerHTML = html.join('');
1.4 使用firstChild和nextSibling代替childNodes遍歷dom元素
說明:約能獲得30%-50%的性能提高。逆向遍歷時(shí)使用lastChild和previousSibling。
服用前:
var nodes = element.childNodes;
for (var i = 0, l = nodes.length; i < l; i++) {
var node = nodes[i];
……
}
服用后:
var node = element.firstChild;
while (node) {
……
node = node.nextSibling;
}
2. 字符串
2.1 使用Array做為StringBuffer,代替字符串拼接的操作
說明:IE在對(duì)字符串拼接的時(shí)候,會(huì)創(chuàng)建臨時(shí)的String對(duì)象;經(jīng)測(cè)試,在IE下,當(dāng)拼接的字符串越來越大時(shí),運(yùn)行效率會(huì)急劇下降。Fx和Opera都對(duì)字符串拼接操作進(jìn)行了優(yōu)化;經(jīng)測(cè)試,在Fx下,使用Array的join方式執(zhí)行時(shí)間約為直接字符串拼接的1.4倍。
服用前:
var now = new Date();
var str = '';
for (var i = 0; i < 10000; i++) {
??? str += '123456789123456789';
}
alert(new Date() - now);
服用后:
var now = new Date();
var strBuffer = [];
for (var i = 0; i < 10000; i++) {
??? strBuffer.push('123456789123456789');
}
var str = strBuffer.join('');
alert(new Date() - now);
3. 循環(huán)語(yǔ)句
3.1 將循環(huán)控制量保存到局部變量
說明:對(duì)數(shù)組和列表對(duì)象的遍歷時(shí),提前將length保存到局部變量中,避免在循環(huán)的每一步重復(fù)取值。
服用前:
var list = document.getElementsByTagName('p');
for (var i = 0; i < list.length; i++) {
??? ……
}
服用后:
var list = document.getElementsByTagName('p');
for (var i = 0, l = list.length; i < l; i++) {
??? ……
}
3.2 順序無關(guān)的遍歷時(shí),用while替代for
說明:該方法可以減少局部變量的使用。比起效率優(yōu)化,更能直接看到的是字符數(shù)量的優(yōu)化。該做法有程序員強(qiáng)迫癥的嫌疑。
服用前:
var arr = [1,2,3,4,5,6,7];
var sum = 0;
for (var i = 0, l = arr.length; i < l; i++) {
??? sum += arr[i];
}????
服用后:
var arr = [1,2,3,4,5,6,7];
var sum = 0, l = arr.length;
while (l--) {
??? sum += arr[l];
}
4. 條件分支
4.1 將條件分支,按可能性順序從高到低排列
說明:可以減少解釋器對(duì)條件的探測(cè)次數(shù)。
4.2 在同一條件子的多(>2)條件分支時(shí),使用switch優(yōu)于if
說明:switch分支選擇的效率高于if,在IE下尤為明顯。4分支的測(cè)試,IE下switch的執(zhí)行時(shí)間約為if的一半。
4.3 使用三目運(yùn)算符替代條件分支
服用前:
if (a > b) {
num = a;
} else {
num = b;
}
服用后:
num = a > b ? a : b;
5. 定時(shí)器
5.1 需要不斷執(zhí)行的時(shí)候,優(yōu)先考慮使用setInterval
說明:setTimeout每一次都會(huì)初始化一個(gè)定時(shí)器。setInterval只會(huì)在開始的時(shí)候初始化一個(gè)定時(shí)器
服用前:
var timeoutTimes = 0;
function timeout () {
??? timeoutTimes++;
??? if (timeoutTimes < 10) {
??? ??? setTimeout(timeout, 10);
??? }
}
timeout();
服用后:
var intervalTimes = 0;
function interval () {
??? intervalTimes++;
??? if (intervalTimes >= 10) {
??? ??? clearInterval(interv);
??? }
}
var interv = setInterval(interval, 10);
5.2 使用function而不是string
說明:如果把字符串作為setTimeout和setInterval的參數(shù),瀏覽器會(huì)先用這個(gè)字符串構(gòu)建一個(gè)function。
服用前:
var num = 0;
setTimeout('num++', 10);????
服用后:
var num = 0;
function addNum () {
??? num++;
}
setTimeout(addNum, 10);
6. 其他
6.1 盡量不使用動(dòng)態(tài)語(yǔ)法元素
說明:eval、Function、execScript等語(yǔ)句會(huì)再次使用javascript解析引擎進(jìn)行解析,需要消耗大量的執(zhí)行時(shí)間。
6.2 重復(fù)使用的調(diào)用結(jié)果,事先保存到局部變量
說明:避免多次取值的調(diào)用開銷。
服用前:
var h1 = element1.clientHeight + num1;
var h2 = element1.clientHeight + num2;
服用后:
var eleHeight = element1.clientHeight;
var h1 = eleHeight + num1;
var h2 = eleHeight + num2;
6.3 使用直接量
說明:?
var a = new Array(param,param,...) -> var a = []
var foo = new Object() -> var foo = {}
var reg = new RegExp() -> var reg = /.../
6.4 避免使用with
說明: with雖然可以縮短代碼量,但是會(huì)在運(yùn)行時(shí)構(gòu)造一個(gè)新的scope。
OperaDev上還有這樣的解釋,使用with語(yǔ)句會(huì)使得解釋器無法在語(yǔ)法解析階段對(duì)代碼進(jìn)行優(yōu)化。對(duì)此說法,無法驗(yàn)證。
服用前:
with (a.b.c.d) {
property1 = 1;
property2 = 2;
}
服用后:
var obj = a.b.c.d;
obj.property1 = 1;
obj.property2 = 2;
6.5 巧用||和&&布爾運(yùn)算符
重要程度:
服用前:
function eventHandler (e) {
if(!e) e = window.event;
}
服用后:
function eventHandler (e) {
e = e || window.event;
}
服用前:
if (myobj) {
doSomething(myobj);
}
服用后:
myobj && doSomething(myobj);
6.6 類型轉(zhuǎn)換
說明:?
1).??? 數(shù)字轉(zhuǎn)換成字符串,應(yīng)用"" + 1,性能上:("" +) > String() > .toString() > new String();
2).??? 浮點(diǎn)數(shù)轉(zhuǎn)換成整型,不使用parseInt(), parseInt()是用于將字符串轉(zhuǎn)換成數(shù)字,而不是浮點(diǎn)數(shù)和整型之間的轉(zhuǎn)換,建議使用Math.floor()或者M(jìn)ath.round()
3).??? 對(duì)于自定義的對(duì)象,推薦顯式調(diào)用toString()。內(nèi)部操作在嘗試所有可能性之后,會(huì)嘗試對(duì)象的toString()方法嘗試能否轉(zhuǎn)化為String。
二.內(nèi)存管理
2.1 循環(huán)引用
說明:如果循環(huán)引用中包含DOM對(duì)象或者ActiveX對(duì)象,那么就會(huì)發(fā)生內(nèi)存泄露。內(nèi)存泄露的后果是在瀏覽器關(guān)閉前,即使是刷新頁(yè)面,這部分內(nèi)存不會(huì)被瀏覽器釋放。
簡(jiǎn)單的循環(huán)引用:
var el = document.getElementById('MyElement');
var func = function () {…}
el.func = func;
func.element = el;?
但是通常不會(huì)出現(xiàn)這種情況。通常循環(huán)引用發(fā)生在為dom元素添加閉包作為expendo的時(shí)候。
如:
function init() {
??? var el = document.getElementById('MyElement');
el.onclick = function () {……}
}
init();
init在執(zhí)行的時(shí)候,當(dāng)前上下文我們叫做context。這個(gè)時(shí)候,context引用了el,el引用了function,function引用了context。這時(shí)候形成了一個(gè)循環(huán)引用。
下面2種方法可以解決循環(huán)引用:
1)??? 置空dom對(duì)象
服用前:
function init() {
var el = document.getElementById('MyElement');
el.onclick = function () {……}
}
init();
服用后:
function init() {
var el = document.getElementById('MyElement');
el.onclick = function () {……}
el = null;
}
init();
將el置空,context中不包含對(duì)dom對(duì)象的引用,從而打斷循環(huán)應(yīng)用。
如果我們需要將dom對(duì)象返回,可以用如下方法:
服用前:
function init() {
??? var el = document.getElementById('MyElement');
??? el.onclick = function () {……}
??? return el;
}
init();
服用后:
function init() {
var el = document.getElementById('MyElement');
el.onclick = function () {……}
try{
return el;
} finally {
??? el = null;
}
}
init();
2)??? 構(gòu)造新的context
服用前:
function init() {
??? var el = document.getElementById('MyElement');
??? el.onclick = function () {……}
}
init();
服用后:
function elClickHandler() {……}
function init() {
??? var el = document.getElementById('MyElement');
??? el.onclick = elClickHandler;
}
init();
把function抽到新的context中,這樣,function的context就不包含對(duì)el的引用,從而打斷循環(huán)引用。
2.2 通過javascript創(chuàng)建的dom對(duì)象,必須append到頁(yè)面中
說明:IE下,腳本創(chuàng)建的dom對(duì)象,如果沒有append到頁(yè)面中,刷新頁(yè)面,這部分內(nèi)存是不會(huì)回收的!
示例代碼:
??? function create () {
??????? var gc = document.getElementById('GC');
??????? for (var i = 0; i < 5000 ; i++)
??????? {
??????????? var el = document.createElement('div');
??????????? el.innerHTML = "test";
??????????? //下面這句可以注釋掉,看看瀏覽器在任務(wù)管理器中,點(diǎn)擊按鈕然后刷新后的內(nèi)存變化
??????????? gc.appendChild(el);
??????? }
??? }
2.3 釋放dom元素占用的內(nèi)存
說明:
將dom元素的innerHTML設(shè)置為空字符串,可以釋放其子元素占用的內(nèi)存。
在rich應(yīng)用中,用戶也許會(huì)在一個(gè)頁(yè)面上停留很長(zhǎng)時(shí)間,可以使用該方法釋放積累得越來越多的dom元素使用的內(nèi)存。
2.4 釋放javascript對(duì)象
說明:在rich應(yīng)用中,隨著實(shí)例化對(duì)象數(shù)量的增加,內(nèi)存消耗會(huì)越來越大。所以應(yīng)當(dāng)及時(shí)釋放對(duì)對(duì)象的引用,讓GC能夠回收這些內(nèi)存控件。
對(duì)象:obj = null
對(duì)象屬性:delete obj.myproperty
數(shù)組item:使用數(shù)組的splice方法釋放數(shù)組中不用的item
2.5 避免string的隱式裝箱
說明:對(duì)string的方法調(diào)用,比如'xxx'.length,瀏覽器會(huì)進(jìn)行一個(gè)隱式的裝箱操作,將字符串先轉(zhuǎn)換成一個(gè)String對(duì)象。推薦對(duì)聲明有可能使用String實(shí)例方法的字符串時(shí),采用如下寫法:
1. DOM
1.1 使用DocumentFragment優(yōu)化多次append
說明:添加多個(gè)dom元素時(shí),先將元素append到DocumentFragment中,最后統(tǒng)一將DocumentFragment添加到頁(yè)面。
該做法可以減少頁(yè)面渲染dom元素的次數(shù)。經(jīng)IE和Fx下測(cè)試,在append1000個(gè)元素時(shí),效率能提高10%-30%,Fx下提升較為明顯。
服用前:
for (var i = 0; i < 1000; i++) {
??? var el = document.createElement('p');
??? el.innerHTML = i;
??? document.body.appendChild(el);
}
服用后:
var frag = document.createDocumentFragment();
for (var i = 0; i < 1000; i++) {
??? var el = document.createElement('p');
??? el.innerHTML = i;
??? frag.appendChild(el);
}
document.body.appendChild(frag);
1.2 通過模板元素clone,替代createElement
說明:通過一個(gè)模板dom對(duì)象cloneNode,效率比直接創(chuàng)建element高。
性能提高不明顯,約為10%左右。在低于100個(gè)元素create和append操作時(shí),沒有優(yōu)勢(shì)。
服用前:
var frag = document.createDocumentFragment();
for (var i = 0; i < 1000; i++) {
??? var el = document.createElement('p');
??? el.innerHTML = i;
??? frag.appendChild(el);
}
document.body.appendChild(frag);????
服用后:
var frag = document.createDocumentFragment();
var pEl = document.getElementsByTagName('p')[0];
for (var i = 0; i < 1000; i++) {
??? var el = pEl.cloneNode(false);
??? el.innerHTML = i;
??? frag.appendChild(el);
}
document.body.appendChild(frag);
1.3 使用一次innerHTML賦值代替構(gòu)建dom元素
說明:根據(jù)數(shù)據(jù)構(gòu)建列表樣式的時(shí)候,使用設(shè)置列表容器innerHTML的方式,比構(gòu)建dom元素并append到頁(yè)面中的方式,效率有數(shù)量級(jí)上的提高。?
服用前:
var frag = document.createDocumentFragment();
for (var i = 0; i < 1000; i++) {
??? var el = document.createElement('p');
??? el.innerHTML = i;
??? frag.appendChild(el);
}
document.body.appendChild(frag);
服用后:
var html = [];
for (var i = 0; i < 1000; i++) {
??? html.push('<p>' + i + '</p>');
}
document.body.innerHTML = html.join('');
1.4 使用firstChild和nextSibling代替childNodes遍歷dom元素
說明:約能獲得30%-50%的性能提高。逆向遍歷時(shí)使用lastChild和previousSibling。
服用前:
var nodes = element.childNodes;
for (var i = 0, l = nodes.length; i < l; i++) {
var node = nodes[i];
……
}
服用后:
var node = element.firstChild;
while (node) {
……
node = node.nextSibling;
}
2. 字符串
2.1 使用Array做為StringBuffer,代替字符串拼接的操作
說明:IE在對(duì)字符串拼接的時(shí)候,會(huì)創(chuàng)建臨時(shí)的String對(duì)象;經(jīng)測(cè)試,在IE下,當(dāng)拼接的字符串越來越大時(shí),運(yùn)行效率會(huì)急劇下降。Fx和Opera都對(duì)字符串拼接操作進(jìn)行了優(yōu)化;經(jīng)測(cè)試,在Fx下,使用Array的join方式執(zhí)行時(shí)間約為直接字符串拼接的1.4倍。
服用前:
var now = new Date();
var str = '';
for (var i = 0; i < 10000; i++) {
??? str += '123456789123456789';
}
alert(new Date() - now);
服用后:
var now = new Date();
var strBuffer = [];
for (var i = 0; i < 10000; i++) {
??? strBuffer.push('123456789123456789');
}
var str = strBuffer.join('');
alert(new Date() - now);
3. 循環(huán)語(yǔ)句
3.1 將循環(huán)控制量保存到局部變量
說明:對(duì)數(shù)組和列表對(duì)象的遍歷時(shí),提前將length保存到局部變量中,避免在循環(huán)的每一步重復(fù)取值。
服用前:
var list = document.getElementsByTagName('p');
for (var i = 0; i < list.length; i++) {
??? ……
}
服用后:
var list = document.getElementsByTagName('p');
for (var i = 0, l = list.length; i < l; i++) {
??? ……
}
3.2 順序無關(guān)的遍歷時(shí),用while替代for
說明:該方法可以減少局部變量的使用。比起效率優(yōu)化,更能直接看到的是字符數(shù)量的優(yōu)化。該做法有程序員強(qiáng)迫癥的嫌疑。
服用前:
var arr = [1,2,3,4,5,6,7];
var sum = 0;
for (var i = 0, l = arr.length; i < l; i++) {
??? sum += arr[i];
}????
服用后:
var arr = [1,2,3,4,5,6,7];
var sum = 0, l = arr.length;
while (l--) {
??? sum += arr[l];
}
4. 條件分支
4.1 將條件分支,按可能性順序從高到低排列
說明:可以減少解釋器對(duì)條件的探測(cè)次數(shù)。
4.2 在同一條件子的多(>2)條件分支時(shí),使用switch優(yōu)于if
說明:switch分支選擇的效率高于if,在IE下尤為明顯。4分支的測(cè)試,IE下switch的執(zhí)行時(shí)間約為if的一半。
4.3 使用三目運(yùn)算符替代條件分支
服用前:
if (a > b) {
num = a;
} else {
num = b;
}
服用后:
num = a > b ? a : b;
5. 定時(shí)器
5.1 需要不斷執(zhí)行的時(shí)候,優(yōu)先考慮使用setInterval
說明:setTimeout每一次都會(huì)初始化一個(gè)定時(shí)器。setInterval只會(huì)在開始的時(shí)候初始化一個(gè)定時(shí)器
服用前:
var timeoutTimes = 0;
function timeout () {
??? timeoutTimes++;
??? if (timeoutTimes < 10) {
??? ??? setTimeout(timeout, 10);
??? }
}
timeout();
服用后:
var intervalTimes = 0;
function interval () {
??? intervalTimes++;
??? if (intervalTimes >= 10) {
??? ??? clearInterval(interv);
??? }
}
var interv = setInterval(interval, 10);
5.2 使用function而不是string
說明:如果把字符串作為setTimeout和setInterval的參數(shù),瀏覽器會(huì)先用這個(gè)字符串構(gòu)建一個(gè)function。
服用前:
var num = 0;
setTimeout('num++', 10);????
服用后:
var num = 0;
function addNum () {
??? num++;
}
setTimeout(addNum, 10);
6. 其他
6.1 盡量不使用動(dòng)態(tài)語(yǔ)法元素
說明:eval、Function、execScript等語(yǔ)句會(huì)再次使用javascript解析引擎進(jìn)行解析,需要消耗大量的執(zhí)行時(shí)間。
6.2 重復(fù)使用的調(diào)用結(jié)果,事先保存到局部變量
說明:避免多次取值的調(diào)用開銷。
服用前:
var h1 = element1.clientHeight + num1;
var h2 = element1.clientHeight + num2;
服用后:
var eleHeight = element1.clientHeight;
var h1 = eleHeight + num1;
var h2 = eleHeight + num2;
6.3 使用直接量
說明:?
var a = new Array(param,param,...) -> var a = []
var foo = new Object() -> var foo = {}
var reg = new RegExp() -> var reg = /.../
6.4 避免使用with
說明: with雖然可以縮短代碼量,但是會(huì)在運(yùn)行時(shí)構(gòu)造一個(gè)新的scope。
OperaDev上還有這樣的解釋,使用with語(yǔ)句會(huì)使得解釋器無法在語(yǔ)法解析階段對(duì)代碼進(jìn)行優(yōu)化。對(duì)此說法,無法驗(yàn)證。
服用前:
with (a.b.c.d) {
property1 = 1;
property2 = 2;
}
服用后:
var obj = a.b.c.d;
obj.property1 = 1;
obj.property2 = 2;
6.5 巧用||和&&布爾運(yùn)算符
重要程度:
服用前:
function eventHandler (e) {
if(!e) e = window.event;
}
服用后:
function eventHandler (e) {
e = e || window.event;
}
服用前:
if (myobj) {
doSomething(myobj);
}
服用后:
myobj && doSomething(myobj);
6.6 類型轉(zhuǎn)換
說明:?
1).??? 數(shù)字轉(zhuǎn)換成字符串,應(yīng)用"" + 1,性能上:("" +) > String() > .toString() > new String();
2).??? 浮點(diǎn)數(shù)轉(zhuǎn)換成整型,不使用parseInt(), parseInt()是用于將字符串轉(zhuǎn)換成數(shù)字,而不是浮點(diǎn)數(shù)和整型之間的轉(zhuǎn)換,建議使用Math.floor()或者M(jìn)ath.round()
3).??? 對(duì)于自定義的對(duì)象,推薦顯式調(diào)用toString()。內(nèi)部操作在嘗試所有可能性之后,會(huì)嘗試對(duì)象的toString()方法嘗試能否轉(zhuǎn)化為String。
二.內(nèi)存管理
2.1 循環(huán)引用
說明:如果循環(huán)引用中包含DOM對(duì)象或者ActiveX對(duì)象,那么就會(huì)發(fā)生內(nèi)存泄露。內(nèi)存泄露的后果是在瀏覽器關(guān)閉前,即使是刷新頁(yè)面,這部分內(nèi)存不會(huì)被瀏覽器釋放。
簡(jiǎn)單的循環(huán)引用:
var el = document.getElementById('MyElement');
var func = function () {…}
el.func = func;
func.element = el;?
但是通常不會(huì)出現(xiàn)這種情況。通常循環(huán)引用發(fā)生在為dom元素添加閉包作為expendo的時(shí)候。
如:
function init() {
??? var el = document.getElementById('MyElement');
el.onclick = function () {……}
}
init();
init在執(zhí)行的時(shí)候,當(dāng)前上下文我們叫做context。這個(gè)時(shí)候,context引用了el,el引用了function,function引用了context。這時(shí)候形成了一個(gè)循環(huán)引用。
下面2種方法可以解決循環(huán)引用:
1)??? 置空dom對(duì)象
服用前:
function init() {
var el = document.getElementById('MyElement');
el.onclick = function () {……}
}
init();
服用后:
function init() {
var el = document.getElementById('MyElement');
el.onclick = function () {……}
el = null;
}
init();
將el置空,context中不包含對(duì)dom對(duì)象的引用,從而打斷循環(huán)應(yīng)用。
如果我們需要將dom對(duì)象返回,可以用如下方法:
服用前:
function init() {
??? var el = document.getElementById('MyElement');
??? el.onclick = function () {……}
??? return el;
}
init();
服用后:
function init() {
var el = document.getElementById('MyElement');
el.onclick = function () {……}
try{
return el;
} finally {
??? el = null;
}
}
init();
2)??? 構(gòu)造新的context
服用前:
function init() {
??? var el = document.getElementById('MyElement');
??? el.onclick = function () {……}
}
init();
服用后:
function elClickHandler() {……}
function init() {
??? var el = document.getElementById('MyElement');
??? el.onclick = elClickHandler;
}
init();
把function抽到新的context中,這樣,function的context就不包含對(duì)el的引用,從而打斷循環(huán)引用。
2.2 通過javascript創(chuàng)建的dom對(duì)象,必須append到頁(yè)面中
說明:IE下,腳本創(chuàng)建的dom對(duì)象,如果沒有append到頁(yè)面中,刷新頁(yè)面,這部分內(nèi)存是不會(huì)回收的!
示例代碼:
??? function create () {
??????? var gc = document.getElementById('GC');
??????? for (var i = 0; i < 5000 ; i++)
??????? {
??????????? var el = document.createElement('div');
??????????? el.innerHTML = "test";
??????????? //下面這句可以注釋掉,看看瀏覽器在任務(wù)管理器中,點(diǎn)擊按鈕然后刷新后的內(nèi)存變化
??????????? gc.appendChild(el);
??????? }
??? }
2.3 釋放dom元素占用的內(nèi)存
說明:
將dom元素的innerHTML設(shè)置為空字符串,可以釋放其子元素占用的內(nèi)存。
在rich應(yīng)用中,用戶也許會(huì)在一個(gè)頁(yè)面上停留很長(zhǎng)時(shí)間,可以使用該方法釋放積累得越來越多的dom元素使用的內(nèi)存。
2.4 釋放javascript對(duì)象
說明:在rich應(yīng)用中,隨著實(shí)例化對(duì)象數(shù)量的增加,內(nèi)存消耗會(huì)越來越大。所以應(yīng)當(dāng)及時(shí)釋放對(duì)對(duì)象的引用,讓GC能夠回收這些內(nèi)存控件。
對(duì)象:obj = null
對(duì)象屬性:delete obj.myproperty
數(shù)組item:使用數(shù)組的splice方法釋放數(shù)組中不用的item
2.5 避免string的隱式裝箱
說明:對(duì)string的方法調(diào)用,比如'xxx'.length,瀏覽器會(huì)進(jìn)行一個(gè)隱式的裝箱操作,將字符串先轉(zhuǎn)換成一個(gè)String對(duì)象。推薦對(duì)聲明有可能使用String實(shí)例方法的字符串時(shí),采用如下寫法:
var myString = new String('Hello World');
本文轉(zhuǎn)自溫景良博客園博客,原文鏈接:http://www.cnblogs.com/wenjl520/archive/2008/10/23/1318080.html,如需轉(zhuǎn)載請(qǐng)自行聯(lián)系原作者
總結(jié)
以上是生活随笔為你收集整理的提高JS性能注意事项(转载)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 无主之地3主线任务一共多少章 18183
- 下一篇: TPLINK物联App如何使用