>  기사  >  웹 프론트엔드  >  HTML 및 JavaScript를 사용하여 효율적으로 이미지 로드

HTML 및 JavaScript를 사용하여 효율적으로 이미지 로드

PHPz
PHPz원래의
2023-08-25 21:53:051688검색

저는 이전에 HTML, CSS 또는 JavaScript를 사용하여 웹 페이지에 이미지를 미리 로드하는 방법에 대한 튜토리얼을 작성했습니다. 우리가 이미지를 미리 로드하는 수고를 하는 이유는 사용자에게 더 나은 탐색 경험을 제공하여 이미지가 로드될 때까지 기다릴 필요가 없도록 하기 위해서입니다.

사용자 경험을 개선한다는 동일한 아이디어가 지연 로딩 이미지에도 적용됩니다. 우리가 웹사이트를 탐색할 때 이미지는 페이지 무게에 영향을 미치는 가장 큰 요소 중 하나입니다. 이를 로드하면 성능이 최적으로 향상되고 대역폭이 절약됩니다.

이 튜토리얼에서는 이미지를 지연 로드하는 다양한 방법에 대해 알아봅니다.

이미지 지연 로딩의 필요성

이미지 로딩이 지연되는 이유를 이해하는 것부터 이 튜토리얼을 시작하겠습니다. 사진 작가를 위한 포트폴리오 웹 사이트를 구축하고 있는데 사진 작가가 최고의 이미지를 모두 한 페이지에 전시한다고 가정해 보겠습니다.

모든 사람이 모든 이미지를 보기 위해 페이지 하단으로 스크롤하지는 않습니다. 그러나 이미지는 여전히 사용자 브라우저에서 다운로드됩니다. 이는 아래 CodePen 데모에서 분명하게 드러납니다.

위 데모에서 첫 번째 이미지를 스크롤하지 않더라도 브라우저가 모든 이미지를 로드한 것을 볼 수 있습니다. 브라우저 개발자 도구의 Network 탭에 있는 아래 스크린샷은 38건의 요청이 이루어졌으며 약 2.5MB의 데이터가 전송되었음을 보여줍니다. 브라우저는 총 19개의 이미지를 다운로드했으며 리디렉션으로 인해 요청 수가 두 배로 늘어났습니다.

使用 HTML 和 JavaScript 高效加载图像

이제 리소스를 절약하기 위해 이미지 로딩을 개선하거나 최적화하려고 노력할 것입니다.

HTML을 사용한 이미지 지연 로딩

이미지를 지연 로드하는 가장 간단한 방법은 loading 属性。所有现代浏览器都支持图像上的 loading 속성을 사용하는 것입니다. 이 속성은 화면에 없는 이미지의 로드를 방지하고 사용자가 이미지를 볼 수 있을 만큼 가까이 스크롤할 때만 로드를 시작하도록 브라우저에 지시하는 데 사용할 수 있습니다. p>

loading 属性可以接受两个可能的值。第一个值是 eager 이는 현재 뷰포트 내에 있지 않더라도 이미지를 즉시 로드하도록 브라우저에 지시합니다. 이는 브라우저의 기본 동작입니다.

두 번째 값은 lazy,它告诉浏览器推迟加载图像,直到它到达距视口的特定距离。该距离由浏览器定义。将 loading 属性的值设置为 lazy이며 클라이언트의 대역폭을 절약할 수 있습니다.

브라우저는 현재 뷰포트에 표시되지 않는 이미지 로드만 지연한다는 점을 기억하는 것이 중요합니다. 웹페이지의 이미지는 다른 텍스트 옆에 배치되어 뷰포트 밖으로 밀려나는 경우가 많습니다. 이 경우 이미지가 지연 로드되도록 하기 위해 특별한 작업을 수행할 필요가 없습니다.

그러나 웹페이지에 이미지만 포함된 이 튜토리얼의 예를 고려해 보세요. 이 경우 이미지를 지연 로딩하려면 이미지 크기를 언급하는 것이 중요합니다. 그렇지 않으면 모든 이미지의 너비와 높이는 처음에 0이 됩니다. 이렇게 하면 브라우저는 모든 이미지가 뷰포트에 표시된다고 생각하고 모든 이미지가 즉시 로드됩니다.

이 경우 이미지 너비와 높이를 명시적으로 지정하면 일부 이미지가 뷰포트 밖으로 푸시됩니다. widthheight HTML 속성이나 CSS를 사용하여 이미지 크기를 자유롭게 지정할 수 있습니다.

지연 로딩 이미지에 대한 마크업은 다음과 같습니다.

으아아아

앞서 말했듯이 CSS에서 이미지 크기를 지정하고 마크업에서 widthheight 속성을 제거할 수도 있습니다.

으아아아

해당 CSS는 다음과 같습니다.

으아아아

다음 CodePen 데모는 실제 지연 로딩을 보여줍니다.

내 브라우저 개발자 도구의 Network 탭에 따르면 이번에는 4개의 이미지만 다운로드되었으며 전송된 데이터의 양은 약 450kB였습니다. 페이지에 19개의 이미지가 있습니다. 이는 또 다른 15개의 이미지 다운로드가 지연된다는 의미입니다. 대역폭 측면에서 이는 약 80%의 절감 효과를 나타냅니다.

使用 HTML 和 JavaScript 高效加载图像

여기서 기억해야 할 중요한 점은 관련된 스크립트가 없더라도 이미지의 지연 로딩은 JavaScript가 활성화된 경우에만 작동한다는 것입니다. 이는 전략적으로 배치된 이미지를 통해 사용자의 스크롤 위치가 추적되는 것을 방지하기 위한 것입니다.

지연 로드되어야 하는 이미지를 언제 다운로드해야 하는지 브라우저는 어떻게 결정합니까? 지연 로드 이미지 다운로드를 실행하는 정확한 조건은 브라우저마다 다릅니다. 그러나 두 가지 주요 요인은 뷰포트와의 거리와 네트워크 속도인 것 같습니다.

지연 로드된 이미지의 다운로드 시간을 정확하게 제어하려면 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,这些技术都将不起作用。

위 내용은 HTML 및 JavaScript를 사용하여 효율적으로 이미지 로드의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.