(jp) =
レスポンシブ画像に関するいくつかの考えを共有したいと思います。 多くのプロジェクトが恩恵を受けることができる特定の考え方について書きます: 本格的な CDN セットアップを必要としないが、レスポンシブ イメージのパフォーマンス向上を享受する小規模および中規模の Web プロジェクト。
レスポンシブ画像の背後にある考え方は単純です。画面上の画像のサイズにできるだけ近いサイズの画像を提供するようにしてください。 これにより、帯域幅の使用量が減り、読み込み時間が短縮されます!
たとえば、幅 600 ピクセルの画面を持つモバイル デバイスに画像を表示している場合、幅 1000 ピクセルの画像をダウンロードする必要はありません。
レスポンシブ イメージ仕様は、メディア クエリだけでなく、ピクセル密度も処理します。 サーバーがしなければならないことは、同じ画像の複数のバリエーションをそれぞれ異なるサイズで生成することだけです。
舞台裏で物事がどのように行われているかについて詳しく知りたい場合は、この記事の最後に興味深いリソースへのリンクをいくつか紹介します。
# レスポンシブ画像のレンダリング方法
同じ画像のバリエーションをレンダリングするさまざまな方法があります。 最も簡単なアプローチは次のとおりです。
画像を指定して、1920px、1200px、800px、400px の 4 つのバリエーションを作成します.
このアプローチは簡単に実装できますが、最適とは言えません。 レスポンシブ画像の目標は、ユーザーの画面で可能な限り最高の品質を維持しながら、読み込み速度の速い画像を提供することです。
この方程式には、ユーザーの画面の幅 (したがって、画像自体の幅) と画像のファイル サイズの 2 つの変数があります。
まったく同じ寸法の 2 つの画像があるとします。 その画像のコンテンツと使用されるエンコーディングに応じて、それらのファイル サイズは大きく異なる可能性があります。
もう 1 つのアプローチは、手動で最適な srcset
画像ごとに。 これは、ほとんどの Web サイトでは実行できません。 Web サイトには多数の画像が含まれる可能性があり、その最適なサイズを手動で計算することも困難です。 srcset
.
幸いなことに、コンピューターは大規模な面倒な計算を得意としています。 このアプローチは良いアイデアのように思えます。
画像を指定して、その画像の x 量のバリエーションを生成します。各バリエーションのファイル サイズは約 10% 小さくなります.
それはどのように聞こえますか? これで、さまざまな画面サイズで発生する可能性のある「オーバーヘッド」のマージンがわずかになりましたが、少なくともマージンが 10% を超えることはないと確信しています。 画像のサイズによって異なります。たとえば、サムネイルとヒーロー画像。 マージンを 10% ではなく 5% に減らすこともできます。 これにより、異なる結果が得られます srcset
レスポンシブ画像の仕様で処理できます。
では、元の画像のサイズしかわからない場合、たとえば同じ画像の 10 個のバリアントのサイズをどのように判断できるのでしょうか? ここで高校数学の出番です。
filesize = 1.000.000
width = 1920
ratio = 9 / 16
height = ratio * width
area = width * height
<=> area = width * width * ratio
pixelprice = filesize / area
<=> filesize = pixelprice * area
<=> filesize = pixelprice * (width * width * ratio)
<=> width * width * ratio = filesize / pixelprice
<=> width ^ 2 = (filesize / pixelprice) / ratio
<=> width = sqrt((filesize / pixelprice) / ratio)
この証明は、与えられた定数 pixelprice
、縮小された画像が指定されたファイルサイズを持つために必要な幅を計算できます。 しかし、これが問題です: pixelprice
は、この画像の 1 ピクセルのコストの概算です。 画像全体を縮小するので、正確な結果を得るにはこの概算で十分です。 PHPでの実装は次のとおりです。
$dimensions = [];
$ratio = $height / $width;
$area = $width * $width * $ratio;
$pixelPrice = $fileSize / $area;
$stepModifier = $fileSize * 0.1;
while ($fileSize > 0)
$newWidth = floor(
sqrt(
($fileSize / $pixelPrice) / $ratio
)
);
$dimensions[] = new Dimension($newWidth, $newWidth * $ratio);
$fileSize -= $stepModifier;
このアプローチでは、事前に画像を拡大縮小することなく、ファイル サイズを 10% 縮小して各バリエーションの寸法を計算できることをもう一度明確にしたいと思います。 つまり、パフォーマンスのオーバーヘッドや、画像をどのようにスケーリングする必要があるかを知るための複数の推測はありません。
# 実際には
オウムの写真を見てみましょう。 この画像は固定です srcset
:
これはダイナミックです srcset
:
インスペクターを開いてレスポンシブモードで遊んでみてください。 ブラウザのキャッシュを必ず無効にして、異なる画面サイズで読み込まれる画像を比較してください。 また、画面のピクセル密度が影響を与える可能性があることにも注意してください。
これを手作業で行うことを想像できますか? 私がすることもできない! 現在の仕事である Spatie で働き始めたときに最初に提案した機能の 1 つは、この動作を Laravel メディア ライブラリに追加することでした。その使用方法は次のように簡単です。
$model
->addMedia($yourImageFile)
->withResponsiveImages()
->toMediaCollection();
<img
src=" $media->getFullUrl() "
srcset=" $media->getSrcset() "
sizes="[your own logic]"
/>
最後に、この投稿の冒頭で言及したリンクを次に示します。
同僚に感謝します セバスチャン この投稿のレビューと編集のために。