現代瀏覽器性能優化-CSS篇

我來填坑了,CSS篇終於寫出來了,若是你沒看過前面的JS篇,能夠在這裏觀看javascript

衆所周知,CSS的加載會阻塞瀏覽器渲染或是引發瀏覽器重繪,目前業界廣泛推薦把CSS放到<head>中,防止在CSS還沒加載完,DOM就已經繪製出來了,形成CSS加載完成後的重繪。那在現代瀏覽器中咱們有沒有辦法提升首屏渲染速度那?css

你是否是常常在第一次打開某個網站的時候看到這種狀況,原本的頁面是這樣的 html

實際上剛加載出來的是這樣的 html5

字體文件沒加載出來,或者加載的太慢了java

理解CSS解析過程

如下面這段HTML爲例,解釋一遍CSS加載解析的過程。webpack

<html>
<head>
  <!-- headStyle.css中存在字體文件webfont.woff2 -->
  <link rel="stylesheet" type="text/css" href="/headStyle.css">
</head>
<body>
  <p>Text</p>
  <link rel="stylesheet" type="text/css" href="/bodyEndStyle.css">
</body>
</html>
複製代碼

瀏覽器自上而下讀取HTML文檔,當發現headStyle.css的時候,中止Parser HTML,開始下載headStyle.css,解析headStyle.css的過程當中發現字體文件webfont.woff2,開始下載webfont.woff2,並繼續解析css生成CSSStyleSheet。解析完畢後,繼續Parser HTML,當發現p標籤時,會將p標籤結合當前的CSSStyleSheet展現出來,此時用戶屏幕中已經有p標籤的內容了。當瀏覽器發現bodyEndStyle.css時,就會下載headStyle.css,解析CSS,而後更新CSSStyleSheet,這時會引發一次重繪。當字體下載完畢的時候也會引發一次重繪。git

這個過程當中,有兩個很是嚴重的問題。1、若是headStyle.css文件很大,瀏覽器須要解析不少行CSS後才能還有個字體文件須要下載,其實此時已經很晚了,字體下載時間稍長一點,就會出現我前面截圖提到的問題。2、bodyEndStyle.css中若是存在p標籤對應的樣式,那p標籤的樣式會在bodyEndStyle.css解析完成後,改變一次樣式,很影響體驗。github

如何解決這些問題那?其中也會用到一些JS篇中提到的點,若是沒看過,建議先看看。web

優化核心依舊是減小下載時間

JS篇中的預先解析DNS(dns-prefetch)依舊適用,提早解析CSS文件所在域名的DNS。瀏覽器

Preload

由於CSS已經在head中,咱們不須要爲css加preload屬性了,可是css中用到的字體文件,必定要在全部css以前proload上。

<link rel="preload" href="/webfont.woff2" as="font">
複製代碼

首頁CSS內聯,非必要CSS異步加載

首頁用到的CSS內聯寫在<head>中,其他CSS均採用異步加載,能夠採用這種本身實現的加載CSS的方法,在合適的須要時加載須要的css

function LoadStyle(url) {
  try {
    document.createStyleSheet(url)
  } catch(e) {
    var cssLink = document.createElement('link');
    cssLink.rel = 'stylesheet';
    cssLink.type = 'text/css';
    cssLink.href = url;
    var head = document.getElementsByTagName('head')[0];
    head.appendChild(cssLink)
  }
}
複製代碼

若是你使用webpack,那就更輕鬆了,使用import函數,大體以下

// 在a.js模塊中直接引入css
import 'style.css'
複製代碼
// 在須要a.js模塊的地方
improt('path-of-a.js').then(module => {})
複製代碼

webpack打包後,實際上是把style.css打包進了a.js,在異步加載a.js的時候,會將style.css中的代碼插入haed標籤中。

終極完美結構

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Faster</title>
  <link rel="dns-prefetch" href="//cdn.cn/">

  <link rel="preload" href="//cdn.cn/webfont.woff2" as="font">
  <link rel="preload" href="//cdn.cn/Page1-A.js" as="script">
  <link rel="preload" href="//cdn.cn/Page1-B.js" as="script">
  
  <link rel="prefetch" href="//cdn.cn/Page2.js">
  <link rel="prefetch" href="//cdn.cn/Page3.js">
  <link rel="prefetch" href="//cdn.cn/Page4.js">

  <style type="text/css"> /* 首頁用到的CSS內聯 */ </style>
</head>
<body>

<script type="text/javascript" src="//cdn.cn/Page1-A.js" defer></script>
<script type="text/javascript" src="//cdn.cn/Page1-B.js" defer></script>
</body>
</html>
複製代碼

JS篇中,我已經解釋過這套結構中JS的執行順序了,本篇只是加入了CSS和字體。至此,我心中終極完美的頁面HTML結構就是這樣了。

若是你對異步加載CSS的方案感興趣,歡迎留言與我討論!

擴展閱讀

相關文章
相關標籤/搜索