私は以前、HTML、CSS、または JavaScript を使用して Web ページに画像をプリロードする方法について説明したチュートリアルを書きました。私たちがわざわざ画像をプリロードする理由は、画像のロードを待つ必要がないように、ユーザーにより良いブラウジング エクスペリエンスを提供するためです。
ユーザー エクスペリエンスを向上させるという同じ考え方が、画像の遅延読み込みにも当てはまります。 Web サイトを閲覧するとき、画像はページの重さに影響を与える最大の要素の 1 つです。それらを最適にロードすると、パフォーマンスが向上し、帯域幅が節約されます。
このチュートリアルでは、画像を遅延読み込みするさまざまな方法について学びます。
このチュートリアルは、画像の遅延読み込みを行う必要がある理由を理解することから始めます。写真家向けのポートフォリオ Web サイトを構築しており、その写真家がすべての最高の画像を 1 ページに紹介しているとします。
すべての画像を見るためにページの一番下までスクロールする人はいないでしょう。ただし、イメージはユーザーのブラウザによってダウンロードされ続けます。これは、以下の CodePen デモで明らかです:
上記のデモの最初の画像をスクロールしなくても、ブラウザーがすべての画像をロードしていることがわかります。ブラウザの開発者ツールの [ネットワーク] タブの次のスクリーンショットは、38 件のリクエストが行われ、約 2.5MB のデータが転送されたことを示しています。ブラウザーは合計 19 個の画像をダウンロードし、リダイレクトによってリクエストの数が 2 倍になりました。
ここでは、リソースを節約するために画像の読み込みを改善または最適化することを試みます。
画像を遅延ロードする最も簡単な方法は、loading
属性を使用することです。最新のブラウザはすべて、画像の loading
属性をサポートしています。この属性を使用すると、画面上にない画像の読み込みを防止し、ユーザーが画像が表示されるまでスクロールした場合にのみ画像の読み込みを開始するようにブラウザに指示できます。 p>
loading
プロパティは 2 つの可能な値を受け入れることができます。最初の値は eager
で、現在ビューポート内にない場合でも、ブラウザーに画像をすぐにロードするように指示します。これはブラウザのデフォルトの動作です。
2 番目の値は lazy
で、ビューポートから特定の距離に達するまで画像の読み込みを遅らせるようブラウザーに指示します。この距離はブラウザによって定義されます。 loading
属性の値を lazy
に設定すると、クライアントの帯域幅が節約される可能性があります。
ブラウザは現在ビューポートに表示されていない画像の読み込みのみを遅延させることに留意することが重要です。多くの場合、Web ページ上の画像は他のテキストと並んで配置され、ビューポートの外に押し出されます。この場合、画像が遅延ロードされるようにするために特別なことを行う必要はありません。
ただし、Web ページに画像のみが含まれるこのチュートリアルの例を考えてみましょう。この場合、画像の遅延読み込みが必要な場合は、画像のサイズについて言及することが重要になります。それ以外の場合、すべての画像の最初の幅と高さはゼロになります。これにより、ブラウザはすべての画像がビューポートに表示されていると認識し、すべての画像がすぐにロードされます。
この場合、画像の幅と高さを明示的に指定すると、一部の画像がビューポートの外に押し出されます。 HTML プロパティの width
および height
を使用するか、CSS で画像のサイズを自由に指定できます。
これは画像の遅延読み込みのマークアップです:
リーリー前に述べたように、CSS で画像のサイズを指定し、マークアップから width
および height
プロパティを削除することもできます。
リーリー
リーリー
次の CodePen デモは、実際の遅延読み込みを示しています:
ブラウザの開発者ツールの
ネットワーク タブには、今回ダウンロードされた画像は 4 つだけで、転送されたデータ量は約 450 KB であることが示されています。ページには 19 枚の画像があるため、さらに 15 枚の画像のダウンロードが遅れることになります。帯域幅の観点から見ると、これは約 80% の節約になります。
ここで覚えておくべき重要な点は、スクリプトが含まれていない場合でも、画像の遅延読み込みは JavaScript が有効になっている場合にのみ機能するということです。これは、戦略的に配置された画像を通じてユーザーのスクロール位置が追跡されるのを防ぐために行われます。
ブラウザは、遅延読み込みする必要がある画像をいつダウンロードするかをどのように判断するのでしょうか?遅延読み込みイメージのダウンロードをトリガーする正確な条件は、ブラウザーごとに異なります。ただし、2 つの主な要因はビューポートからの距離とネットワーク速度のようです。
遅延読み込みイメージのダウンロード時間を正確に制御したい場合は、JavaScript を使用する必要があります。
现在我们将学习如何使用 JavaScript 延迟加载图像。这将使我们能够更好地控制整个过程。如果您认为默认的延迟加载不够激进,您可以使用 Intersection Observer API 创建自己的延迟加载脚本。
在编写任何 JavaScript 之前,我们需要对标记进行一些更改:
<img class="lazy-load" data-src="https://picsum.photos/id/628/1080/1080">
我们的 img
标签现在将包含一个名为 lazy-load
的类,以帮助我们识别哪些图像需要延迟加载。 img
标签将使用 data-src
属性来跟踪图像路径,而不是 src
属性。这会阻止图像立即开始下载。
Intersection Observer API 允许我们检测目标元素是否与其任何祖先元素或文档的视口相交。我们将使用 IntersectionObserver()
构造函数来创建 IntersectionObserver
对象。该构造函数接受回调函数作为其第一个参数,并接受一个用于自定义观察者行为的可选对象作为第二个参数。
我们传递给构造函数的回调函数接收两个参数。第一个是相交元素的数组,第二个是观察者本身。自定义选项允许您指定要检查交集的根元素、向根元素添加额外偏移值的根边距以及确定浏览器何时开始报告交集的阈值。
这是我们的交叉点观察者对象的代码:
function preload_image(img) { img.src = img.dataset.src; console.log(`Loading ${img.src}`); } const config_opts = { rootMargin: '200px 200px 200px 200px' }; let observer = new IntersectionObserver(function(entries, self) { for(entry of entries) { if(entry.isIntersecting) { let elem = entry.target; preload_image(elem); self.unobserve(elem); } } }, config_opts);
我在根元素(本例中为视口)的所有边上提供了 200 像素的边距。只要任何图像位于视口 200 像素范围内,我们的交叉点观察器就会激活。默认情况下,阈值设置为 0。值为零意味着只要图像的一小部分位于我们指定的范围内,就会调用 preload_image()
函数。 unobserve()
方法告诉浏览器停止观察该特定图像以进行进一步的交叉。
preload_image()
函数获取图像的 data-src
属性的值,并将其应用于 src
属性。这会触发我们图像的下载。
我们现在需要做的就是查询文档中的所有图像,然后告诉观察者观察它们是否有交集。这是为我们实现这一目标的代码。
let images = document.querySelectorAll('img.lazy-load'); for(image of images) { observer.observe(image); }
您是否注意到我们正在使用 img.lazy-load
选择器来查询我们的图像?这个类可以帮助我们轻松识别所有想要延迟加载的图像。没有此类的图像将正常加载。
这是一个 CodePen 演示,用于查看我们的图像是否确实延迟加载。
这次,我的浏览器开发者工具中的网络选项卡显示,之前只下载了两张图片,总共传输的数据量约为 192 kB。与原始演示相比,我们的带宽节省现已高达 92%。
我承认我已经让交叉观察者变得非常激进,只加载非常接近视口的图像。然而,这就是您自己实现该功能的美妙之处。
延迟加载图像对每个人来说都是双赢的。它将减少服务器的负载,同时节省用户的带宽。请记住,数据,尤其是移动数据,在世界上的某些地方非常昂贵。
现在浏览器原生支持延迟加载图像,只需对标记进行微小更改即可充分利用该功能。浏览器还足够智能,可以根据网络速度和图像位置确定延迟加载图像的理想时间。您还可以使用 Intersection Observer API 相对轻松地自行实现该功能。
这里要记住的一件重要事情是,如果用户端禁用 JavaScript,这些技术都将不起作用。
以上がHTML と JavaScript を使用して画像を効率的にロードするの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。