Home  >  Article  >  Web Front-end  >  Efficiently load images using HTML and JavaScript

Efficiently load images using HTML and JavaScript

PHPz
PHPzOriginal
2023-08-25 21:53:051690browse

I previously wrote a tutorial discussing how to preload images on a web page using HTML, CSS, or JavaScript. The reason we go to the trouble of preloading images is to provide a better browsing experience for users so they don't have to wait for images to load.

The same idea of ​​improving user experience also applies to lazy loading images. When we browse a website, images are one of the biggest factors affecting page weight. Loading them optimally improves performance and saves bandwidth.

In this tutorial, we will learn about different ways to lazy load images.

Necessity of lazy loading of images

We'll start this tutorial by understanding why you should bother with lazy loading images. Let's say you're building a portfolio website for a photographer, and they showcase all their best images on one page.

Not everyone will scroll to the bottom of the page to see all the images. However, the image is still downloaded by the user's browser. This is evident in the CodePen demo below:

Even if you don't scroll past the first image in the demo above, you will see that the browser has loaded all the images. The following screenshot of the Network tab in the browser's developer tools shows that 38 requests were made, transferring approximately 2.5MB of data. The browser downloaded a total of 19 images, and the redirect doubled the number of requests.

使用 HTML 和 JavaScript 高效加载图像

We will now try to improve or optimize image loading to save resources.

Lazy loading of images using HTML

The simplest way to lazy load an image involves using the loading attribute. All modern browsers support the loading attribute on images, which can be used to instruct the browser to prevent loading images that are not on screen and only start loading them when the user scrolls close enough to make them visible . p>

loading The property can accept two possible values. The first value is eager, which tells the browser to load the image immediately, even if it is not currently within the viewport. This is the browser's default behavior.

The second value is lazy, which tells the browser to delay loading the image until it reaches a specific distance from the viewport. This distance is defined by the browser. Setting the value of the loading attribute to lazy may save bandwidth for the client.

It is important to remember that browsers only delay load images that are not currently visible in the viewport. Often, images on web pages are placed alongside other text, pushing them out of the viewport. In this case, you don't need to do anything special to ensure that the images are lazy loaded.

However, consider the example in this tutorial where the web page contains only images. In this case, if you want lazy loading of images, then it becomes important to mention the size of the images. Otherwise, all images will initially have a width and height of zero. This will make the browser think that all images are visible in the viewport, and all images will be loaded immediately.

In this case, explicitly specifying image width and height will push some images out of the viewport. You can freely specify image dimensions using the width and height HTML properties or in CSS.

This is the markup for lazy loading images:

<img loading="lazy" src="https://picsum.photos/id/628/1080/1080" width="600" height="600">

As I said before, you can also specify the image dimensions in CSS and remove the width and height properties from the markup:

<img loading="lazy" src="https://picsum.photos/id/628/1080/1080">

The corresponding CSS is:

img {
  width: 600px;
  height: 600px;
}

The following CodePen demo shows lazy loading in action:

The Network tab in my browser's developer tools shows that only four images were downloaded this time, and the amount of data transferred was approximately 450 kB. There are 19 images on the page, which means another 15 images will be delayed in downloading. In terms of bandwidth, this represents a saving of approximately 80%.

使用 HTML 和 JavaScript 高效加载图像

One important thing to remember here is that even without scripts involved, lazy loading of images only works when JavaScript is enabled. This is done to prevent the user's scroll position from being tracked through strategically placed images.

How do browsers determine when an image that should be lazy loaded should be downloaded? The exact conditions that trigger a lazy-loaded image download vary from browser to browser. However, the two main factors seem to be distance from the viewport and network speed.

If you want precise control over the download time of lazy-loaded images, you must use JavaScript.

使用 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%。

使用 HTML 和 JavaScript 高效加载图像

我承认我已经让交叉观察者变得非常激进,只加载非常接近视口的图像。然而,这就是您自己实现该功能的美妙之处。

最终想法

延迟加载图像对每个人来说都是双赢的。它将减少服务器的负载,同时节省用户的带宽。请记住,数据,尤其是移动数据,在世界上的某些地方非常昂贵。

现在浏览器原生支持延迟加载图像,只需对标记进行微小更改即可充分利用该功能。浏览器还足够智能,可以根据网络速度和图像位置确定延迟加载图像的理想时间。您还可以使用 Intersection Observer API 相对轻松地自行实现该功能。

这里要记住的一件重要事情是,如果用户端禁用 JavaScript,这些技术都将不起作用。

The above is the detailed content of Efficiently load images using HTML and JavaScript. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn