提高 JavaScript 性能【從URL解析到DOM點操作】

前公司創業公司創業還沒成功,新制度倒是層出不窮,紛紛擾擾。心裏不快,乾脆裸辭跑回廣州。面試了兩天就確定了新公司,從小程序又轉戰Vue。

許久沒碰Vue,手生得很啊!很感謝新公司CTO傑哥給我機會讓我快速瞭解公司業務,上手項目。雖然剛進公司不到一個月,但是得到機會見識了架構好的代碼,一個月內多次刷新對前端的認知。難得本月業務寫完大半,遂抽空開始學JavaScript性能相關,於是有此文。

本文是我學習Web性能所整理的文章。主要讀物:《高性能JavaScript》、《你不知道的JS》、MDN網站以及網絡上一些解讀文章。

頁面加載與運行過程

1、DNS解析:將URL解析爲IP地址

2、TCP連接:三次握手與四次分手

3、各種HTTP請求:接口請求、JavaScript加載等

4、服務端的響應:服務端響應請求並返回數據

5、瀏覽器解析:瀏覽器對數據進行解析

6、頁面渲染:解析的數據通過DOM樹、CSS樹與JavaScript生命週期渲染過程生成最終的頁面

7、定時任務與後置JavaScript加載:JavaScript會在特定生命週期/業務期間被調用,影響頁面

通過上面的過程我們瞭解了 從發送URL請求到頁面渲染完成/事件觸發 期間發生的事情,而 1-4 是涉及服務端和客戶端雙方合作部分,我們先關注 5-7 ,也就是我們前端工程師能獨立優化性能的部分

首先,我們在加載頁面到渲染頁面之前,頁面呈現出來的是一片空白。我們要做的第一件事,就是儘可能壓縮這段空白頁面出現的時間。而我們知道瀏覽器讀取頁面代碼是自頂向下按順序執行的。那麼我們就得先搞清楚一件事。

瀏覽器在什麼時候開始渲染頁面?

瀏覽器是在讀取 body 節點後纔開始渲染頁面。也就是說,執行 head 標籤內語句的整個過程,頁面都是一片空白,所以我們儘可能的將 JavaScript 與 CSS 渲染代碼放在 body 底部。

那麼我們是不是要將全部的 JavaScript 與 CSS 代碼置於 body 呢?

不是的,我們需要將頁面渲染所相關的 JavaScript 與 CSS 代碼放在 head 標籤內,而耗時操作與業務代碼、定時任務等都放在 body 底部加載即可。另一方面,隨着項目不斷擴充業務場景,載入的 JavaScript 與 CSS 越來越多,我們就需要考慮多兩個問題。

JavaScript 如何按期待的順序載入與執行?JavaScript 拆分載入好還是合併載入好?

第一個問題有許多種解法,包括定時器、異步回調等,我個人覺得最好的方式是使用 Promise 進行鏈式調用,清晰明瞭。但是這樣鏈式調用了就會產生一個新的問題,我們爲什麼不將代碼合併成同一段 JavaScript 代碼載入,而是要分成多鏈式載入呢?我們都知道,每次載入 JavaScript 和載入完成後的編譯都是一項耗時操作,我們如果將多段 JavaScript 合併成一段後載入,不就可以更快地獲取想要的頁面效果嗎?

答案是肯定的。多段 JavaScript 合併後,載入速度將大大提高。因爲我們將略去絕大部分 JavaScript 執行時間,那爲什麼基本沒有團隊這麼做呢?答案很簡單,因爲在 JavaScript 加載過程中,頁面是處於“卡頓”狀態,這將非常嚴重影響用戶體驗。那我們又希望提高性能,又無法整合 JavaScript,這可咋整啊?

耗時代碼拆分單獨運行,同業務代碼片段儘量整合,涉及 DOM 操作的代碼預加載

耗時操作的代碼,例如發送請求、Canvas 繪圖等,只能單獨加載,有時候甚至還得做多一步操作,例如加個 Loading、進度條等;同業務代碼,例如獲取接口數據後進行的後續操作,(修改DOM節點等)儘量合併,此時代碼加載將無法分隔開來,如果中途停止 JavaScript 加載,而是讓用戶進行操作,用戶會覺得他之前進行的操作毫無反饋,從而影響了用戶體驗;涉及 DOM 操作的代碼,例如放大圖片功能,popup 層展示功能等,如果等到需要的時候才加載 JavaScript 代碼將造成明顯卡頓,我們可以通過代碼預加載來避免這種狀況。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章