遊戲陪玩原始碼前端圖片載入優化的各種技巧

雲豹科技程式設計師發表於2021-10-19

目前遊戲陪玩原始碼的前端圖片載入優化技術有很多,像懶載入/預載入,img上的srcset屬性以及picture標籤,新的圖片編碼格式以及Client Hints等。

Client Hints

顧名思義,client hints是指通過遊戲陪玩原始碼客戶端資訊來進行資源選擇的一種方法,由於用在圖片載入上,所以這裡的遊戲陪玩原始碼客戶端資訊一般是指圖片寬度,DPR(device pixel ratio)和視窗寬度(viewport width)。其基本原理是在http傳輸中加入相關header,讓伺服器好選擇一張合適的圖片返回給客戶端。

如何使用

要使用client hints,需要在新增一個meta標籤,內容如下:

<meta http-equiv="Accept-CH" content="DPR, Viewport-Width">

然後當遊戲陪玩原始碼向伺服器請求圖片的時候,就會附帶上兩個額外的header:

DPR: 2Viewport-Width: 535

由此可知,遊戲陪玩原始碼客戶端的畫素密度是2,Viewport的寬度是535畫素,這樣伺服器就能通過客戶端資訊來傳送不同的圖片了,這些圖片既可以是已經儲存的不同解析度的圖片,也可以即時地對圖片大小進行轉換,這取決於儲存和計算之間的權衡。

相容性

Cient Hints不是一個很新的東西,但它的相容性卻一般,可以作為一種漸進式使用者體驗的方法。
下面是它的遊戲陪玩原始碼相容性:
在這裡插入圖片描述
可以看到,除了Chrome和Opera以及新版Edge之外全軍覆沒,所以這種方法見過的人少,用過的人更少了。下面就介紹一個一種更常用的方法。

Responsive images

如果說client hints是在伺服器上對圖片進行區分,那麼Responsive images就是將這個過程放到遊戲陪玩原始碼上了。一般來說,組成Responsive images的標籤和屬性有img標籤上的srcset,sizes屬性,以及picture和source標籤。

如何使用

關於srcset和sizes

理解這兩者的最好方法就是用一個簡單的例子,下面這個例子來自MDN:

<img srcset="elva-fairy-480w.jpg 480w,
             elva-fairy-800w.jpg 800w"
     sizes="(max-width: 600px) 480px,
            800px"
     src="elva-fairy-800w.jpg"
     alt="Elva dressed as a fairy">

首先,sizes決定了一個叫插槽的東西,顧名思義,就是留給這個圖片的空間是多少,假設我放置這個圖片的容器是800px,需要填滿這個容器,那麼就應該寫成sizes=“800px”,同時,sizes支援使用媒體查詢來區分不同的slot,不同的slot使用逗號分開,如上面的寫法,意思就是當viewport寬度大於600px的時候,slot寬度為800px,否則為480px,當沒有圖片剛好匹配slot寬度時,瀏覽器會選擇第一張比slot寬的圖片。
其次,srcset決定了可以使用的圖片來源,如上面的寫法,就是說遊戲陪玩原始碼可以按照slot的寬度從寬度分別為480px和800px的兩張圖片中自動進行選擇。
最後,src屬性是當瀏覽器不支援srcset時候進行回退使用。
需要注意的是,srcset每張圖片後面跟的寬度單位是w,代表圖片檔案的實際寬度,也即img.naturalWidth的寬度,為什麼要用原生解析度呢,其實道理很簡單,我們可以想一下如果圖片後面跟著的是css pixel的話,那麼實際上游戲陪玩原始碼是無法知道最合適的圖片的,因為不同裝置的DPR不一樣,假設當前裝置DPR為1,srcset=“elva-fairy-480w.jpg 480px”,表明想在slot寬度為480px的時候使用這張圖片,但如果另一臺裝置DPR為2,很顯然圖片就會糊了,這樣就達不到想要的效果了。所以最好的方式是告訴瀏覽器圖片的原始解析度,讓它通過DPR和slot寬度自行判斷需要使用哪個圖片。

不需要使用sizes的情況

實際上,sizes並不是必須的,我們知道img作為替換元素,在沒有css規定的情況下,它的大小由內容(也就是圖片本身決定),也就是說遊戲陪玩原始碼在實際載入完成圖片之前,都是無法知道img佔的位置大小的,所以才需要sizes這個屬性顯式地規定slot的寬度,也就是程式設計師期望載入完圖片之後佔的寬度。
但如果使用css規定了img的大小:

img {
  width: 300px;
  height: auto;}

這樣的話,遊戲陪玩原始碼就能夠知道img佔的寬度,sizes也就變得不是必須了。

關於picture標籤

picture標籤實現的是根據媒體選擇區分不同圖片來源的功能:

<picture>
  <source media="(max-width: 799px)" srcset="elva-480w-close-portrait.jpg">
  <source media="(min-width: 800px)" srcset="elva-800w.jpg">
  <img src="elva-800w.jpg" alt="Chris standing up holding his daughter Elva">
</picture>

其中source標籤標明可以選擇的圖片來源,遊戲陪玩原始碼會使用第一個匹配的source作為圖片來源。如果像上面這樣寫,那麼視窗寬度在大於等於800px的時候會使用第二個source,否則使用第一個source。

在最後一個source後面要加上一個img標籤,一是為了在沒有source匹配時有預設顯示的圖片,二是當遊戲陪玩原始碼不支援picture時可以平穩回退。

picture和srcset的區別

從上面的程式碼來看,picture和srcset實現了相似的功能,但實際上它們是很不一樣的,從遊戲陪玩原始碼匹配的邏輯來看可以很明顯地區分它們:

picture: media -> sourcesrcset: media -> slot -> source

可以看到srcset匹配的過程中多了一個slot,也就是說srcset匹配的圖片依據的是圖片所佔空間,而picture匹配依據的是螢幕寬度。
同時picture可以根據圖片格式進行選擇:

<picture>
  <source srcset="mdn-logo.svg" type="image/svg+xml">
  <img src="mdn-logo.png" alt="MDN">
</picture>

如果遊戲陪玩原始碼不支援svg,那麼就會使用img中的png影像。

相容性
在這裡插入圖片描述

從相容性來看,Responsive images明顯比Client Hints好的多,除了不爭氣的IE以外大部分新瀏覽器都支援。

圖片格式

圖片格式是優化遊戲陪玩原始碼圖片載入的重要方式之一,除了常用的png/jpeg影像之外,現在常用的高壓縮比+高質量的圖片編碼格式有WebP和AVIF等。

WebP

webp是Google搞得一種基於vp8視訊幀編碼的圖片編碼格式,前期相容性一般,現在除了IE和safari之外的新瀏覽器大部分都支援:
在這裡插入圖片描述

AVIF

AVIF由開源組織AOMedia開發,Netflix、Google與Apple均是該組織的成員

有大公司撐腰,AVIF可以說前景比較光明,但其目前的原生相容性不佳:
在這裡插入圖片描述
不過好在其有一個polyfill:Kagami/avif.js
這個polyfill使用service worker劫持fetch事件然後對avif圖片進行處理,所以頁面中的img標籤可以直接引用avif檔案:

<body>
  <!-- Register worker -->
  <script src="reg.js"></script>
  <!-- Can embed AVIF with IMG tag now -->
  <img src="image.avif">
  <!-- Or via CSS property -->
  <div style="background: url(image2.avif)">
    some content  </div></body>

當然,前提是需要遊戲陪玩原始碼支援service worker。

好了,以上便是“遊戲陪玩原始碼開發,前端圖片載入優化的各種技巧”的全部內容,希望對大家有幫助。

本文轉載自網路,轉載僅為分享乾貨知識,如有侵權歡迎聯絡雲豹科技進行刪除處理
原文連結:


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69996194/viewspace-2838159/,如需轉載,請註明出處,否則將追究法律責任。

相關文章