Web 第三方嵌入的最佳實踐
今天給大家?guī)硪黄?Web 第三方嵌入相關(guān)的實踐文章,在我們的網(wǎng)頁中嵌入一個第三方網(wǎng)頁是再常見不過的需求了,比如一些視頻播放、在線地圖或者廣告等等。
第三方的內(nèi)容可能會通過多種方式影響我們頁面的性能。比如它可能會阻塞渲染、與我們頁面上其他的資源爭奪網(wǎng)絡(luò)帶寬、第三方網(wǎng)頁的嵌入也可能在加載時導(dǎo)致布局偏移,進而影響我們網(wǎng)頁的 Core Web Vitals 指標(biāo)。
本文主要討論的就是在網(wǎng)頁加載第三方嵌入時可以使用的一些最佳實踐。里面的一些實例大多是海外的一些網(wǎng)站,不過里面的一些思路還是很值得借鑒的。
什么是嵌入
第三方嵌入可能是你網(wǎng)站上顯示的任何內(nèi)容,首先它滿足下面?zhèn)z條件:
- 不是你寫的
- 由第三方服務(wù)器提供
一般嵌入經(jīng)常用于以下的情況:
- 與體育、新聞、娛樂和時尚相關(guān)的網(wǎng)站會嵌入一些第三方視頻
- 將社交媒體(比如 Twitter )卡片嵌入到自己的網(wǎng)頁中
- 一些餐廳、公園或者活動頁面通常需要嵌入在線地圖
一般我們都會通過 <iframe> 來嵌入一個三方網(wǎng)頁。
第三方嵌入的性能影響
大部分流行的第三方嵌入網(wǎng)頁都會加載超過 100 KB 的 JavaScript,有時甚至高達 2 MB,它們需要更多的時間加載并且占用了主進程。
Lighthouse 或者 Chrome DevTools 這些性能監(jiān)控工具都可以幫我們衡量第三方嵌入對性能的影響。
雖然第三方嵌入給我們帶來了很大的性能影響,我們還是要用,所以我們需要一些優(yōu)化方案來盡可能的減少它們的影響。
腳本排序
在設(shè)計良好的網(wǎng)頁中,我們頁面的主 JS 肯定是要首先加載的,第三方嵌入的資源一定要放在后面。
例如,新聞頁面上的新聞肯定要在嵌入的
對第三方嵌入資源的加載請求會阻斷我們主 JS 的加載,所以第三方腳本標(biāo)簽的位置很重要。
將第三方腳本標(biāo)簽放在網(wǎng)頁的主要資源之后,并使用 async 或 defer 屬性異步加載它們。
<head>
<title>Order of Things</title>
<link rel="stylesheet" media="screen" href="/assets/application.css">
<script src="index.js"></script>
<script src="https://example.com/3p-library.js" async></script>
</head>
懶加載
一般的第三方嵌入都不是我們網(wǎng)頁的主要功能,所以它們不一定是首屏可見的,在這種情況下,我們可能需要等用戶向下滾動到這部分功能的時候再加載它。
根據(jù)不同的嵌入要求和類型,我們可能需要以下幾種方式的懶加載:
原生 <iframe> 的懶加載
使用 <iframe> 嵌入第三方網(wǎng)頁,我們可以使用瀏覽器的原生懶加載支持,這回使瀏覽器在用戶即將滾動到該標(biāo)簽之前才加載它。
<iframe src="https://example.com"
loading="lazy"
width="600"
height="400">
</iframe>
不過需要注意的是,Chrome77 以上才支持懶加載。
loading 屬性支持設(shè)置下面的值:
- lazy: 表示瀏覽器應(yīng)該延遲加載 iframe。瀏覽器會直到 iframe 接近可視區(qū)域時才加載它。
- eager:立即加載 iframe。
- auto: 由瀏覽器決定是否延遲加載這個iframe。
lazysizes
由于原生的懶加載的兼容性問題,不同的瀏覽器可能會有不一樣的行為表現(xiàn)。如果你希望更好的控制懶加載的距離閾值,或者希望跨瀏覽器提供一致的延遲加載體驗,可以使用 lazysizes 這庫。
「https://github.com/aFarkas/lazysizes」
lazysizes 是一個快速、高性能并且對 SEO 友好的懶加載庫,適用于圖片和 iframe,你可以像下面這樣使用,實現(xiàn) YouTube 視頻的嵌入:
<script src="lazysizes.min.js" async>
</script>
<iframe src="https://www.youtube.com/embed/aKydtOXW8mI"
width="560" height="315"
class="lazyload"
title="YouTube video player"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write;
encrypted-media; gyroscope; picture-in-picture"
allowfullscreen>
</iframe>
lazysizes 使用的就是瀏覽器的 Intersection Observer API 來檢測元素的可見性。
在 Facebook 中使用 data-lazy
Facebook 提供了可以嵌入的不同類型的社交插件,包括帖子、評論、視頻等,插件都包括一個 data-lazy 屬性,
用封面替換嵌入
雖然交互式的嵌入為頁面增加了可交互性和靈活性,但很多用戶可能都不會和它們進行交互。例如,并不是每個瀏覽餐廳頁面的用戶都會單擊、展開、滾動嵌入的地圖。同樣,并非每個訪問電信服務(wù)商頁面的用戶都會和聊天機器人聊天。在這些情況下,你可以通過在特定位置僅顯示外觀來完全避免加載或者延遲加載嵌入網(wǎng)頁。
是的,這個封面看起來是個嵌入的網(wǎng)頁,但是實際上它不能進行任何交互,就是能看看罷了,但是在某些場景下也能解決一些問題,我們來實際看幾個例子
使用靜態(tài)圖像
就拿剛剛地圖的例子來講,其實地圖的可交互性不是必備的,用戶完全可以跳轉(zhuǎn)到在線地圖網(wǎng)站去做更多的操作,所以這時候你完全可以只展示一個地圖截圖。
你可以使用 DevTools 的節(jié)點屏幕截圖工具來截取 iframe 的屏幕截圖:
DevTools 截圖的格式是 Webp。
使用動態(tài)圖像
這個技術(shù)可以讓你在運行時生成與交互式嵌入類似的動態(tài)圖像,比如下面幾個工具:
Maps Static API:Google Maps Static API 服務(wù)可以根據(jù)標(biāo)準(zhǔn)的 HTTP 請求中包含的 URL 參數(shù)生成地圖,并且可以將地圖作為可以顯示在網(wǎng)頁上的圖像返回。
下面是一個例子,img 被包裹在一個 a 標(biāo)簽里面,單擊一下就可以跳轉(zhuǎn)到 Google Map:
<a href="https://www.google.com/maps/place/Albany,+NY/">
<img src="https://maps.googleapis.com/maps/api/staticmap?center=Albany,+NY&zoom=13&scale=1&size=600x300&maptype=roadmap&format=png&visual_refresh=true" alt="Google Map of Albany, NY">
</a>
Twitter 截圖:類似于地圖截圖,你可以通過 Tweetpik 這樣的工具來生成一個動態(tài) Twitter 圖片。Tweetpik API 通過接收一個推文的 URL 就可以返回帶有其內(nèi)容的圖片。API 還支持一些參數(shù)來自定義圖像的背景、顏色、邊框和尺寸等等。
點擊加載
我們可以默認(rèn)情況下使用靜態(tài)或者動態(tài)的圖片來作為封面,當(dāng)用戶點擊那塊區(qū)域的時候我們再去動態(tài)加載嵌入的網(wǎng)頁,我們來看幾個例子:
- YouTube 封面
Lite-youtube-embed 是一個專門為 YouTube 生成封面的庫,它生成的圖片看起來就像一個真正的視頻播放器,當(dāng)我們?nèi)c擊它,它才會去真正加載播放器:
<lite-youtube videoid="ogfYd705cRs" playlabel="Play: Keynote (Google I/O '18)">
</lite-youtube>
另外還有一些做類似事情的庫:lite-youtube、lite-vimeo-embed、lite-vimeo。
- 聊天組件封面
React-live-chat-loader 會加載一個看起來像聊天嵌入的按鈕,但是它實際上不是嵌入的組件,而是一個圖片,當(dāng)用戶懸?;蛘唿c擊這個按鈕的時候,才會實際使用聊天組件去替換它。
布局穩(wěn)定性
雖然動態(tài)加載嵌入內(nèi)容可以提高頁面的加載性能,但有時會導(dǎo)致頁面內(nèi)容意外移動,這稱為布局偏移。
CLS 是 Core Web Vitals 之一,它會測量在頁面的整個生命周期中發(fā)生的每個意外的樣式移動的所有單獨布局更改得分的總和。
為了避免發(fā)生太大的布局偏移,我們可以通過指定 iframe 的 width 和 height 屬性或通過為將加載第三方嵌入的靜態(tài)圖片設(shè)置固定大小。
<iframe src="https://www.youtube.com/embed/aKydtOXW8mI" width="560" height="315">
</iframe>
Layout Shift Terminator
由于第三方嵌入通常會忽略它們呈現(xiàn)的最終內(nèi)容的尺寸(寬度、高度),所以它們可能會導(dǎo)致頁面上的布局發(fā)生重大的變化。如果不使用 DevTools 在各種不同的視口尺寸下手動檢查最終尺寸,這個問題可能很難解決。
我們可以通過 Layout Shift Terminator 這個工具來減少這種布局偏移,他可以幫助我們自動生成各種流行的視口的媒體查詢和容器查詢:
本文譯自:「https://web.dev/embed-best-practices/」 希望文章的內(nèi)容可以幫到你。
