本文展示了一種技術(shù),它能通過異步下載樣式表,以阻止它們的下載阻塞頁面的渲染,從而盡可能快的讓訪問者獲取到信息內(nèi)容。
警告! 我發(fā)這篇帖子全是好意,但是它并不負(fù)責(zé)讓讀它的人意識到下面將會遇到的問題. 社區(qū)很快地給了我許多的反饋 (有些反饋我很感激) ,而越來越明顯的是這項技術(shù)并不如我所希望的那樣穩(wěn)定. 不像我那樣的成功地對它進(jìn)行了測試和利用,許多開發(fā)者在 IE 和 Firefox 中都遇到了問題( F F測試版中直接崩潰) 而其他人則報告在 Chrome 和 Safari 中是成功的。我現(xiàn)在的建議是: 不要將其用于產(chǎn)品。我計劃處理好這些反饋,并結(jié)合任何有關(guān)的信息對本文進(jìn)行更新。
這些技術(shù)背后的原理不是新的。例如燈絲(Filament)技術(shù)組已經(jīng)發(fā)布了大量有關(guān) 加載CSS 和字體的內(nèi)容. 我寫就本文以記錄我對加載非阻塞資源的想法和觀點(diǎn)。
觸發(fā)異步樣式下載的訣竅是使用一個 <link> 元素,并 為media 屬性設(shè)置一個不可用的值 (我用的是 media="none", 不過其它的任何值也是可以的)。當(dāng)一個媒體查詢的結(jié)果值計算出來是 false 的時候,瀏覽器仍然會下載樣式表,但是不會在渲染頁面之前等待樣式表的資源可用。
CSS Code復(fù)制內(nèi)容到剪貼板
<link rel="stylesheet" href="css.css" media="none">
樣式表一下載好,media 屬性就必須被設(shè)置一個可用的值,以便樣式規(guī)則能被應(yīng)用到 html 文檔中onload 事件就可以用來將 media 屬性切換到all:
CSS Code復(fù)制內(nèi)容到剪貼板
<link rel="stylesheet" href="css.css" media="none" onload="if(media!=’all’)media=’all’">
這種加載 CSS 的方法將比標(biāo)準(zhǔn)的方法在向訪問者傳送有用信息的速度上快很多。至關(guān)重要的 CSS 加載時仍然可以用一般的阻塞方式處理 (或者你也可以為了最終的性能對它進(jìn)行內(nèi)聯(lián)處理) ,而不重要的樣式則可以慢慢下載,并在解析/渲染過程的后面一點(diǎn)的階段進(jìn)行應(yīng)用.
這一技術(shù)使用了 JavaScript,但是你也可以在一個<noscript>元素中封裝一個等價的阻塞方式的 <link> 元素來處理不能運(yùn)行 JavaScript 的瀏覽器:
CSS Code復(fù)制內(nèi)容到剪貼板
<link rel="stylesheet" href="css.css" media="none" onload="if(media!=’all’)media=’all’">
<noscript><link rel="stylesheet" href="css.css"></noscript>
這項技術(shù)有一個副作用。當(dāng)一個非阻塞的樣式表完成加載,文檔就將進(jìn)行重繪,以反映它定義的任何新的樣式規(guī)則。而注入新的樣式到頁面中會觸發(fā)內(nèi)容回流, 但這也只是在這對第一次沒有歷史緩存的頁面加載過程中會是一個問題。由于任何跟性能有關(guān)的東西,你都將要在需要控制一次回流耗費(fèi)超過潛在的速度優(yōu)勢時,進(jìn)行必要的調(diào)整。
新聞熱點(diǎn)
疑難解答