網路速度很慢,但是有一些簡單的策略可以使網站變快。其中之一就是將關鍵的css內聯插入到網頁的標籤, 但是,如果您的網站包含數百頁,甚至更糟糕的是包含數百種不同的模板,那麼你該怎麼做呢? 你不能手動做這件事。 Dean Hume解釋了一個簡單的方法來完成它。如果您是經驗豐富的網頁開發人員,您可能會發現這篇文章顯而易見,並且不言而喻,但對於您的客戶和初級開發人員來說,這是一個很好的選擇。— Ed.
提供快速,流暢的網路體驗是如今構建網站的重要部分。 大多數情況下,我們開發網站,而不去理解瀏覽器實際在做什麼。 瀏覽器是如何從我們建立的HTML,CSS和JavaScript渲染我們的網頁? 我們如何使用這些知識來加速我們網頁的渲染?
在 SmashingMag閱讀更多:
如果我想快速提高網站的效能, Google的 PageSpeed Insights 工具是我的首選。 當嘗試檢測網頁並找到需要改進的區域時,這非常有用。 您只需輸入要測試的頁面的URL,該工具就會提供一系列效能建議。
如果您曾經通過PageSpeed Insights工具執行自己的網站,您可能會遇到以下建議。
CSS and JavaScript 會阻塞頁面的渲染。 (檢視大圖)
我必須承認,我第一次看到這個時有點困惑。 該建議的內容如下:
“如果以下資源未下載完成,您的頁面上的任何內容都不會被渲染。 嘗試延遲或非同步載入阻塞資源,或直接在HTML中內聯嵌入這些資源的關鍵部分。“
幸運的是,解決這個問題比看起來更簡單! 答案在於CSS和JavaScript在您的網頁中的載入方式。
什麼是關鍵CSS?
對CSS檔案的請求可以顯著增加網頁呈現所需的時間。 原因是預設情況下,瀏覽器將延遲頁面呈現,直到它完成載入、解析和執行所有在“頁面”中引用的CSS檔案。 這樣做是因為它需要計算頁面的佈局。
不幸的是,這意味著如果我們有一個非常大的CSS檔案,並且需要一段時間才能完成下載,我們的使用者將在瀏覽器開始呈現頁面之前等待整個檔案被下載下來。 幸運的是,有一個巧妙的技術,使我們能夠優化我們的CSS的傳輸並減輕阻塞。這種技術被稱為優化關鍵渲染路徑。 關鍵渲染路徑表示瀏覽器呈現頁面的所有必須步驟。 我們想要找到最小的阻塞CSS集合 ,或者關鍵 CSS,以使頁面顯示給使用者。 關鍵資源是可能阻塞頁面首屏呈現的所有資源。 這背後的想法是,網站應該在前幾個TCP資料包響應中為使用者獲取第一個螢幕的內容(或“首屏”內容)。 想要簡要了解如何在網頁上工作,請檢視下面的圖片。
關鍵 CSS是向使用者呈現第一屏的內容所需CSS的最少集合。 (檢視大圖)
在上面的示例中,網頁的關鍵部分只是使用者在首次載入頁面時可以看到的內容。 這意味著我們只需要載入最小量的CSS來渲染頁面頂部的內容。 對於CSS的其餘部分,我們不需要擔心,因為我們可以非同步載入它。
我們如何確定關鍵CSS? 確定頁面的關鍵CSS是相當複雜的,需要您瀏覽網頁的DOM。 接下來,我們需要確定當前應用於檢視中每個元素的樣式列表。 手動執行此操作將是一個繁瑣的過程,但是一些很棒的工具可以自動執行這個過程。
在本文中,我將向您展示如何使用關鍵的CSS提高您的網頁呈現速度,並介紹一個可以幫助您自動執行此過程的工具。
關鍵CSS實踐
使用關鍵CSS,我們需要改變我們處理CSS的方式 – 這意味著將其分成兩個檔案。 對於第一個檔案,我們僅提取渲染上述內容所需的最小CSS集,然後將其內聯在網頁中。 對於第二個檔案或非關鍵的CSS,我們非同步載入它,以免阻塞網頁。
一開始似乎有點奇怪,但是通過將關鍵的CSS整合到HTML中,我們可以消除關鍵路徑中的額外的請求。 這使我們能夠在一次請求中提供關鍵的CSS,以儘快向使用者展示頁面。
下面的程式碼給出了一個基本的例子。
1 2 3 4 5 6 7 8 9 |
<!doctype html> <head> <style> /* 內聯CSS */ </style> ``<script> loadCSS('non-critical.css'); </script>`` </head> <body> ...body goes here </body> </html> |
如上,我們將關鍵CSS內聯在style
標籤中。然後,使用 loadCSS();
非同步載入非關鍵的CSS。 這很重要,因為我們在展示首屏後載入繁重的(非關鍵) CSS。
起初,這似乎是一場噩夢。 為什麼要手動在每個頁面內嵌CSS片段? 但是有一個好訊息,這個過程可以自動化,在這個例子中,我將執行一個名為Critical 的工具。 Addy Osmani 創造,它是一個允許您自動提取和內聯關鍵路徑CSS到HTML中的的Node.js包。 我將把這個工具和 Grunt 一起介紹, Grunt是一個JavaScript 任務執行器, 自動處理CSS。 如果你之前沒聽過Grunt, 這個網站有一些非常 詳細文件, 以及配置專案的各種解釋。我之前部落格介紹過這個工具.
開始
我們先從Node.js控制檯開始,並導航到您的網站的路徑。 通過在您的控制檯中輸入以下命令來安裝Grunt命令列介面:
1 2 |
npm install -g grunt-cli |
這將把grunt
命令放在你的系統路徑中,允許從任何目錄執行它。 接下來,使用以下命令安裝Grunt任務執行程式:
1 2 |
npm install grunt --save-dev |
然後安裝 grunt-critical 外掛.
1 2 |
npm install grunt-critical --save-dev |
接下來,您需要建立專案任務配置的Gruntfile。 看起來有點像下面的程式碼。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
module.exports = function (grunt) { grunt.initConfig({ critical: { dist: { options: { base: './' }, // The source file src: 'page.html', // The destination file dest: 'result.html' } } }); // Load the plugins grunt.loadNpmTasks('grunt-critical'); // Default tasks. grunt.registerTask('default', ['critical']); }; |
在上面的程式碼中,我配置了 Critical 外掛來檢視我的page.html檔案。 然後它會根據給定的頁面處理CSS來計算關鍵的CSS。 接下來,它將內聯關鍵的CSS並相應地更新HTML頁面。
通過在控制檯中輸入grunt
來執行外掛。
使用Grunt自動檢測網路效能。(檢視大圖)
如果您導航到該資料夾,則應該會注意到一個名為result.html的檔案,其中包含內聯的關鍵CSS,而剩餘的CSS非同步載入。 您的網頁現在就可以使用了!
在幕後, 外掛自動使用 PhantomJS, 一個無頭WebKit瀏覽器,捕獲所需的關鍵CSS。 這意味著它能夠靜默地載入您的網頁並測試最佳關鍵CSS。 這個功能還保證了外掛在不同螢幕尺寸上的靈活性。 例如,您可以提供不同的螢幕尺寸,外掛將相應地捕獲並內聯您的關鍵CSS 。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
critical: { dist: { options: { base: './', dimensions: [{ width: 1300, height: 900 }, { width: 500, height: 900 }] }, files: [ {src: ['index.html'], dest: 'dist/index.html'} ] } } |
上面的程式碼將從多個維度處理給定的檔案,並內聯相應的關鍵CSS。 這意味著您可以根據多個螢幕寬度執行您的網站,並確保您的使用者仍然擁有相同的體驗。 我們知道,使用3G和4G的移動連線可能是不穩定的 – 這就是為什麼這種技術對於移動使用者來說如此重要。
在生產環境中使用Critical
使用Critical這樣的工具是自動提取和內聯關鍵CSS的好方法,而無需改變開發網站的方式,但是如何適應真實場景? 要將新更新的檔案置於目標檔案,您只需按照通常的方式進行部署 – 無需在生產環境中更改。 您只需記住,每次構建或更改CSS檔案時,都需要執行Grunt。
我們在本文中執行的程式碼示例涵蓋了單個檔案的使用,但是當您需要處理多個檔案關鍵CSS甚至整個資料夾時會發生什麼? 您的Gruntfile可以更新以處理多個檔案,類似於下面的示例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
critical: { dist: { options: { base: './', dimensions: [{ width: 1300, height: 900 }, { width: 500, height: 900 }] }, files: [ {src: ['index.html'], dest: 'dist/index.html'}, {src: ['blog.html'], dest: 'dist/blog.html'} {src: ['about.html'], dest: 'dist/about.html'} {src: ['contact.html'], dest: 'dist/contact.html'} ] } } |
您還可以使用以下程式碼對給定資料夾中的每個HTML檔案執行任務:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
critical: { dist: { options: { base: './', dimensions: [{ width: 1300, height: 900 }, { width: 500, height: 900 }], src: '*.html', dest: 'dist/' } } } |
上面的程式碼示例可以讓您深入瞭解如何在您的網站上實現。
測試
一如以往,測試任何新的變化是非常重要的。 如果您想要測試更改,有一些很棒的工具可以線上免費使用。進到 Google’s PageSpeed Insights 並通過該工具執行您的URL。 您應該注意到,您的網頁現在不再具有任何阻塞資源,並且您的效能改進建議已經變綠 。而你可能也熟悉了另一個偉大的工具。WebPagetest
使用WebPagetest是測試您的網頁及時呈現的好方法。 (檢視大圖)
它是一個免費的工具,可以讓您從全球各個地點進行網站速度測試。 除了對您的網頁的內容進行豐富的分析性審查,如果您選擇“Visual Comparison”, 該工具將比較兩個網頁。 這是比較更新您的關鍵CSS之前和之後的結果並回放差異的好方法。
使用關鍵CSS的想法是,我們的網頁會盡快呈現,從而儘快向使用者展示內容。 測量這個的最好方法是使用 speed index. WebPagetest採用的測量方法是衡量頁面內容的視覺填充速度。SpeedIndex測量可視頁面載入的視覺進度,並計算內容繪製速度的總體得分。 比較 SpeedIndex測量通過內聯關鍵CSS之前和之後的改變。 您將對您的渲染時間的改變大吃一驚。
深入瞭解
正如大多數優化工具,對你的網站總有利弊。弊端之一是 丟失瀏覽器中的CSS快取 。 如果動態網頁更改頻繁,我們不希望快取HTML頁面 這意味著內聯CSS 每次重新下載。 需要說明的是隻列出關鍵的CSS,非同步載入剩下的非關鍵的CSS。 我們可以快取非關鍵的CSS。有很多爭論和反對關於在中內聯CSS, 瞭解更多我推薦 Hans Christian Reinl的部落格 “A counter statement: Putting the CSS in the head”。
如果您使用(CDN),也值得一提的是,您還應該 從CDN中提供非關鍵的CSS。 這樣做允許您直接從邊緣提供快取的資源,提供更快的響應時間,而不是一路路由到源伺服器來獲取它們。
對於傳統的網頁,內聯CSS的技術運作良好,但根據您的情況,可能並不總是適用。 如果您有客戶端JavaScript生成HTML怎麼辦? 如果您在單頁面應用程式上怎麼辦? 如果您儘可能多地輸出關鍵的CSS,它將提升頁面渲染效果。 瞭解關鍵CSS的工作原理及是否適用於您的網頁,這一點很重要。 我喜歡Guy Podjarny對此的立場:
“儘管有這些限制,Inline在前端優化領域仍然是一個很重要的工具。 因此,你應該使用它,但要小心,不要濫用它。“
—Guy Podjarny
在 “為什麼內聯一切不是答案”,他提供了關於什麼時候應該_什麼時候不應該嵌入CSS的好建議。
這不完美
雖然生成和內聯關鍵CSS所需的許多工具都在不斷改進,但可能還有一些需要改進的領域。 如果您發現任何錯誤,您的專案,open up an issue 或提出請求,並在GitHub貢獻專案。
為您的網站優化關鍵渲染路徑可以大大改善頁面載入時間。 使用這種技術使我們能夠使用響應式佈局,而不會影響其眾所周知的優點。 這也是確保您的頁面載入快速而不妨礙您的設計的好方法。
更多資源
如果您喜歡使用其他構建系統(如Gulp),則可以直接使用外掛,而無需下載Grunt。 還有一個有用的教程,如何使用Gulp優化基本頁面.
還有其他外掛可以提取你的關鍵CSS,比如 Penthouse,和來自Filament 公司的criticalCSS。我強烈推薦 “我們如何使RWD網站快速載入” 瞭解如何使用這個技術來確保他們的網頁儘可能快地載入。
Smashing Magazine的總編輯Vitaly Friedman寫了一篇關於Smashing Magazine如何改進表現的文章 improved the performance 。如果您想了解關於渲染路徑的更多資訊,那麼在Udacity網站上可以免費使用 一個有用的課程。 Google Developers website 也有關於 優化CSS傳輸的內容。 Patrick Hamman 寫了一篇部落格關於 如何識別關鍵的CSS建立更快的網頁。
預設情況下,您是否在您的專案中嵌入關鍵CSS? 你使用什麼工具? 你遇到什麼問題? 歡迎在文章下方分享你的經驗!
(il, rb, ml, og)