圖片載入時使用 SVG 作為圖片 placehold

簡評:使用 SVG 作為佔位符不但可以減少數據大小還可以達到不錯的顯示效果。

不同類型的圖片 placehold

對於圖片佔位符,通常我們會使用以下幾種處理方式。

  • 保持圖像為空:這樣可以保證內容不會出現跳動。
  • 默認佔位符:比如說用戶想要查看個人資料顯示頭像內容,如果請求失敗或者沒有上傳過圖片,那麼通常會使用默認佔位符(這種佔位符一般會使用 SVG 資源)。
  • 純色:從圖像中獲取顏色,並作為背景顏色。圖片在過度是時候回顯得比較平滑(pinterest 就是使用這種方式)。
  • 模糊的圖像:這種方式會獲取原圖的縮略圖並對其進行渲染,等圖片載入完成再過度到原圖。

以上是我們比較常見的處理圖片 placehold 的方法。還有另外一種方式是使用 SVG。

基於 SVG 的 placehold

SVG 是矢量圖像的理想選擇,但是大部分情況是需要顯示點陣圖,我們需要考慮的是如何將點陣圖轉換成矢量圖,下面提供幾種轉換方案。

  1. 使用矢量繪製原圖的輪廓,具體代碼可以參考 demo。

2. 將原圖轉換為色塊圖,具體代碼可以參考 demo。

https://www.zhihu.com/video/916036903155924992

  • Primitive

這裡推薦 Primitive 這個庫,這個庫可以將點陣圖生成矢量圖,我們來看看效果。

上圖分別使用不同數量的形狀來繪製原圖。使用矢量圖作為 placehold 有一個很好的優點是小,例如上圖 10 個圖形的矢量圖僅僅只佔了 1030 個位元組,當通過 SVGO 來傳輸時,代碼還能減少到 640 個位元組。

<svg xmlns =http://www.w3.org/2000/svgwidth =1024height =1024> <path fill =「#817c70d =M0 0h1024v1024H0z/> <g fill- opacity =「。502> <path fill =「#03020fd =M178 994l580 92L402-62/> <path fill =「#f2e2bad =M638 894L614 6l472 440/> <path fill =「# fff8bed =M-62 854h300L138-62/> <路徑填充=」#76c2d9d =M410-62L154 530-62 38/> <路徑填充=」#62b4cfd =M1086-2L498- 305148 508/> <path fill =」#010412d =M430-2l196 52-76 356/> <path fill =」#eb7d3fd =M598 594l488-32-308 520/> <path fill =「#080a18d =M198 418l32 304 116-448/> <path fill =「#3f201dd =M1086 1062l-344-52 248-148/> <path fill =「#ebd29fd = M630 658l-60-372 516 320/> </ g> </ svg>

要達到滿意的效我們就必須使用更多的圖形來繪製它,如果用 100 個圖形來繪製點陣圖,生成的 SVG 大概有 8kB(SVGO 大概 5KB)。隨著圖形數量的增加,大小也會隨之增加。

  • SQIP

這是一種折中處理方式,我們可以理解為 Primitive 和高斯模糊的簡單疊加,這種方式我可以使用少量的圖形塊就能達到我們滿意的效果。

上圖輸出的 SVG 大小為 900 位元組。

<svg xmlns =「 http://www.w3.org/2000/svg 」viewBox =「0 0 2000 2000」> <filter id =「b」> <feGaussianBlur stdDeviation =「12」/> </ filter> <路徑填充=「#817c70」d =「M0 0h2000v2000H0z」/> <g filter =「 url(#b)「transform =」translate(4 4)scale(7.8125)「fill-opacity =」。5「> <ellipse fill =」#000210「rx =」1「ry =」1「transform =」matrix(50.41098 -3.7951 11.14787 148.07886 107 194.6)「/> <ellipse fill =」#eee3bb「rx =」1「ry =」1「transform =」matrix(-56.38179 17.684 -24.48514 -78.06584 205 110.1)「/> <ellipse fill =」#fff4bd 「rx =」1「ry =」1「transform =」matrix(35.40604 -5.49219 14.85017 95.73337 16.4 123.6)「/> <ellipse fill =」#79c7db「cx =」21「cy =」39「rx =」65「 ry =「65」/> <ellipse fill =「#0c1320」cx =「117」cy =「38」rx =「34」ry =「47」/> <ellipse fill =「#5cb0cd」rx =「1」 ry =「1」transform =「矩陣(-39.46201 77.24476 -54.56092 -27.87353 219.2 7.9)「/> <path fill =」#e57339「d =」M271 159l-123-16 43 128z「/> <ellipse fill =」#47332f「cx =」214「 cy =「237」rx =「242」ry =「19」/> </ g> </ svg>

  • 剪影

Mikael Ainalem 分享了一個 codepen,使用雙色輪廓作為 placehold,結果效果非常好:

上面這種 SVG 是通過手繪得到的,不過我們也可以使用自動化工具自動生成。

  • node-potrace (js)可以將原圖轉換成矢量圖。

  • Craft 3 CMS 也添加了對剪影的支持 —— Potracio (php)。
  • image-trace-loader 可以追蹤圖片資源,然後導入生成的 img/svg+xml URL

原文:How to use SVG as a Placeholder, and Other Image Loading Techniques

推薦閱讀:前端開發備忘錄(合集)

歡迎關註:知乎專欄「極光日報」,每天為 Makers 導讀三篇優質英文文章。


推薦閱讀:

TAG:前端开发 | 网页设计 | 前端性能优化 |