JavaScript知識(shí)點(diǎn)總結(jié)之如何提高性能
JavaScript的性能問(wèn)題不容小覷,這就需要我們開發(fā)人員在編寫JavaScript程序時(shí)多注意一些細(xì)節(jié),本文非常詳細(xì)的介紹了一下JavaScript性能優(yōu)化方面的知識(shí)點(diǎn),絕對(duì)是干貨。
先給大家鞏固下javascript基本語(yǔ)法:
javascript基本語(yǔ)法
定義變量統(tǒng)一用var關(guān)鍵字
語(yǔ)法:var 變量名稱=變量值
標(biāo)示符:①、由字母數(shù)字下劃線構(gòu)成 不能以數(shù)字開頭 不能是關(guān)鍵字 嚴(yán)格區(qū)分大小寫
數(shù)據(jù)類型:
數(shù)值型:number
字符串:string
布爾型:boolean
特殊數(shù)據(jù)類型:undefined 空的 未定義的 未賦值的
空值:null
引用類型object function
檢測(cè)參數(shù)的數(shù)據(jù)類型:typeof()返回該數(shù)據(jù)類型對(duì)應(yīng)的字符串
兩個(gè)等號(hào)==和三個(gè)等號(hào)===的用法
==:比較值相等 與數(shù)據(jù)類型無(wú)關(guān)
===:比較全等 與數(shù)值和數(shù)據(jù)類型都有關(guān)
布爾環(huán)境:遇到if自動(dòng)轉(zhuǎn)換成布爾值
字符串string中的布爾環(huán)境:空為假 非空為真
數(shù)值number中的布爾環(huán)境:0為假 非0為真
number與string之間的關(guān)系
①、遇到+做拼接操作
②、需要做運(yùn)算操作時(shí),要把字符串轉(zhuǎn)換成數(shù)值型
轉(zhuǎn)換方法1、字符串*1 變成數(shù)值型
轉(zhuǎn)換方法2:Number(字符串) 轉(zhuǎn)換成數(shù)值型
一:針對(duì)js文件的加載位置
在HTML文件中,<script>標(biāo)簽是可以加在<head>區(qū)域和<body>區(qū)域的。這里鑒于JavaScript執(zhí)行和UI渲染的單線程原因,如果js文件載入會(huì)阻塞后面對(duì)于頁(yè)面的解析過(guò)程,頁(yè)面會(huì)等到j(luò)s文件完全加載并運(yùn)行后才繼續(xù)執(zhí)行該做的操作。那么問(wèn)題就來(lái)了,這樣可能會(huì)出現(xiàn)頁(yè)面空白o(hù)r卡頓現(xiàn)象。作為一名前端開發(fā),重要的不僅僅止于實(shí)現(xiàn)了需求,應(yīng)該還有優(yōu)質(zhì)的用戶體驗(yàn)。那么我們就需要消除用戶枯燥的等待,針對(duì)這個(gè)問(wèn)題,這里有本獸想到的兩種解決方案:
1. 如果js文件沒(méi)有特殊要求指明需要在頁(yè)面渲染之前載入及編譯完成的,那么選擇將js文件放到</body>標(biāo)簽前(既所有的頁(yè)面所呈現(xiàn)內(nèi)容的后面),css文件還是放到<head>區(qū)域(誰(shuí)也不愿意看一個(gè)布局雜亂無(wú)章的頁(yè)面)。這樣做就能先讓用戶看到有布局的頁(yè)面而不是空白頁(yè)了,那么也會(huì)有人指出:那數(shù)據(jù)得通過(guò)js請(qǐng)求加載進(jìn)來(lái)啊,怎么辦呢?可以對(duì)數(shù)據(jù)的加載做排序,急需呈現(xiàn)的接口放前面執(zhí)行,不是那么需要的可以延后執(zhí)行,同時(shí)做個(gè)簡(jiǎn)單的載入動(dòng)畫or提示。
2. 如果這些js文件有指明需要先執(zhí)行了,才能更好的展示頁(yè)面內(nèi)容,那么就在第一個(gè)js或者頁(yè)面上先放個(gè)載入小動(dòng)畫,可以一些有趣的或者萌萌的動(dòng)畫場(chǎng)景。這樣也是能較好的避免用戶等待的無(wú)聊,說(shuō)不定人家還對(duì)這個(gè)載入動(dòng)畫更感興趣呢,這樣可提升項(xiàng)目的用戶體驗(yàn)感。
最終推薦:將<script>標(biāo)簽盡可能的放到</body>標(biāo)簽前面加載,以提升用戶體驗(yàn)。
二:針對(duì)js文件的合并
在很多團(tuán)隊(duì)開發(fā)中,我們可能會(huì)將不同功能的代碼塊分別放置在不同的js文件中,以便于開發(fā)過(guò)程中眾人合作寫代碼會(huì)更加方便,畢竟只需要找對(duì)應(yīng)文件夾或文件而不是在一個(gè)很長(zhǎng)的文件中找一個(gè)方法。這確實(shí)是會(huì)提高團(tuán)隊(duì)開發(fā)效率及新人加入后的更容易進(jìn)行二次開發(fā)及維護(hù)。那么將這個(gè)問(wèn)題放到頁(yè)面性能里呢?這正是問(wèn)題所在,在這本書中指出:Each HTTP request brings with it additional performance overhead,so downloading one single 100 KB file will be faster than downloading four 25 KB files.
下載1個(gè)100KB的文件比下載4個(gè)25KB的文件要快,而開發(fā)過(guò)程中區(qū)分開各個(gè)文件又有很大的好處,那么合并這個(gè)問(wèn)題也就放在開發(fā)完后再處理咯,相信這個(gè)操作大家都不會(huì)陌生吧,現(xiàn)在的前端工具這么豐富,各位習(xí)慣用什么壓縮就用什么壓縮吧~
這里簡(jiǎn)單提出下,在載入文件方面還可以用到defer和async屬性,用于延遲加載和異步加載,在現(xiàn)代瀏覽器中,大多數(shù)是已經(jīng)支持defer屬性了,還沒(méi)習(xí)慣用這個(gè)額,也不知道具體會(huì)不會(huì)存在什么問(wèn)題。有興趣的朋友可自行g(shù)oogle該知識(shí)點(diǎn),這里件簡(jiǎn)單提下吧。
現(xiàn)在的框架也大多配合懶加載和按需加載了。
三:更快速的數(shù)據(jù)訪問(wèn)
對(duì)于瀏覽器來(lái)說(shuō),一個(gè)標(biāo)識(shí)符所處的位置越深,去讀寫他的速度也就越慢(對(duì)于這點(diǎn),原型鏈亦是如此)。這個(gè)應(yīng)該不難理解,簡(jiǎn)單比喻就是:雜貨店離你家越遠(yuǎn),你去打醬油所花的時(shí)間就越長(zhǎng)... 熊孩子,打個(gè)醬油那么久,菜早燒焦了 -.-~
如果我們需要在當(dāng)前函數(shù)內(nèi)多次用到一個(gè)變量值,那么我們可以用一個(gè)局部變量先將其存儲(chǔ)起來(lái),案例如下:
//修改前 function showLi(){ var i = 0; for(;i<document.getElementsByTagName("li").length;i++){ //一次訪問(wèn)document console.log(i,document.getElementsByTagName("li")[i]); //三次訪問(wèn)document }; }; //修改后 function showLi(){ var li_s = document.getElementsByTagName("li"); //一次訪問(wèn)document var i = 0; for(;i<li_s.length;i++){ console.log(i,li_s[i]); //三次訪問(wèn)局部變量li_s }; };
四:DOM操作的優(yōu)化
眾所周知的,DOM操作遠(yuǎn)比javascript的執(zhí)行耗性能,雖然我們避免不了對(duì)DOM進(jìn)行操作,但我們可以盡量去減少該操作對(duì)性能的消耗。
讓我們通過(guò)代碼解釋這個(gè)問(wèn)題:
function innerLi_s(){ var i = 0; for(;i<20;i++){ document.getElementById("Num").innerHTML="A"; //進(jìn)行了20次循環(huán),每次又有2次DOM元素訪問(wèn):一次讀取innerHTML的值,一次寫入值 }; };
針對(duì)以上方法進(jìn)行一次改寫:
function innerLi_s(){ var content =""; var i = 0; for(;i<20;i++){ content += "A"; //這里只對(duì)js的變量循環(huán)了20次 }; document.getElementById("Num").innerHTML += content; //這里值進(jìn)行了一次DOM操作,又分2次DOM訪問(wèn):一次讀取innerHTML的值,一次寫入值 };
五:減少Dom的重繪重排版
元素布局的改變或內(nèi)容的增刪改或者瀏覽器窗口尺寸改變都將會(huì)導(dǎo)致重排,而字體顏色或者背景色的修改則將導(dǎo)致重繪。
對(duì)于類似以下代碼的操作,據(jù)說(shuō)現(xiàn)代瀏覽器大多進(jìn)行了優(yōu)化(將其優(yōu)化成1次重排版):
//修改前 var el = document.getElementById("div"); el.style.borderLeft = "1px"; //1次重排版 el.style.borderRight = "2px"; //又1次重排版 el.style.padding = "5px"; //還有1次重排版 //修改后 var el = document.getElementById("div"); el.style.cssText = "border-left:1px;border-right:2px;padding:5px"; //1次重排版
針對(duì)多重操作,以下三種方法也可以減少重排版和重繪的次數(shù):
1.Dom先隱藏,操作后再顯示 2次重排 (臨時(shí)的display:none)
2.document.createDocumentFragment() 創(chuàng)建文檔片段處理,操作后追加到頁(yè)面 1次重排
3.var newDOM = oldDOM.cloneNode(true)創(chuàng)建Dom副本,修改副本后oldDOM.parentNode.replaceChild(newDOM,oldDOM)覆蓋原DOM 2次重排
五:循環(huán)的優(yōu)化
這應(yīng)該是較多人都知道的寫法了,簡(jiǎn)單帶過(guò)即可(后面還是用代碼+注釋形式說(shuō)明)~
//修改前 var i = 0; for(;i<arr.lengthli++){ //每次循環(huán)都需要獲取數(shù)組arr的length console.log(arr[i]); } //修改后 var i = 0; var len = arr.length; //獲取一次數(shù)組arr的length for(;i<len;i++){ console.log(arr[i]); } //or var i = arr.length;; for(;i;i--){ console.log(arr[i]); }
六:合理利用二進(jìn)制
如:對(duì)2取模,則偶數(shù)最低位是0,奇數(shù)最低位是0,與1進(jìn)行位與操作的結(jié)果是0,奇數(shù)的最低位是1,與1進(jìn)行位與操作的結(jié)果是1。
代碼如下:
.odd{color:red} .even{color:yellow} <ul> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> <li>6</li> </ul> var i = 0; var lis = document.getElementsByTagName("li"); var len = lis.length; for(;i<len;i++){ if(i&1){ lis[i].className = "even"; } else{ lis[i].className = "odd"; } };
雖說(shuō)現(xiàn)代瀏覽器都已經(jīng)做的很好了,但是本獸覺(jué)得這是自己對(duì)代碼質(zhì)量的一個(gè)追求。并且可能一個(gè)點(diǎn)或者兩個(gè)點(diǎn)不注意是不會(huì)產(chǎn)生多大性能影響,但是從多個(gè)點(diǎn)進(jìn)行優(yōu)化后,可能產(chǎn)生的就會(huì)質(zhì)的飛躍了~
- 關(guān)于vue.js彈窗組件的知識(shí)點(diǎn)總結(jié)
- javaScript知識(shí)點(diǎn)總結(jié)(必看篇)
- JavaScript入門系列之知識(shí)點(diǎn)總結(jié)
- JS運(yùn)動(dòng)相關(guān)知識(shí)點(diǎn)小結(jié)(附彈性運(yùn)動(dòng)示例)
- js+jquery常用知識(shí)點(diǎn)匯總
- JavaScript 語(yǔ)言基礎(chǔ)知識(shí)點(diǎn)總結(jié)(思維導(dǎo)圖)
- JS重要知識(shí)點(diǎn)小結(jié)
- javascript Excel操作知識(shí)點(diǎn)
- javascript知識(shí)點(diǎn)收藏
- JS常用知識(shí)點(diǎn)整理
相關(guān)文章
JS繪圖Flot如何實(shí)現(xiàn)動(dòng)態(tài)可刷新曲線圖
這篇文章主要介紹了JS繪圖Flot如何實(shí)現(xiàn)動(dòng)態(tài)可刷新曲線圖,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-10-10JS實(shí)現(xiàn)旋轉(zhuǎn)木馬輪播案例
這篇文章主要為大家詳細(xì)介紹了JS實(shí)現(xiàn)旋轉(zhuǎn)木馬輪播案例,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-10-10JavaScript對(duì)象引用與賦值實(shí)例詳解
這篇文章主要介紹了JavaScript對(duì)象引用與賦值,結(jié)合實(shí)例形式分析了JavaScript對(duì)象引用及賦值的操作技巧與相關(guān)注意事項(xiàng),需要的朋友可以參考下2017-03-03純js實(shí)現(xiàn)頁(yè)面返回頂部的動(dòng)畫(超簡(jiǎn)單)
下面小編就為大家?guī)?lái)一篇純js實(shí)現(xiàn)頁(yè)面返回頂部的動(dòng)畫(超簡(jiǎn)單)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-08-08JS實(shí)現(xiàn)彈出浮動(dòng)窗口(支持鼠標(biāo)拖動(dòng)和關(guān)閉)實(shí)例詳解
這篇文章主要介紹了JS實(shí)現(xiàn)彈出浮動(dòng)窗口,可支持鼠標(biāo)拖動(dòng)和關(guān)閉的功能,界面美觀大方,涉及javascript動(dòng)態(tài)創(chuàng)建對(duì)話框的相關(guān)技巧,需要的朋友可以參考下2015-08-08