網絡圖像效果性能對決
已發表: 2022-03-10隨著瀏覽器不斷提高其圖形渲染能力,在其中進行真正設計的能力越來越成為現實。 幾行代碼現在可以產生快速而引人注目的視覺效果,並且無需太多努力即可實現一致性。 與 Web 開發中的大多數事情一樣,通常有很多方法可以達到相同的效果。
在這篇文章中,我們將看看最流行的圖像效果之一,灰度,並評估 HTML 畫布、SVG、CSS 過濾器和 CSS 混合模式的易於實現和性能影響。 哪一個會贏?
關於 SmashingMag 的進一步閱讀:
- 網絡圖像效果性能對決
- HTML5:事實與神話
- 使用 ImageMagick 高效調整圖像大小
- 聰明的 JPEG 優化技術
網絡上的過濾器就像放置在圖像上的鏡頭一樣工作。 它們在瀏覽器呈現佈局和初始繪製後應用於圖像。 在支持的瀏覽器中,過濾器可以單獨應用,也可以相互疊加。 因為它們可以在初始渲染後作為圖像修改應用,並且可能是一種增強,過濾器優雅地降級,只是在不支持它們的瀏覽器中不可見。
CSS 過濾器
讓我們從最直接的生成灰度效果的方法開始:不起眼但功能強大的 CSS 過濾器。

為了達到這個效果,我們添加了一行 CSS: filter: grayscale(1)
。 此濾鏡使圖像去飽和,可用於 0 到 1(或 0% 到 100%)之間的任何數字或基於百分比的值。 注意:目前,基於 WebKit 的瀏覽器的過濾器必須以-webkit-
為前綴。 但是,諸如 Autoprefixer 之類的解決方案將消除手動添加它們的需要。
現場演示 - CSS 過濾器
.cssfilter-gray { -webkit-filter: grayscale(1); background: url('img/bird.jpg'); filter: grayscale(1); }
背景混合模式
CSS 混合模式為圖像效果組合提供了無窮無盡的選擇。 有兩種使用混合模式的方法: mix-blend-mode
屬性和background-blend-mode
屬性。
-
mix-blend-mode
是描述元素如何與其後面的內容混合的屬性。 -
background-blend-mode
用於具有多個背景的元素,並描述了這些背景之間的關係。
在我們的示例中,我們將使用background-blend-mode: luminosity
將亮度通道拉到灰色背景上,從而生成灰度圖像。 需要注意的一點是背景順序是恆定的:背景圖像必須始終在純色或漸變背景之前排序,才能正確渲染效果。 顏色必須是最後一個背景層。 這也是對不支持background-blend-mode
的舊瀏覽器的保護——圖像仍然會在沒有效果的情況下呈現。
混合模式和 CSS 過濾器的唯一區別是我們現在有多個背景,並且使用background-blend-mode: luminosity
,它從頂部圖像(鳥類測試儀)中獲取亮度值並將這些亮度值分層灰色的第二個背景。
現場演示 - 背景混合模式
.cssfilter-gray { background: url('img/bird.jpg'), gray; background-blend-mode: luminosity; }
目前,這是最新的,因此受支持最少的選項,儘管它仍然在 Chrome 和 Firefox 中運行良好,並且部分支持 Safari。 注意:Safari 支持除基於 HSL 的混合模式之外的所有混合模式:色調、飽和度、顏色和亮度。
HTML5 畫布
HTML5 <canvas>
在圖像處理方面提供了極大的靈活性,因為我們可以訪問每個單獨的像素數據(特別是通過canvasContext.getImageData
),並且可以通過 JavaScript 操作每個像素。 然而,這種方法最複雜,開銷也最大。 由於安全問題,它在跨域問題上也有一些細微差別。
要修復 Chrome 中的跨域錯誤,您的圖像需要託管在 GitHub Pages 或 Dropbox 等跨域資源共享 (CORS) 友好站點上,並指定crossOrigin="Anonymous"
。 請參閱演示的實時示例。
使用<canvas>
實現灰度效果的方法是從像素值中的任何離群值中去除紅色、綠色和藍色分量,同時保持其亮度級別(亮度)。 一種方法是對 RGB 值進行平均,如下所示: grayscale = (red + green + blue) / 3;
.

在下面的示例中,我們在圖像數據中使用格式為(R,G,B,a)
的 RGBa 值; 紅色通道是data[0]
,綠色通道是data[1]
,依此類推。 然後我們得到每個通道的亮度級別(亮度)並將它們平均以轉換圖像灰度。
現場演示 – HTML5 Canvas
SVG 過濾器
SVG 過濾器擁有最廣泛的支持(甚至在 Internet Explorer 和 Edge 中!),並且(幾乎)與直接使用 CSS 過濾器一樣容易。 您可以將它們與相同的filter
屬性一起使用。 事實上,CSS 過濾器源於 SVG 過濾器。 與畫布一樣,SVG 過濾器允許您超越二維效果的平面,因為您可以利用 WebGL 著色來創建更複雜的結果。
有幾種方法可以應用 SVG 過濾器,但在這種情況下,我們仍將在背景圖像上使用filter
屬性,就像 CSS 過濾器示例一樣以保持一致性。 與 SVG 過濾器的最大區別在於,我們需要小心地使用正確的路徑包含並鏈接到此過濾器。 這意味著我們需要在我們使用它的元素上方的頁面上導入 SVG (這可以通過使用模板引擎和 include 語句變得更容易)。
現場演示 – SVG 過濾器
<svg> <filter> <feColorMatrix type="saturate" values="0"/> </filter> </svg>
.svgfilter-gray { background: url('img/bird.jpg'); -webkit-filter: url(#grayscale-filter); filter: url(#grayscale-filter); }
過濾器性能
那麼這些在初始渲染性能方面是如何疊加的呢? 我為每個測試頁面製作了一個測試頁面,並使用了 Chrome 47 中的 WebPagetest 比較功能。請記住,每個測試給出的結果略有不同,總體趨勢可以總結如下:
CSS 過濾器、SVG 過濾器和 CSS 混合模式方法都在相對相似的時間範圍內加載。 有時 SVG 過濾器比 CSS 混合模式更快(但總是幾乎沒有),反之亦然。 CSS 過濾器通常是加載速度最快的,而<canvas>
總是最慢的。 這是收集到的最重要的見解。 <canvas>
在渲染圖像時經常落後於其他方法。
為了公平起見,我還想比較多個圖像的加載時間。 我為每個版本創建了十個(而不僅僅是一個)並再次運行測試:
結果是相似的(請記住,每次測試都有細微的差異)。 在這種情況下,CSS 過濾器慢了 0.1 毫秒,表明在 CSS 過濾器、混合模式和 SVG 過濾器之間,結果對於最快的方法是不確定的。 然而,相比之下,HTML5 <canvas>
明顯落後。
通過 JavaScript 渲染和繪製渲染時間深入了解頁面加載時間,您可以看到這種趨勢仍在繼續。

過濾器類型 | 渲染時間 | 繪畫時間 |
---|---|---|
CSS 過濾器 | 12.94 毫秒 | 4.28ms |
CSS 混合模式 | 12.10ms | 4.45ms |
SVG 過濾器 | 14.77 毫秒 | 5.80毫秒 |
畫布過濾器 | 15.23 毫秒 | 10.73 毫秒 |
同樣, <canvas>
花費了最長的渲染時間和最長的繪製時間,而兩個 CSS 選項是最快的,SVG 排在中間。
這些結果是有道理的,因為<canvas>
在我們能夠看到任何圖像之前獲取每個單獨的像素並對其執行操作。 這在渲染時需要大量的處理能力。 雖然通常 SVG 用於矢量圖形,但在處理光柵圖像效果時,我仍然強烈推薦它們而不是<canvas>
。 SVG 不僅速度更快,而且在 DOM 中更容易處理和更靈活。 一般來說,CSS 過濾器比 SVG 過濾器更優化,因為從歷史上看,它們是 SVG 過濾器的快捷方式,因此在瀏覽器中進行了優化。
#沒有過濾器
不使用過濾器會怎樣? 我將我們整體最快的方法(添加 CSS 過濾器)與在上傳之前在照片編輯軟件中編輯圖像進行了比較(我在 Mac OS X 上使用預覽來消除飽和度)。 在預編輯圖像時,我在測試中發現了一致的 0.1ms 性能改進:
結論
圖像過濾器是一種有趣且有效的方式,可在 Web 上提供視覺統一和美學吸引力。 請記住,它們確實會帶來輕微的性能影響,但也具有在瀏覽器中快速設計的好處以及設計交互的機會。
對於簡單的圖像效果,請使用 CSS 過濾器,因為它們具有最廣泛的支持和最簡單的用法。 如需更複雜的圖像效果,請查看 SVG 濾鏡或 CSS 混合模式。 SVG 濾鏡效果特別好,因為它們具有通道操作功能和feColorMatrix
。 CSS 混合模式還提供了一些非常好的視覺效果,頁面上的元素重疊。 您可以在 SVG 中使用類似的混合模式(例如feBlend
),儘管它們類似於 CSS background-blend-mode
,因為交互與 SVG 本身相關,而不是與周圍元素相關,如mix-blend-mode
允許的那樣。 只是不要將<canvas>
用於過濾器。