首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

前端性能优化:图片懒加载全攻略

  • 25-04-18 11:01
  • 3830
  • 5392
juejin.cn

简介

在对项目进行性能优化时,最常见的优化就是图片的懒加载,懒加载的目的是延迟加载页面上的图片,只有当图片进入视口的时候才加载,这样可以减少初始页面加载时间,节省带宽,提升用户体验。

懒加载有什么好处?

  1. 减少首屏加载时间:仅加载用户可见区域的图片,降低首次渲染阻塞。
  2. 节省带宽和流量:避免加载用户可能永远不会看到的内容(如长页面底部的图片)。
  3. 提升用户体验:防止页面卡顿,尤其是移动端和弱网环境。
  4. 优化SEO和性能评分:直接影响 Lighthouse 等工具的性能评分指标(如 LCP、FCP)。

在vue项目中(使用 vue-lazyload/vue3-lazyload 库)

  1. 安装库:

    bash
    代码解读
    复制代码
    npm install vue-lazyload --save
  2. 全局配置(在 main.js 中):

    javascript
    代码解读
    复制代码
    import Vue from 'vue'; import VueLazyload from 'vue-lazyload'; Vue.use(VueLazyload, { preLoad: 1.3, // 预加载比例 loading: 'path/to/loading.gif', // 占位图 error: 'path/to/error.png', // 加载失败图 attempt: 3 // 重试次数 });
  3. 在组件中使用:

    html
    代码解读
    复制代码
    <template> <img v-lazy="imageUrl" alt="description"> template>

在React 项目中(使用 react-lazyload 库)

  1. 安装库:

    bash
    代码解读
    复制代码
    npm install react-lazyload --save
  2. 包裹组件:

    jsx
    代码解读
    复制代码
    import LazyLoad from 'react-lazyload'; function MyComponent() { return ( <LazyLoad height={200} offset={100} placeholder={<LoadingSpinner />}> <img src="image.jpg" alt="description" /> LazyLoad> ); }

原生JavaScript的实现方法

原生js的实现方法有两种:使用Intersection Observer API和通过监听滚动事件(传统方案)。其中,Intersection Observer更现代,性能更好,而滚动事件监听则是传统方法,兼容性可能更好,但性能较差。

方案1:使用 Intersection Observer API

实现步骤:

  1. 将图片的真实URL存放在data-src属性中
  2. 当图片进入可视区域时,将data-src赋值给src属性
  3. 使用IntersectionObserver监听元素可见性变化
html
代码解读
复制代码
html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>图片懒加载示例title> <style> .lazy-img { width: 100%; height: 600px; /* 根据实际需求设置高度 */ background: #f0f0f0; margin: 20px 0; object-fit: cover; } style> head> <body> <img class="lazy-img" data-src="https://picsum.photos/800/600?image=1" alt="图片1"> <img class="lazy-img" data-src="https://picsum.photos/800/600?image=2" alt="图片2"> <script> document.addEventListener('DOMContentLoaded', () => { // 获取所有需要懒加载的图片元素 const lazyImages = document.querySelectorAll('.lazy-img'); // 配置Intersection Observer const observerOptions = { root: null, // 使用视口作为观察区域 rootMargin: '0px 0px 200px 0px', // 提前200px触发加载 threshold: 0.1 // 当元素10%进入视口时触发 }; // 创建观察器实例 const observer = new IntersectionObserver((entries, observer) => { entries.forEach(entry => { if (entry.isIntersecting) { // 当元素进入视口 const img = entry.target; // 替换src属性触发图片加载 img.src = img.dataset.src; // 加载完成后移除观察 img.addEventListener('load', () => { img.classList.add('loaded'); observer.unobserve(img); }); } }); }, observerOptions); // 开始观察所有图片 lazyImages.forEach(img => observer.observe(img)); }); script> body> html>

代码解析:

  1. HTML结构

    • 使用data-src存储真实图片地址
    • 初始src为空或使用占位图
    • 通过CSS设置图片容器的占位样式
  2. IntersectionObserver配置

    • rootMargin: '0px 0px 200px 0px':提前200px触发加载
    • threshold: 0.1:当元素10%进入视口时触发
  3. 加载流程

    • 检测到元素进入视口时替换src属性
    • 图片加载完成后移除观察器

方案2:传统滚动监听方案(兼容旧浏览器)

html
代码解读
复制代码
<script> // 节流函数:避免频繁触发滚动事件 function throttle(func, delay = 200) { let lastCall = 0; return (...args) => { const now = new Date().getTime(); if (now - lastCall < delay) return; lastCall = now; func.apply(this, args); } } // 判断元素是否进入视口 function isInViewport(element) { const rect = element.getBoundingClientRect(); return ( rect.top <= window.innerHeight * 1.5 && // 提前1.5屏加载 rect.bottom >= 0 ); } // 加载可见图片 function lazyLoad() { const images = document.querySelectorAll('.lazy-img[data-src]'); images.forEach(img => { if (isInViewport(img)) { img.src = img.dataset.src; img.removeAttribute('data-src'); } }); } // 初始化 document.addEventListener('DOMContentLoaded', lazyLoad); window.addEventListener('scroll', throttle(lazyLoad)); window.addEventListener('resize', throttle(lazyLoad)); script>

实践建议

  1. 占位符策略

    • 使用与图片比例一致的占位容器
    • 可添加低质量图片预览(LQIP)
  2. 性能优化

    • 优先使用WebP格式图片
    • 配合loading="lazy"原生属性(兼容性需注意)
    html
    代码解读
    复制代码
    <img src="image.jpg" loading="lazy" alt="...">

实现效果对比

指标IntersectionObserver滚动监听
性能消耗低(浏览器原生优化)高(频繁触发)
代码复杂度简单复杂
浏览器兼容性IE不支持(需polyfill)全兼容
精确度高依赖计算逻辑

注意事项

  1. 首屏图片不要使用懒加载
  2. 对SEO关键内容谨慎使用
  3. 移动端注意rootMargin的合理设置
  4. 优先使用原生loading="lazy"(需考虑目标用户浏览器)
注:本文转载自juejin.cn的zayyo的文章"https://juejin.cn/post/7493828568838406180"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2491) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

104
前端
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top