我來填坑了,CSS篇終於寫出來了,若是你沒看過前面的JS篇,能夠在這裏觀看。javascript
衆所周知,CSS的加載會阻塞瀏覽器渲染或是引發瀏覽器重繪,目前業界廣泛推薦把CSS放到
<head>
中,防止在CSS還沒加載完,DOM就已經繪製出來了,形成CSS加載完成後的重繪。那在現代瀏覽器中咱們有沒有辦法提升首屏渲染速度那?css
你是否是常常在第一次打開某個網站的時候看到這種狀況,原本的頁面是這樣的 html
實際上剛加載出來的是這樣的 html5
字體文件沒加載出來,或者加載的太慢了java
如下面這段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。瀏覽器
由於CSS已經在head中,咱們不須要爲css加preload屬性了,可是css中用到的字體文件,必定要在全部css以前proload上。
<link rel="preload" href="/webfont.woff2" as="font">
複製代碼
首頁用到的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的方案感興趣,歡迎留言與我討論!