




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第總結(jié)分享10個(gè)JavaScript代碼優(yōu)化小tips目錄寫在前面慎用全局變量通過原型新增方法避免閉包中的內(nèi)存泄露避免使用屬性訪問方法for循環(huán)優(yōu)化選擇最優(yōu)的循環(huán)方式減少判斷層級(jí)減少作用域鏈查找層級(jí)減少數(shù)據(jù)讀取次數(shù)字面量與構(gòu)造式
寫在前面
想要做到JavaScript的代碼優(yōu)化,首先需要做的是準(zhǔn)確的測(cè)試JavaScript的代碼執(zhí)行時(shí)間。其實(shí)需要做的就是采集大量的執(zhí)行樣本進(jìn)行數(shù)學(xué)統(tǒng)計(jì)和分析,這里我們使用的是benchmark.js來檢測(cè)代碼的執(zhí)行情況。
首先我們需要在項(xiàng)目中安裝依賴,代碼如下:
yarnaddbenchmark--save
npmibenchmark--save
然后我們寫一個(gè)測(cè)試代碼,如下所示:
constBenchmark=require('benchmark')
constsuite=newBenchmark.Suite()
//添加測(cè)試
suite
*add()方法接受兩個(gè)參數(shù),其中第一個(gè)表示測(cè)試的名稱,第二個(gè)表示測(cè)試的內(nèi)容,他是一個(gè)函數(shù)*
.add('join1000',()={
newArray(1000).join('')
.add('join10000',()={
newArray(10000).join('')
//添加時(shí)間監(jiān)聽
.on('cycle',event={
//打印執(zhí)行時(shí)間
console.log(String(event.target))
//完成后執(zhí)行觸發(fā)的事件
.on('complete',()={
console.log('最快的是:'+suite.filter('fastest').map('name'))
//執(zhí)行測(cè)試
.run({async:true})
復(fù)制代碼
代碼執(zhí)行結(jié)果如下:
//join1000x146,854ops/sec1.86%(88runssampled)
//join10000x16,083ops/sec1.06%(92runssampled)
//最快的是:join1000
在結(jié)果中,ops/sec表示的是每秒執(zhí)行的次數(shù),當(dāng)然是越大越好,緊接著是每秒執(zhí)行次數(shù)上下相差的百分比,最后括號(hào)中的內(nèi)容表示共取樣多少次。
或者也可以使用JSBench.me工具進(jìn)行替換,網(wǎng)站測(cè)試截圖如下:
我們可以看到,都是join1000的性能更好一些(我感覺我在說廢話)。
慎用全局變量
這里所說的慎用全局變量,為什么要慎用呢?主要有以下幾點(diǎn):
全局變量定義在全局執(zhí)行上下文,是所有作用域鏈的頂端。每次查找的時(shí)候都從局部找到最頂端,在時(shí)間上會(huì)有所消耗。全局執(zhí)行上下文一直存在于上下文的執(zhí)行棧,直到程序退出,才會(huì)被銷毀,內(nèi)存空間浪費(fèi)。如果某個(gè)局部作用域出現(xiàn)了同名的變量則會(huì)遮蓋或者說污染全局變量。
下面我們就來寫一段代碼,看一下全局變量與布局變量在執(zhí)行效率方面的差異,代碼如下:
...
suite
.add('全局變量',()={
//該函數(shù)內(nèi)模擬全局作用域
leti,
str=''
for(i=0;i1000;i++){
str+=i
.add('局部變量',()={
for(leti=0,str='';i1000;i++){
str+=i
...
代碼運(yùn)行結(jié)果如下:
全局變量x158,697ops/sec1.05%(87runssampled)
局部變量x160,697ops/sec1.03%(90runssampled)
最快的是:局部變量
雖然說差異不大,但是我們可以感知全局變量比局部的性能更差一些。
通過原型新增方法
為構(gòu)造函數(shù)增加實(shí)例對(duì)象需要的方法時(shí),盡量使用原型的方式添加,而不是構(gòu)造函數(shù)內(nèi)部進(jìn)行添加,我們可以看如下測(cè)試代碼:
...
suite
.add('構(gòu)造函數(shù)內(nèi)部添加',()={
functionPerson(){
this.sayMe=function(){
return'一碗周'
letp=newPerson()
.add('原型方式內(nèi)部添加',()={
functionPerson(){}
Ptotype.sayMe=function(){
return'一碗周'
letp=newPerson()
...
代碼運(yùn)行結(jié)果如下:
構(gòu)造函數(shù)內(nèi)部添加x573,786ops/sec1.97%(89runssampled)
原型方式內(nèi)部添加x581,693ops/sec3.46%(80runssampled)
最快的是:構(gòu)造函數(shù)內(nèi)部添加
避免閉包中的內(nèi)存泄露
由于閉包會(huì)使得函數(shù)中的變量都被保存在內(nèi)存中,內(nèi)存消耗很大,所以不能濫用閉包,否則會(huì)造成網(wǎng)頁(yè)的性能問題,嚴(yán)重可能導(dǎo)致內(nèi)存泄露。解決方法是,在退出函數(shù)之前,將不使用的局部變量全部刪除(即將局部變量重新賦值為null)。
避免使用屬性訪問方法
在JavaScript中的對(duì)象中,避免使用一些屬性訪問方法,這是因?yàn)镴avaScript中的所有屬性都是外部可見的。
示例代碼如下:
...
suite
.add('使用屬性訪問方法',()={
functionPerson(){
='一碗周'
this.getName=function(){
return'一碗周'
letp=newPerson()
letn=p.getName()
.add('不使用屬性訪問方法',()={
functionPerson(){
='一碗周'
letp=newPerson()
letn=
...
代碼運(yùn)行結(jié)果如下:
使用屬性訪問方法x406,682ops/sec2.33%(82runssampled)
不使用屬性訪問方法x554,169ops/sec2.03%(85runssampled)
最快的是:不使用屬性訪問方法
for循環(huán)優(yōu)化
我們?cè)谑褂胒or循環(huán)時(shí),可以將有些必要的數(shù)據(jù)進(jìn)行緩存,就比如arr.length這種屬性,不需要每次判斷都獲取一下,從而優(yōu)化我們的代碼。
示例代碼如下:
...
suite
.add('正序',()={
letarr=newArray(100)
letstr=''
for(leti=0;iarr.length;i++){
str+=i
.add('緩存',()={
letarr=newArray(100)
letstr=''
for(leti=arr.length;i;i--){
str+=i
.add('緩存的另一種寫法',()={
letarr=newArray(100)
letstr=''
for(leti=0,l=arr.length;ii++){
str+=i
...
代碼運(yùn)行結(jié)果如下:
正序x1,322,889ops/sec1.36%(86runssampled)
緩存x1,356,696ops/sec0.70%(92runssampled)
緩存的另一種寫法x1,383,091ops/sec0.70%(93runssampled)
最快的是:緩存的另一種寫法
選擇最優(yōu)的循環(huán)方式
我們現(xiàn)在常用的循環(huán)有forEach、for和for...in循環(huán),這幾種那個(gè)是性能最優(yōu)的呢,測(cè)試代碼如下:
...
suite
.add('forEach',()={
letarr=newArray(100)
letstr=''
arr.forEach(i={
str+=i
.add('for...in',()={
letarr=newArray(100)
letstr=''
for(iinarr){
str+=i
.add('for',()={
letarr=newArray(100)
letstr=''
for(leti=0,l=arr.length;ii++){
str+=i
...
代碼運(yùn)行結(jié)果如下:
forEachx4,248,577ops/sec0.89%(86runssampled)
for...inx4,583,375ops/sec1.15%(91runssampled)
forx1,343,871ops/sec1.91%(88runssampled)
最快的是:for...in
由運(yùn)行結(jié)果可以看出我們可以盡量使用for...in或者forEach循環(huán),減少使用for循環(huán)。
減少判斷層級(jí)
減少判斷層級(jí)就是減少一些if語(yǔ)句的嵌套,如果是一些必要的條件我們可以通過單層if結(jié)合return直接跳出函數(shù)的執(zhí)行,關(guān)于優(yōu)化前與優(yōu)化后的代碼執(zhí)行比對(duì)如下所示:
...
/***
接收兩類文件,zip和rar*
壓縮包的大小限制為10兆*
suite
.add('嵌套寫法',()={
functionuploadFile(suffix,size){
//允許上傳的后綴名
constsuffixList=['.zip','.rar']
constM=1024*1024
if(suffixList.includes(suffix)){
if(size=10*M){
return'下載成功'
uploadFile('.zip',1*1024*1024)
.add('減少判斷寫法',()={
functionuploadFile(suffix,size){
//允許上傳的后綴名
constsuffixList=['.zip','.rar']
constM=1024*1024
if(!suffixList.includes(suffix))return
if(size10*M)return
return'下載成功'
uploadFile('.zip',1*1024*1024)
...
代碼運(yùn)行結(jié)果如下:
嵌套寫法x888,445,014ops/sec2.48%(88runssampled)
減少判斷寫法x905,763,884ops/sec1.35%(92runssampled)
最快的是:減少判斷寫法,嵌套寫法
雖然說差距并不是很大,但是不適用嵌套的代碼比普通代碼更優(yōu)一些。
減少作用域鏈查找層級(jí)
減少代碼中作用域鏈的查找也是代碼優(yōu)化的一種方法,如下代碼展示了兩者的區(qū)別:
...
suite
.add('before',()={
varname='一碗粥'
functionsayMe(){
name='一碗周'
functionprint(){
varage=18
returnname+age
print()
sayMe()
.add('after',()={
varname='一碗粥'
functionsayMe(){
varname='一碗周'//形成局部作用域
functionprint(){
varage=18
returnname+age
print()
sayMe()
...
代碼運(yùn)行結(jié)果如下:
beforex15,509,793ops/sec7.78%(76runssampled)
afterx17,930,066ops/sec2.89%(83runssampled)
最快的是:after
上面代碼只是為了展示區(qū)別,并沒有實(shí)際意義。
減少數(shù)據(jù)讀取次數(shù)
如果對(duì)象中的某個(gè)數(shù)據(jù)在一個(gè)代碼塊中使用兩遍以上,這樣的話將其進(jìn)行緩存從而減少數(shù)據(jù)的讀取次數(shù)來達(dá)到更優(yōu)的一個(gè)性能,
測(cè)試代碼如下:
...
varuserList={
one:{
name:'一碗周',
age:18,
two:{
name:'一碗粥',
age:18,
suite
.add('before',()={
functionreturnOneInfo(){
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 舞蹈機(jī)構(gòu)并購(gòu)合同協(xié)議書
- 搭伙合同 協(xié)議書怎么寫
- 中國(guó)吸水穩(wěn)定劑行業(yè)市場(chǎng)前景預(yù)測(cè)及投資價(jià)值評(píng)估分析報(bào)告
- 2025年長(zhǎng)租公寓行業(yè)市場(chǎng)分析報(bào)告
- 店鋪成長(zhǎng)規(guī)劃方案
- 簡(jiǎn)單安全施工合同協(xié)議書
- 萬(wàn)科-項(xiàng)目故事線梳理及場(chǎng)景應(yīng)用策劃標(biāo)準(zhǔn)
- 鋁藝欄桿安裝合同協(xié)議書
- 買車合同簽訂協(xié)議書
- 西洋樂器市場(chǎng)前景預(yù)測(cè)與跨界營(yíng)銷策略制定與實(shí)施手冊(cè)
- 抖音合伙人合同協(xié)議書
- 大學(xué)英語(yǔ)四級(jí)考試模擬試卷2025年真題模擬測(cè)試
- 公司級(jí)新員工安全培訓(xùn)課件
- 滬教版(牛津英語(yǔ))二年級(jí)英語(yǔ)下冊(cè)全冊(cè)單元試題
- 折彎工藝培訓(xùn)
- 大學(xué)生干部競(jìng)選學(xué)生會(huì)干部競(jìng)選207
- 小升初英文寫作專題訓(xùn)練題100題(含參考范文答案)
- 2025-2030年煤炭貿(mào)易產(chǎn)業(yè)發(fā)展分析及發(fā)展趨勢(shì)與投資前景預(yù)測(cè)報(bào)告
- 農(nóng)業(yè)灌溉系統(tǒng)全掌握-故障排查與維護(hù)實(shí)戰(zhàn)指南
- 中國(guó)金融黑灰產(chǎn)治理研究報(bào)告 2024
- 行政管理??乒舶踩芾碓囶}及答案
評(píng)論
0/150
提交評(píng)論