banner
meanc

meanc

自部署博客在 blog.meanc.cc
twitter
github
discord server

性能优化的利器 延迟加载

众所周知,性能优化一般就两个东西,不加载,和缓存

当然不加载是不行的,所以今天就来讲讲延迟加载

当前网页除了大规模 js 加载,还有一些我们可以进行优化的地方

对于字体文件加载,可以看我的文章 - 字体模块设计

图片加载#

图片性能优化包含很多内容,包括压缩,格式,用视频替换 GIF, 根据尺寸提供图片,使用 webp, 使用 cdn.
这些不是我们今天的内容,今天来看看图片延迟加载
最新的浏览器默认实现浏览器级别的延迟加载,可以使用 loading 属性来开启

<img loading="lazy" />

我们还可以通过 IntersectionObserver 对象,来开启对 img 的延迟加载更精细的控制,例如在视口中出现 1s 以上才开始显示图片

// 获取所有需要延迟加载的图片元素
const lazyImages = document.querySelectorAll(".lazy-loaded-image");

// 设置 IntersectionObserver 的选项
const options = {
  root: null,
  rootMargin: "0px",
  threshold: 0.5
};

// 创建 IntersectionObserver 对象
const lazyImageObserver = new IntersectionObserver((entries, observer) => {
  entries.forEach((entry) => {
    if (entry.isIntersecting && entry.intersectionRatio >= 0.5) {
      // 如果图片在视口中出现1s以上,开始加载图片
      setTimeout(() => {
        const lazyImage = entry.target;
        lazyImage.src = lazyImage.dataset.src;
        lazyImage.classList.remove("lazy");
        lazyImageObserver.unobserve(lazyImage);
      }, 1000);
    }
  });
}, options);

// 观察所有需要延迟加载的图片元素
lazyImages.forEach((lazyImage) => {
  lazyImageObserver.observe(lazyImage);
});

css 文件中的图片#

css 文件中的图片不可以用上面的加载方式,但是我们同样可以使用视口监视的方式,来动态添加类名已达到延迟加载图片的目的

.lazy-backgroundbackground-image: url("hero-placeholder.jpg");
/* Placeholder image */}
.lazy-background.visiblebackground-image: url("hero.jpg"); 
/* The final image */}

我们通过修改上面的代码将 setTimeout 中的内容替换为 (其他代码相对应的改动)

   lazyBackGround.classList.add("visible");

来达到动态改变 css 加载的图片方式实现延迟加载

视频的延迟加载#

video 没有 lazy 属性,但是有个 preload 可以使用

<video controls preload="none" poster="one-does-not-simply-placeholder.jpg">  <source src="one-does-not-simply.webm" type="video/webm">  <source src="one-does-not-simply.mp4" type="video/mp4"></video>

这里有个 poster 属性,这个属性非常有用,可以将图片当作占位图来使用

前文提到过,我们可以使用视频来替换 GIF 显示,这是因为相同内容,视频相对于 GIF 有明显的体积优势

这种场景下,我们的 video 标签是这样的
这是一个延迟加载的 自动播放,一直循环的视频

<video class="lazy" autoplay muted loop playsinline width="610" height="254" poster="one-does-not-simply.jpg">  <source data-src="one-does-not-simply.webm" type="video/webm">  <source data-src="one-does-not-simply.mp4" type="video/mp4"></video>

我们依然可以使用 IntersectionObserver 来动态的替换 source 元素的 src , 来精细的控制延迟加载

if (video.isIntersecting) {

for (var source in video.target.children) {

var videoSource = video.target.children[source];

if (

typeof videoSource.tagName === 'string' &&

videoSource.tagName === 'SOURCE'

) {

videoSource.src = videoSource.dataset.src;

}

}

video.target.load();

video.target.classList.remove('lazy');

lazyVideoObserver.unobserve(video.target);

}

iframe 的延迟加载#

iframe 同样支持 loading=lazy, 最简单的方法就是直接添加到标签上,这对于页面中嵌入大量视频的场景非常有效

加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。