我来填坑了,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的方案感兴趣,欢迎留言与我讨论!