我的大部分性能優化工作都集中在JavaScript和CSS上,從早期的Move Scripts to the Bottom和Put Stylesheets at the Top規則。為了強調這些規則的重要性,我甚至說過,“JS和CSS是頁面上最重要的部分”。
幾個月後,我意識到這是錯誤的。圖片才是頁面上最重要的部分。
我關注JS和CSS的重點也是如何能夠更快地下載圖片。圖片是用戶可以直觀看到的。他們並不會關注JS和CSS。確實,JS和CSS會影響圖片內容的展示,尤其是會影響圖片的展示方式(比如圖片輪播,CSS背景圖和媒體查詢)。但是我認為JS和CSS只是展示圖片的方式。在頁面加載的過程中,應當先讓圖片和文字先展示,而不是試圖保證JS和CSS更快下載完成。
我優化JS和CSS的目的就是讓頁面盡快渲染。
伴著關注渲染時間的念頭,我查詢了HTTP Archive來了解我們的頁面開始渲染的時間。下面是一些衡量的數值:
從世界最快的30萬個地址的測量值中,我提取出其中的50%和90%部分。如下面展示的一樣,在頁面加載的前三分之一段時間內,沒有任何渲染動作。
表格 1. 頁面加載過程中的各個時間點頁面等待渲染的時間是整個頁面加載時間的三分之一,這個事實讓人出乎意料。HTTP Archive上的數據說明,頁面花費了32%到36%的時間來等待渲染開始。但是只需要10%的時間來獲取第一個字節。因此,浏覽器在22%到26%的時間段內,雖然已經接受到了數據,但是卻不做任何渲染。在這段時間內浏覽器通常都是在下載解析腳本和樣式—這兩者都會阻礙頁面的渲染。
曾經,浏覽器在這個時間段內(從接受到第一個字節到渲染開始)是處於空閒狀態的。這是因為舊的浏覽器中,一個腳本的下載會阻塞其他所有的資源的下載,比如IE6&7。浏覽器廠商意識到雖然浏覽器需要等待腳本下載執行完成後才能構建DOM,但是沒有理由阻塞頁面其他資源的並行下載。在2009年的IE8之後,浏覽器預加載其他資源的請求。研究表明,預加載讓頁面加載速度快了20%。今天,所有主流浏覽器都支持預加載。在這些浏覽器數據中,我展示了每個主流浏覽器最早支持預加載的版本。
(順便說一句,我認為預加載是最有效的性能提升方式。設想現在的浏覽器中腳本下載會阻塞其他資源,面對頁面上如此龐大的腳本數量,頁面的性能會糟糕到哪個程度)
這時我們又要回到 Jason Grigsby的一條tweet:
我不得不承認一點。我試圖推進響應式圖片,並且越來越傾向於鼓勵開發者來使用JS阻止預加載。
Jason指的“響應式圖片”是一項技術,使用腳本來生成圖片。通常這個技術用於實現圖片對分辨率的適應。一個例子是Picturefill。當你將“預加載”和“響應式圖片”合起來思考——預加載會提前加載圖片的SRC,但是響應式圖片技術通常又沒有SRC,或者只是有一個1×1的替代圖片。這兩項技術之間有沖突。下面有一些權衡:
接著Jason在後一條tweet中說:
讓我覺得不舒服的是,大部分結論都沒有經過測試。只是一些理論,而不是數據。
我並沒有數據來比較這兩個方式,但是HTTP Archive中開始渲染的時間占總加載時間的三分之一也說明了一些問題。似乎渲染確實被腳本阻塞了,也就是說IMG標簽還沒有被創建。那麼在1/3點後的時間裡,IMG標簽會被解析,然後JS和CSS才會執行並開始下載需要的圖片。
我認為,在頁面加載過程中初始化圖片請求太晚了,並且相對使用預加載後的效果,頁面的渲染時間確實被推遲了。再次聲明,我沒有數據來對比這兩項技術。同時,我也不確定在markup技術的響應式圖片中使用預加載會有怎樣的改觀。(Jason有篇博客文章有相關的內容,The real conflict behind <picture> and @srcset)
理想情況下,我們利用markup解決了預加載和響應式圖片之間的沖突問題。直到那時,我依然擔心這樣的技術在開發社區中大量使用會讓響應式圖片付出預加載失效的代價。我希望浏覽器可以增強預加載的效果,那麼現在和未來裡網站就能夠充分利用預加載的功能。