Web画像効果パフォーマンス対決
公開: 2022-03-10ブラウザがグラフィックレンダリング機能を絶えず向上させるにつれて、ブラウザ内で真に設計する機能がより現実的になりつつあります。 数行のコードで、すばやく劇的な視覚的インパクトを与えることができ、多くの労力をかけずに一貫性を保つことができます。 そして、Web開発のほとんどのものと同様に、同じ効果を達成するための多くの方法があります。
この投稿では、最も人気のある画像効果の1つであるグレースケールを見て、HTMLキャンバス、SVG、CSSフィルター、およびCSSブレンドモードの実装の容易さとパフォーマンスへの影響の両方を評価します。 どちらが勝ちますか?
SmashingMagの詳細:
- Web画像効果パフォーマンス対決
- HTML5:事実と神話
- ImageMagickによる効率的な画像サイズ変更
- 巧妙なJPEG最適化手法
ウェブ上のフィルターは、画像の上にレンズを置いたように機能します。 これらは、ブラウザがレイアウトと初期ペイントをレンダリングした後に画像に適用されます。 サポートされているブラウザでは、フィルタを個別に適用することも、重ねて適用することもできます。 これらは最初のレンダリング後に画像の変更として適用でき、拡張機能である可能性が高いため、フィルターは、それらをサポートしていないブラウザーに表示されないだけで、正常に機能が低下します。
CSSフィルター
グレースケール効果を生成するための最も簡単な方法である、謙虚でありながら強力なCSSフィルターから始めましょう。

この効果を実現するために、CSSの1行を追加します: 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
プロパティの2つの方法があります。
-
mix-blend-mode
は、要素がその背後にあるコンテンツとどのようにブレンドされるかを説明するプロパティです。 -
background-blend-mode
は、複数の背景を持つ要素に使用され、これらの背景間の関係を記述します。
この例では、 background-blend-mode: luminosity
を使用して、灰色の背景の上に明度チャネルをプルし、グレースケール画像を作成します。 注意すべき点の1つは、背景の順序が一定であるということです。効果を適切にレンダリングするには、背景画像を常に単色またはグラデーションの背景の前に順序付ける必要があります。 色は最後の背景レイヤーである必要があります。 これは、 background-blend-mode
サポートしていない古いブラウザに対する保護手段でもあります。画像は効果なしでレンダリングされます。
ブレンドモードとCSSフィルターの唯一の違いは、複数の背景があり、 background-blend-mode: luminosity
を使用していることです。これは、上部の画像(鳥のテスター)から明るさの値を取得し、それらの明るさの値を灰色の2番目の背景。
ライブデモ–バックグラウンドブレンドモード
.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>
を使用してグレースケール効果を実現する方法は、明度レベル(明るさ)を維持しながら、ピクセル値の範囲外の値から赤、緑、青のコンポーネントを取り除くことです。 これを行う1つの方法は、次のようにRGB値を平均化することですgrayscale = (red + green + blue) / 3;
。

以下の例では、画像データ(R,G,B,a)
の形式のRGBa値を使用しています。 赤のチャネルはdata[0]
、緑のチャネルはdata[1]
などです。 次に、これらの各チャネルの明度レベル(明るさ)を取得し、それらを平均して画像をグレースケールにします。
ライブデモ–HTML5キャンバス
SVGフィルター
SVGフィルターは(Internet ExplorerやEdgeでも)最も幅広いサポートがあり、CSSフィルターと直接同じように(ほぼ)簡単に使用できます。 同じfilter
プロパティで使用できます。 実際、CSSフィルターはSVGフィルターから生まれました。 キャンバスと同様に、SVGフィルターを使用すると、WebGLシェーディングを利用してさらに複雑な結果を作成できるため、2次元効果の平面を超越することができます。
SVGフィルターを適用する方法はいくつかありますが、この場合でも、一貫性を保つためのCSSフィルターの例と同様に、背景画像のfilter
プロパティを使用します。 SVGフィルターとの最大の違いは、このフィルターを適切なパスで含めてリンクするように注意する必要があることです。 これは、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>
は、画像のレンダリングにおいて他の方法よりも定期的に遅れていました。
公平を期すために、複数の画像の読み込み時間も比較したいと思いました。 それぞれのレンディションを(1つだけではなく)10個作成し、テストを再度実行しました。
結果は同様でした(各テストにはわずかな違いがあることに注意してください)。 この場合、CSSフィルターは0.1ミリ秒遅くなり、CSSフィルター、ブレンドモード、およびSVGフィルターの間で、最も高速な方法の結果は決定的ではないことを示しています。 ただし、HTML5 <canvas>
は比較すると著しく遅れています。
JavaScriptレンダリングとペイントレンダリング時間を介してページの読み込み時間を詳しく見ると、この傾向が続いていることがわかります。

フィルタータイプ | レンダリングする時間 | ペイントする時間 |
---|---|---|
CSSフィルター | 12.94ms | 4.28ms |
CSSブレンドモード | 12.10ms | 4.45ms |
SVGフィルター | 14.77ms | 5.80ms |
キャンバスフィルター | 15.23ms | 10.73ms |
繰り返しになりますが、 <canvas>
はレンダリングに最も時間がかかり、ペイントに最も時間がかかりましたが、2つのCSSオプションは最も高速で、SVGが真ん中にありました。
<canvas>
は個々のピクセルを取得し、画像をまったく表示する前にそのピクセルに対して操作を実行しているため、これらの結果は理にかなっています。 これには、レンダリング時に多くの処理能力が必要です。 通常、SVGはベクターグラフィックスに使用されますが、ラスターイメージ効果を処理する場合は、 <canvas>
よりもSVGを強くお勧めします。 SVGは高速であるだけでなく、DOM内での処理がはるかに簡単で、柔軟性があります。 一般に、CSSフィルターはSVGフィルターよりもさらに最適化されています。これは、歴史的にSVGフィルターから出現したショートカットであり、ブラウザーで最適化されているためです。
#nofilter
フィルタを使用しないのはどうですか? 全体的に最も高速な方法(CSSフィルターの追加)を、アップロードする前に写真編集ソフトウェアで画像を編集する方法と比較しました(Mac OS Xでプレビューを使用して彩度を削除しました)。 画像を事前編集すると、テストで一貫して0.1ミリ秒のパフォーマンスの向上が見られました。
結論
画像フィルターは、ウェブ上で視覚的な統一性と美的魅力を提供するための楽しく効果的な方法です。 パフォーマンスがわずかに低下するだけでなく、ブラウザでのスピーディーなデザインとインタラクションをデザインする機会もあることを覚えておいてください。
単純な画像効果の場合は、CSSフィルターを使用します。これは、CSSフィルターが最も広くサポートされ、最も簡単に使用できるためです。 より複雑な画像効果については、SVGフィルターまたはCSSブレンドモードを確認してください。 SVGフィルター効果は、チャネル操作機能とfeColorMatrix
があるため、特に優れています。 CSSブレンドモードは、ページ上の要素が重なっている非常に優れた視覚効果も提供します。 SVG内で同様のブレンドモード( feBlend
など)を使用できますが、相互作用がSVG自体に関係し、 mix-blend-mode
で許可されているように周囲の要素には関係しないという意味で、CSSbackground background-blend-mode
に似ています。 フィルタに<canvas>
を使用しないでください。