影響LCP的四個因素以下:css
瀏覽器獲取文檔的時間越長,用戶看到頁面的時間也會越長。較快的服務器響應時間,能夠直接改善每個頁面加載相關的指標,包括LCP。html
可使用 TTFB(Time to First Byte)
來測試服務器響應時間,你能夠經過如下手段來優化 TTFB
這個指標。vue
你是否在服務器上運行一些昂貴的查詢,佔用了服務器必定的時間?或者服務器上作了一些複雜的操做,致使頁面內容返回延後?分析和提高服務端代碼的效率能夠直接改善瀏覽器從服務端獲取數據的時間。react
比起僅僅是提供靜態頁面而言,不少服務端的web框架都會動態建立頁面。換句話說,比起直接返回一個現存的html文件,這些框架會執行一些邏輯來建立頁面。這就取決於數據庫查詢時間,或者UI框架建立組件的時間(好比: React)。大部分web框架都有提供性能指導,開發者能夠根據指導來提高處理速度。webpack
CDN全稱Content Delivery Network,是一個分佈在不一樣地域的服務器集羣。若是瀏覽器去請求數據,CDN會選擇就近的一個服務器給你返回,避免請求產生太長網絡路徑,甚至跨國。git
若是你的html是靜態的,每一次請求都不會變,能夠服務端緩存下來,不用每次從新建立頁面。經過緩存一份生成好的html到硬盤,服務端緩存能夠有效的下降TTFB,最小化資源的使用。github
service worker能夠實現這樣一個功能,優先使用緩存頁面,若是頁面有更新,會將新頁面緩存下來,下次啓動則使用新緩存。web
下圖是使用service worker的一個對比:數據庫
發往第三方服務的請求也會影響LCP,特別是當頁面關鍵內容依賴它們的時候。使用 rel="preconnect"
告知瀏覽器你的資源鏈接須要儘量地快。api
<link rel="preconnect" href="https://example.com">
也可使用 dns-prefetch
讓dns解析更快。
<link rel="dns-prefetch" href="https://example.com">
考慮到瀏覽器兼容性, dns-prefetch
能夠做爲 preconnect
的一個fallback。
<head> <link rel="preconnect" href="https://example.com"> <link rel="dns-prefetch" href="https://example.com"> </head>
preconnect通常只配置一個,dns-prefetch能夠配置多個,因此通常把最關鍵的資源配置成preconnect,好比js或者css所在的cdn域名
在瀏覽器渲染任何內容以前,須要解析html,並生成dom樹。html解析器會被任何樣式文件 <link rel="stylesheet">
以及同步腳本 <script src="main.js">
阻塞並暫停解析。
這個不只影響FCP,也影響了LCP。延遲加載非關鍵的js和css能夠加速頁面的主內容的加載。
有如下三種方法:
移除css中沒必要要的字符、註釋和空格等,通常打包工具都會自帶相應的插件。
使用開發者工具中的 Coverage
能夠找到頁面未使用的css。
優化方案:
rel="preload"
和 onload
異步加載對於初次渲染無用的css將關鍵路徑的css直接放在 <head>
中內聯引用:
這樣能夠避免一次服務器請求,讓css阻塞時間更短。
若是你沒法手動添加內聯樣式,可使用第三方庫:
有如下三種方案:
主要有如下幾種元素會影響LCP:
<img>
元素<svg>
中的 <image>
元素<video>
元素(若是定義了封面圖,會影響LCP)url()
背景圖的元素有如下幾種方式能夠保證這些文件儘快的加載:
大部分網站的最大元素都是圖片,若是能加速這些圖片的加載,能有效改善LCP。參考如下步驟:
有時候,在css或者js中聲明或者使用的一個重要資源可能比你預期的要晚獲取,好比字體文件。
若是你明確的知道某個資源須要提升優先級,可使用 <link rel="preload">
。
<link rel="preload" as="script" href="script.js"> <link rel="preload" as="style" href="style.css"> <link rel="preload" as="image" href="img.png"> <link rel="preload" as="video" href="vid.webm" type="video/webm"> <link rel="preload" href="font.woff2" as="font" type="font/woff2" crossorigin>
Chrome73版本以後,預加載同時支持響應式:
<link rel="preload" as="image" href="wolf.jpg" imagesrcset="wolf_400px.jpg 400w, wolf_800px.jpg 800w, wolf_1600px.jpg 1600w" imagesizes="50vw" >
使用 Gzip
或者 Brotli
,gzip支持度較好,brotli的壓縮比更高,但只有更新的瀏覽器才支持。
當加載頁面的主內容的時候,能夠根據用戶設備和網絡條件來加載不一樣的資源。要完成這些,可使用 Network Information, Device Memory, 和 HardwareConcurrency 的api。
if (navigator.connection && navigator.connection.effectiveType) { if (navigator.connection.effectiveType === '4g') { // Load video } else { // Load image } }
如下是一些有用的屬性:
navigator.connection.effectiveType
: 網絡類型,如4G等navigator.connection.saveData
: data-saver是否開啓navigator.hardwareConcurrency
: cpu核數navigator.deviceMemory
: 設備內存能夠直接使用 workbox 的第三方庫更方便的緩存資源,這是谷歌提供的一個工具庫。
不少網站如今都使用客戶端渲染。一些框架像 angluar, react,vue等,能夠方便的建立spa的單頁面應用,部分替代了服務器的功能。
若是你構建的應用是以上這種方式,須要注意若是你的bundle的js文件過大,會影響LCP。若是不作優化,用戶可能長時間沒法看到頁面,也沒法交互,直到js所有下載執行完。有如下幾個優化項:
與減小js阻塞時間同樣。
這樣可讓內容在服務端渲染好,而後返回給瀏覽器,以此來減小LCP。但這種方式存在一些隱患:
TTI(Time to Interactive)
預渲染是一個獨立的技術,主要是爲了解決服務端渲染的代碼複雜度。經過啓動一個無頭瀏覽器,在構建的時候就將每一個路由頁面渲染好並建立對應的html文件,這些文件也能夠和對應的js bundles一塊兒使用。
預渲染的方式,不能改善TTI,但對TTFB會比服務端渲染要更好些。
開發者工具已經能夠針對實驗數據進行這些指標的測試:
本文只是對LCP的優化作了簡單而又比較全的介紹,後面的文章會針對個別項進行單獨的介紹。