如何更快地構建與渲染

上一篇中,我詳細描述了瀏覽器渲染的過程,那麼,如何來提升渲染效率,使頁面更快的加載完成呢。
我將這些方法分爲幾部分分別介紹。

CSS部分

1. 媒體類型和媒體查詢

  將CSS分割爲片段,對於不同的瀏覽器,不同的終端,不同的閱讀模式,應用不同的CSS樣式表。如果將這些內容寫到統一個文件中,瀏覽器需要下載並解析他們。所以我們應該將這些內容通過對link元素的media屬性來指定:

<head>
<link rel="stylesheet" type="text/css" href="theme.css" />
<link rel="stylesheet" type="text/css" href="print.css" media="print"/>
<link rel="stylesheet" type="text/css" href="style.css" media="(min-width:40em)"/>
</head>

  注意:無論是否需要解析使用,瀏覽器都會下載這些樣式表。
  

2. 編寫高效的CSS

  關鍵選擇器,是一個複雜的CSS選擇器中最右邊部分。它是瀏覽器最先尋找的。寫CSS代碼的時候,關鍵選擇器是能否高效的決定因素。

#content .intro {..}

  瀏覽器會尋找.intro的實例(可能會很多),然後沿着DOM樹向上查找,確定剛纔找到的實例是否在一個帶有ID爲content的容器裏面。
  但是,下面的選擇器就有點糟糕啦:

#content * {..}`

  這個選擇器所做的是選擇所有在頁面上的單個元素(是每個單個的元素),然後去看看它們是否有一個 #content 的父元素。這是一個非常不高效選擇器因爲它的關鍵選擇器執行開銷太大了。
  更多高效選擇器的知識戳這裏

3.GPU加速

  利用CSS3 transform:translate3d開啓硬件加速,提升網站動畫渲染性能。
  更多相關知識戳這裏

JS部分

1. 異步加載

  DOM 扮演着兩種角色:它既是 HTML 文檔的對象表示,也充當着外界(比如JavaScript)和頁面交互的接口。
  js腳本的加載會阻塞DOM樹的構建,因爲有些js腳本需要操作DOM,這將改變DOM樹。js腳本還可以查詢關於 DOM 的一些東西,如果是在 DOM 還在在構建的時候,它可能會返回意外的結果。這些腳本如果在DOM樹構建完成再操作,減少了對瀏覽器渲染速度的影響。
  deferasync 屬性提供給開發者一個方式來告訴瀏覽器哪些外部腳本(包含src的腳本)是需要異步加載的。他們都告訴瀏覽器在“後臺”加載腳本的同時繼續解析 HTML,並在腳本加載完執行。
  defer 和 async 之間的不同是他們開始執行腳本的時機的不同。
  defer 比 async 要先引入瀏覽器。它的執行在解析完全完成之後纔開始,它處在DOMContentLoaded事件之前。 它保證腳本會按照它在 HTML 中出現的順序執行,並且不會阻塞解析。
  async 腳本在它們完成下載完成後的第一時間執行,它處在 window 的load 事件之前。 這意味着有可能(並且很有可能)設置了 async 的腳本不會按照它們在 HTML 中出現的順序執行。這也意味着他們可能會中斷 DOM 的構建。設置async 的腳本的加載有着較低的優先級。他們通常在所有其他腳本加載之後才加載,而不阻塞 DOM 構建。然而,如果一個指定async 的腳本很快就完成了下載,那麼它的執行會阻塞 DOM 構建以及所有在之後才完成下載的同步腳本。

2.預加載

Preloader 簡介
  HTML 解析器在創建 DOM 時如果碰上同步腳本(synchronous script),解析器會停止創建
  DOM,轉而去執行腳本。所以,如果資源的獲取只發生在解析器創建DOM時,同步腳本的介入將使網絡處於空置狀態,尤其是對外部腳本資源來說,當然,頁面內的腳本有時也會導致延遲。

  預加載器(Preloader)的出現就是爲了優化這個過程,預加載器通過分析瀏覽器對 HTML文檔的早期解析結果(這一階段叫做“令牌化(tokenization)”),找到可能包含資源的標籤(tag),並將這些資源的 URL收集起來。令牌化階段的輸出將會送到真正的 HTML 解析器手中,而收集起來的資源 URLs會和資源類型一起被送到讀取器(fetcher)手中,讀取器會根據這些資源對頁面加載速度的影響進行有次序地加載。
  preload使開發者能夠自定義資源的加載邏輯,且無需忍受基於腳本的資源加載器帶來的性能損失。通過這一方法我們告訴瀏覽器開始獲取某一特定資源,畢竟我們是作者,知道瀏覽器很快就會用到這一資源。
  你只需寫上:

<link rel="preload" href="very_important.js" as="script">

  你可用as告訴瀏覽器你讓他預加載文件的類型:

“script” “style” “image” “media” “document”

  忽略 as 屬性,或者錯誤的 as 屬性會使 preload 等同於 XHR 請求,瀏覽器不知道加載的是什麼,因此會賦予此類資源非常低的加載優先級。
  關於預加載,我們已經有<link rel=“prefetch”>,而且瀏覽器支持情況還不錯。但是他的作用是告訴瀏覽器加載下一頁面可能會用到的資源,不是當前頁。
  web 字體是較晚才能被發現的關鍵資源(late-discovered critical resources)中常見的一類 。有了 preload 這個標準,簡單的一段代碼就能搞定字體的預加載。

<link rel="preload" href="font.woff2" as="font" type="font/woff2" crossorigin>

  需要注意的一點是:crossorigin 屬性是必須的,即便是字體資源在自家服務器上,因爲用戶代理必須採用匿名模式來獲取字體資源。

 
  參考文章:
 1. 關於Preload,你應該知道些什麼
 2. 更快地構建 DOM: 使用預解析, async, defer 以及 preload

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