《前端之路》之 網頁生成的過程及對性能的影響


11: 網頁生成的過程及對性能的影響

網頁生成的過程

網頁生成過程,大致可以分成五步

1. HTML代碼轉化為DOM

2. CSS代碼轉化成CSSOM(CSS Object Model)

3. 結合DOM和CSSOM,生成一棵渲染樹(包含每個節點的視覺信息)

4. 生成布局(layout),即將所有渲染樹的所有節點進行平面合成

5. 將布局繪制(paint)在屏幕上

在這五步里面,第一步到第三部都非常快,第四步和第五步很耗時

重排和重繪

網頁生成的時候,至少會渲染一次。而我們需要關注的是用戶訪問過程中,那些會導致網頁重新渲染的行為:

· 修改DOM

· 修改樣式表

· 用戶事件(例如鼠標懸停,頁面滾動,輸入框輸入文字等)

重新渲染,就涉及重排重繪

重排(reflow)

即重新生成布局,重排必然導致重繪,如元素位置的改變,就會觸發重排和重繪。

重繪(repaint)

即重新繪制,需要注意的是,重繪不一定需要重排,比如改變某個元素的顏色,就只會觸發重繪,而不會觸發重排。

對於性能的影響

重排和重繪會不斷觸發,這是不可避免的,但是它們非常消耗資源,是導致網頁性能低下的根本原因。

提高網頁性能,就是要降低重排和重繪的頻率和成本,盡量少觸發重新渲染

大部分瀏覽器通過隊列化修改批量顯示優化重排版過程。然而有些操作會強迫刷新並要求所有計划改變的部分立刻應用。

本資料作為dom操作最佳實踐的補充

刷新率

網頁動畫的每一幀(frame)都是一次重新渲染,每秒低於24幀的動畫,人眼就能感受到停頓。一般的網頁動畫,需要達到每秒30幀到60幀的頻率,才能比較流暢

而大多數顯示器的刷新頻率是60Hz,為了與系統一致,以及節省電力,瀏覽器會自動按照這個頻率,刷新動畫。所以,如果網頁能夠做到每秒60幀,就會跟顯示器同步刷新,達到最佳的視覺效果。這意味着,一秒之內進行60次重新渲染,每次重新渲染的時間不能超過16.66ms

刷新率

FPS(frame per second),即一秒之間能夠完成多少次重新渲染

開發者工具的Timeline面板

通過JS代碼實現 FPS 的檢測

這個時候 我們拿 我去年寫的 Vuejs 中文社區的網站。來試一試

VueJs 中文社區

打開控制台執行下面的代碼:


// 返回是否 有 requestAnimationFrame 方法  1000ms 會執行 60 次
var rAF = function () {
    return (
        window.requestAnimationFrame ||
        window.webkitRequestAnimationFrame ||
        function (callback) {
            window.setTimeout(callback, 1000 / 60);
        }
    );
}();


var frame = 0;
var allFrameCount = 0;
var lastTime = Date.now();
var lastFameTime = Date.now();
  
var loop = function () {
    var now = Date.now();
    var fs = (now - lastFameTime);
    var fps = Math.round(1000 / fs);
  
    lastFameTime = now;
    // 不置 0,在動畫的開頭及結尾記錄此值的差值算出 FPS
    allFrameCount++;
    frame++;
  
    if (now > 1000 + lastTime) {
        var fps = Math.round((frame * 1000) / (now - lastTime));
        console.log(`${new Date()} 1S內 FPS:`, fps);
        frame = 0;
        lastTime = now;
    };
  
    rAF(loop);
}

loop();

然后我們看到了如下的顯示:

Mon Aug 13 2018 20:14:44 GMT+0800 (中國標准時間) 1S內 FPS: 60
Mon Aug 13 2018 20:14:45 GMT+0800 (中國標准時間) 1S內 FPS: 60
Mon Aug 13 2018 20:14:46 GMT+0800 (中國標准時間) 1S內 FPS: 55
Mon Aug 13 2018 20:14:47 GMT+0800 (中國標准時間) 1S內 FPS: 60
Mon Aug 13 2018 20:14:48 GMT+0800 (中國標准時間) 1S內 FPS: 60
Mon Aug 13 2018 20:14:49 GMT+0800 (中國標准時間) 1S內 FPS: 60
Mon Aug 13 2018 20:14:50 GMT+0800 (中國標准時間) 1S內 FPS: 58
Mon Aug 13 2018 20:14:51 GMT+0800 (中國標准時間) 1S內 FPS: 60
Mon Aug 13 2018 20:14:52 GMT+0800 (中國標准時間) 1S內 FPS: 60
Mon Aug 13 2018 20:14:53 GMT+0800 (中國標准時間) 1S內 FPS: 60
Mon Aug 13 2018 20:14:54 GMT+0800 (中國標准時間) 1S內 FPS: 56
Mon Aug 13 2018 20:14:55 GMT+0800 (中國標准時間) 1S內 FPS: 59

剛剛好 屏幕的刷新率就在 60 fps 左右, 很流暢。

寫在最后

在現在 Vue 、Recat 、 Angular 三大框架盛行的當今,最原始的 瀏覽器渲染網頁的時候就做哪些事情或許我們已經忘記了一些。

這篇文章也只是做一個基礎的記憶,網頁是如何進行渲染的,在這三大框架的下,虛擬DOM 的出現,對於網頁加載有什么優勢?

重排、重繪的時候就做哪些事情? 頁面渲染的性能瓶頸往往出現在哪里? 我們如何能夠減少這些性能消耗的操作?

這些疑問,都是這邊文件做的一個解釋。

GitHub 地址:(歡迎 star 、歡迎推薦:)

網頁生成的過程及對性能的影響


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM