異步加載CSS

說到加載 CSS 這種事兒不是很簡單嗎?像這樣咯:css

<link rel="stylesheet" href="cssfile.css">

這不就完事兒了嘛!瀏覽器

這樣是沒錯!可是這樣有問題啊——會阻塞渲染!瀏覽器看到這個標籤就會停下手裏的活兒,去加載 CSS 並解析了。緩存

固然了,若是這個 CSS 文件是接下來要渲染的內容所需的,那無可厚非,必須先要有了這個 CSS 才能接着渲染,阻塞也是情理之中。app

但實際的狀況倒是,咱們不少 CSS 內容其實在首屏的時候是不須要,起碼等到後續纔會使用,那麼這個時候這些 CSS 這樣加載去阻塞內容渲染就不對了。異步

也就是說,針對優先級不那麼高的(暫時用不到)CSS,就應該要想辦法讓它異步加載,不要阻塞瀏覽器渲染。ide

那麼怎麼弄呢?fetch

老方子

如今介紹第一種老辦法:經過 JS 動態插入 link 標籤來異步載入 CSS 代碼,就像這樣:this

var myCSS = document.createElement( "link" );
myCSS.rel = "stylesheet";
myCSS.href = "mystyles.css";
document.head.insertBefore( myCSS, document.head.childNodes[ document.head.childNodes.length - 1 ].nextSibling );

這個很好理解吧,就是後續 JS 執行的時候,去建立一個 link 標籤來加載 CSS 代碼。spa

還有一個辦法呢就是利用 link 上的 media 屬性,將它設置爲和用戶當前瀏覽器環境不匹配的值,好比:media="print",甚至能夠設置爲一個徹底無效的值 media="jscourse" 之類的。code

這樣一來,瀏覽器就會認爲這個 CSS 文件優先級很是低,就會在不阻塞的狀況下進行加載。可是爲了讓 CSS 規則生效,最後仍是要將 media 值改對才行。因此,這個辦法落實到代碼就是這樣:

<link rel="stylesheet" href="cssfile.css" media="jscourse" onload="this.media='all'">

 

介紹完了老方子,咱們再來看看新葯方。

新的異步加載方式

新方子就是利用規範中新增長的 rel="preload" ,就像這樣:

<link rel="preload" href="cssfile.css" as="style" onload="this.rel='stylesheet'">

經過 preload 屬性值就是告訴瀏覽器這個資源文件隨後會用到,請提早加載好。可是這只是加載,因此你看當它加載完畢後,仍是須要將 rel 值改回去,這才能讓 CSS 生效。

你是否是想問:這和老方子也沒多大區別嘛!

看上去確實如此,可是呢,語義上更加好一些。另外就是你仔細點就會發現 as="style"這個屬性,因此 preload 不單單能夠用在 CSS 文件上,而是能夠用在絕大多數的資源文件上。好比:JS 文件

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

而後要用的時候,就建立一個 script 標籤指向它:

var script = document.createElement("script");
script.src = "scriptfile.js";
document.body.appendChild(script);

這個時候瀏覽器就直接從緩存中拿這個文件了,不會再發請求了,由於此前已經加載好了。

那麼 preload 中的 as 屬性支持哪些資源文件呢?下面這些均可以:

  • audio
  • document
  • embed
  • fetch
  • font
  • image
  • object
  • script
  • style
  • track
  • worker
  • video

是否是火燒眉毛想去試試了?告訴你個壞消息,目前 preload 只有 Chrome 是完美支持的,其餘瀏覽器慘不忍睹,哎!

相關文章
相關標籤/搜索