原本想整理一篇完整的JavaScript優化知識點出來跟你們討論分享一下的,可是因爲最近我的的時間比較少,因此先整理了兩個知識點,以後有時間了再繼續整理後面的。不喜歡勿噴,有錯誤的歡迎大佬指點。
2019/05/14/01:30javascript
傳統的方式java
傳統的方式就是,把JavaScript的腳本放到head標籤以後</body>以前,也就把script標籤放到最尾處,來確保頁面加載完以後才執行JavaScript腳本,從而達到一些沒必要要的阻塞。(可能這也是咱們平時用得比較多的方式)es6
延遲JavaScript腳本執行面試
1.HTML4爲script標籤擴展了一個Defer屬性,指定這個屬性的script標籤的腳本不會修改DOM,所以代碼能安全的延遲執行。加上這個屬性的script標籤的腳本能夠放在DOM的任意位置,當瀏覽器加載到它是,它會被下載,但不會被執行,因此不能阻塞頁面的方面,它會等到頁面加載完成後,在windown的load()函數以後執行。
<script type="text/javascript" src="./a.js" defer="defer"></script> <script type="text/javascript"> console.log("b") </script> <script type="text/javascript"> window.onload = function () { console.log("c") } //這個例子,最終輸出的順序是b,a,c </script>
2.在H5的時候,script又擴展了一個async屬性,它與defer相同點就是都是採用並行下載,不會在下載的過程形成頁面的阻塞狀況;不一樣點就是,它們的執行時機:async加載完以後,自動執行(也就是說,當加載到它的時候,瀏覽器能夠繼續往下加載頁面,當它加載完以後,它就會自動執行,而不須要等到頁面加載完以後再執行,也不用頁面加載等它執行完再日後執行);而dafer要等頁面加載完成後纔會執行。
合拼JavaSript腳本瀏覽器
由於每一個script標籤初始下載是=時都會阻塞頁面渲染,因此減小頁面包含的script標籤數量也有助於頁面加載性能的優化。(若是頁面有不少的script標籤,沒個script標籤都會發送一次http請求( http://tool.oschina.net/jscom...),從而浪費了不少不必的時間,咱們能夠經過某些在線工具將多個script標籤合拼成一個script標籤,最終頁面只引用了一個script,也就是隻發送了一次http請求,這樣加載性能會比以前加載多個script標籤快)
2019/05/15/02:05緩存
JavaScript的做用域一樣關係到性能的問題安全
//結果輸出什麼? for(var i = 0; i<10;i++){ setTimeout(function () { console.log(i) },1000) }
咱們指望的結果是輸出0-9。可是結果拼不是咱們想這樣,這玩(diao)意(mao)既然輸出十次10.爲何會這樣?由於當setTimeout執行的時候,for循環已經完成,已經變成了10。閉包
怎樣解決?(在es6沒有到來以前,通常都是同閉包的方法把做用域緩存起來)async
for(var i = 0; i<10;i++){ (function(i){ setTimeout(function () { console.log(i) },1000) })(i) } //結果輸出爲0-9
最後輸出的結果就跟咱們期待的同樣了,可是上面使用了閉包,閉包也涉及到做用域鏈的性能問題;由於閉包的屬性包含了與執行環境做用域相同的對象的引用,所以致使閉包裏面的變量沒辦法被銷燬,從而佔用了更多的內存空間,也有可能致使內存泄漏問題,因此使用閉包時仍是要謹慎,它關係到內存以及執行速度。函數
//上面代碼優化後 for(let i = 0; i<10;i++){ setTimeout(function () { console.log(i) },1000) }
2.儘可能使用局部變量緩存全局變量
let obj = { name:"July" } function Person() { console.log(obj.name +"去吃飯",obj.name +"去睡覺",obj.name +"去打籃球") } Person() //改 let obj = { name:"July" } function Person() { let name = obj.name console.log(name +"去吃飯",name +"去睡覺",name +"去打籃球") } Person()
3.儘可能不要使用動態做用域,由於他們會改變執行環境的做用域鏈。好比with()語句和try{}catch(){}的catch(){}字句...,它們都會改變執行環境的做用域鏈。好比下面這段代碼:with會把一個包含了obj所有屬性的新的可變變量置於做用域鏈的頭部,使得訪問obj對象屬性速度很是快,可是訪問局部變量則變慢了,所以仍是儘可能避免使用。
let obj = { name:"July" } function Person() { with(obj){ console.log(name +"去吃飯",name +"去睡覺",name +"去打籃球") } } Person()