要捕獲 JavaScript 代碼中的異常一般會(huì)采用 try catch,不過(guò) try catch 的使用是否是對(duì)代碼性能產(chǎn)生影響呢?答案是肯定有的,但是有多少不得而知。
前端線上腳本錯(cuò)誤的捕獲方法:
window . JSTracker = window . JSTracker || [ ] ;
try {
//your code
} catch ( e ) {
JSTracker . push ( e ) ;
throw e ; //建議將錯(cuò)誤再次拋出,避免測(cè)試無(wú)法發(fā)現(xiàn)異常
}
設(shè)計(jì)實(shí)驗(yàn)方式
簡(jiǎn)單的設(shè)計(jì)方案也就是對(duì)比實(shí)驗(yàn)。
空白組1:[無(wú) try catch 的情況下對(duì)數(shù)據(jù)取模1千萬(wàn)次耗時(shí)]
< ! DOCTYPE html >
< html >
< head >
< title > 1無(wú) try catch的情況耗時(shí) < / title >
! function ( ) {
//無(wú)try catch的情況耗時(shí)
var t = new Date ( ) ;
//耗時(shí)代碼開(kāi)始
for ( var i = 0 ; i < 100000000 ; i ++ ) {
var p = i % 2 ;
}
//耗時(shí)代碼結(jié)束
document . write ( new Date ( ) – t ) ;
} ( ) ;
script>
< / head >
< body >
< / body >
< / html >
參照組2:[將耗時(shí)代碼用 try 包圍,內(nèi)聯(lián)耗時(shí)代碼]
< ! DOCTYPE html >
< html >
< head >
< title > 2在 try中內(nèi)聯(lián)代碼的耗時(shí)情況 < / title >
! function ( ) {
//在 try 中內(nèi)聯(lián)代碼的耗時(shí)情況
var t = new Date ( ) ;
try {
//耗時(shí)代碼開(kāi)始
for ( var i = 0 ; i < 100000000 ; i ++ ) {
var p = i % 2 ;
}
//耗時(shí)代碼結(jié)束
throw new Error ( ) ;
} catch ( e ) {
}
document . write ( new Date ( ) – t ) ;
} ( ) ;
script>
< / head >
< body >
< / body >
< / html >
參照組3:[將耗時(shí)代碼用 try 包圍,外聯(lián)耗時(shí)代碼]
< ! DOCTYPE html >
< html >
< head >
< title > 3在 try中內(nèi)聯(lián)代碼的耗時(shí)情況 < / title >
! function ( ) {
function run ( ) {
//耗時(shí)代碼開(kāi)始
for ( var i = 0 ; i < 100000000 ; i ++ ) {
var p = i % 2 ;
}
//耗時(shí)代碼結(jié)束
}
//在 try 中內(nèi)聯(lián)代碼的耗時(shí)情況
var t = new Date ( ) ;
try {
run ( ) ;
throw new Error ( ) ;
} catch ( e ) {
}
document . write ( new Date ( ) – t ) ;
} ( ) ;
script>
< / head >
< body >
< / body >
< / html >
參照組4:[將耗時(shí)代碼用 catch 包圍,內(nèi)聯(lián)耗時(shí)代碼]
< ! DOCTYPE html >
< html >
< head >
< title > 4在 catch中內(nèi)聯(lián)代碼的耗時(shí)情況 < / title >
! function ( ) {
//在 catch 中內(nèi)聯(lián)代碼的耗時(shí)情況
var t = new Date ( ) ;
try {
throw new Error ( ) ;
} catch ( e ) {
//耗時(shí)代碼開(kāi)始
for ( var i = 0 ; i < 100000000 ; i ++ ) {
var p = i % 2 ;
}
//耗時(shí)代碼結(jié)束
}
document . write ( new Date ( ) – t ) ;
} ( ) ;
script>
< / head >
< body >
< / body >
< / html >
參照組5:[將耗時(shí)代碼用 catch 包圍,外聯(lián)耗時(shí)代碼]
< ! DOCTYPE html >
< html >
< head >
< title > 5在 catch中內(nèi)聯(lián)代碼的耗時(shí)情況 < / title >
! function ( ) {
function run ( ) {
//耗時(shí)代碼開(kāi)始
for ( var i = 0 ; i < 100000000 ; i ++ ) {
var p = i % 2 ;
}
//耗時(shí)代碼結(jié)束
}
//在 catch 中內(nèi)聯(lián)代碼的耗時(shí)情況
var t = new Date ( ) ;
try {
throw new Error ( ) ;
} catch ( e ) {
run ( ) ;
}
document . write ( new Date ( ) – t ) ;
} ( ) ;
script>
< / head >
< body >
< / body >
< / html >
運(yùn)行結(jié)果(只選取了 Chrome 作為示例)
– | 不使用 try-catch | try 中耗時(shí),內(nèi)聯(lián)代碼 | try 中耗時(shí),外聯(lián)代碼 | catch 中耗時(shí),內(nèi)聯(lián)代碼 | catch 中耗時(shí),外聯(lián)代碼 |
---|---|---|---|---|---|
Chrome51 | 98.2 | 1026.9 | 107.7 | 1028.5 | 105.9 |
給出總結(jié)
使用 try catch 的使用無(wú)論是在 try 中的代碼還是在 catch 中的代碼性能消耗都是一樣的。
需要注意的性能消耗在于 try catch 中不要直接塞進(jìn)去太多的代碼(聲明太多的變量),最好是吧所有要執(zhí)行的代碼放在另一個(gè) function 中,通過(guò)調(diào)用這個(gè) function 來(lái)執(zhí)行。
針對(duì)第二點(diǎn),可以查看 ECMA 中關(guān)于 try catch 的解釋,在代碼進(jìn)入 try catch 的時(shí)候 js引擎會(huì)拷貝當(dāng)前的詞法環(huán)境,拷貝的其實(shí)就是當(dāng)前 scope 下的所有的變量。
建議
在使用 try catch 的時(shí)候盡量把 try catch 放在一個(gè)相對(duì)干凈的 scope 中,同時(shí)在 try catch 語(yǔ)句中也盡量保證足夠少的變量,最好通過(guò)函數(shù)調(diào)用方式來(lái) try catch。
試驗(yàn)中的現(xiàn)象解釋
測(cè)試過(guò)程中還是發(fā)現(xiàn)了一個(gè)疑問(wèn), 以下兩段代碼在 Chrome 44 中運(yùn)行出來(lái)的結(jié)果差距非常大,加了一句空的 try catch 之后平均為:850ms,加上之前為:140ms。
! function ( ) {
//無(wú) try catch 的情況耗時(shí)
var t = new Date ( ) ;
//耗時(shí)代碼開(kāi)始
for ( var i = 0 ; i < 100000000 ; i ++ ) {
var p = i % 2 ;
}
//耗時(shí)代碼結(jié)束
document . write ( new Date ( ) – t ) ;
try {
} catch ( e ) {
}
} ( ) ;
! function ( ) {
//無(wú) try catch 的情況耗時(shí)
var t = new Date ( ) ;
//耗時(shí)代碼開(kāi)始
for ( var i = 0 ; i < 100000000 ; i ++ ) {
var p = i % 2 ;
}
//耗時(shí)代碼結(jié)束
document . write ( new Date ( ) – t ) ;
} ( ) ;
其實(shí)原因很簡(jiǎn)單
只要把代碼改為這樣 耗時(shí)就降下來(lái)了:
! function ( ) {
! function ( ) {
//無(wú) try catch 的情況耗時(shí)
var t = new Date ( ) ;
//耗時(shí)代碼開(kāi)始
for ( var i = 0 ; i < 100000000 ; i ++ ) {
var p = i % 2 ;
}
//耗時(shí)代碼結(jié)束
document . write ( new Date ( ) – t ) ;
} ( ) ;
try {
} catch ( e ) {
}
} ( ) ;
聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com