当前位置: 首页 > news >正文

【前端】懒加载(组件/路由/图片等)+预加载 汇总

目录

  • 懒加载
    • 组件
    • 路由
    • 图片
    • 其他场景
  • 预加载

按需加载=懒加载+预加载

懒加载

组件

组件频繁使用时不建议懒加载,只懒加载低频组件!

  • vue
    defineAsyncComponent+suspense【vue2不支持】+ #default/fallback
    #default 插槽:渲染真正的内容(比如异步组件)
    #fallback 插槽:在内容加载期间显示的占位内容(比如 loading 文案或动画)
<Suspense><template #default><MyComponent /></template><template #fallback>Loading...</template>
</Suspense>// 异步组件(默认内置 Suspense 支持)搭配 <Suspense> 使用
const MyComponent = defineAsyncComponent(() => import('./MyComponent.vue'))
  • React
    React.lazy 和 Suspense
const MyComponent = React.lazy(() => import('./MyComponent'))<Suspense fallback={<div>Loading...</div>}><MyComponent />
</Suspense>

路由

//vue
// Vue Router 中使用动态 import 实现懒加载
const routes = [{path: '/about',component: () => import('./views/About.vue')}
]//react routerv6+
const About = React.lazy(() => import('./pages/About'))
//注意:每个使用 React.lazy()的路由组件都要手动包一层 <Suspense>。
<Route path="/about" element={<Suspense fallback={<div>Loading...</div>}><About /></Suspense>
} />

图片

  • HTML 原生方式(推荐,所有框架都通用)
<img src="image.jpg" loading="lazy" alt="示例图">
  • vue/react
//vue
//插件 vue-lazyload
// main.ts
import VueLazyLoad from 'vue3-lazyload'
app.use(VueLazyLoad)
// 使用
<img v-lazy="imageUrl" />//react
//1. 原生 loading="lazy"
//2. IntersectionObserver 手写懒加载(更高级)暂略

其他场景

类型VueReact
第三方组件defineAsyncComponent()React.lazy()
Markdown/Code 高亮插件异步加载 PrismJS 等库同上
地图库(如高德)<script async> 动态加载 SDKuseEffect + createElement('script')
iframe/视频等设置 loading="lazy" + 原生IntersectionObserverloading="lazy"/preload="none" // 不预加载视频 /第三方库 react-intersection-observer /原生IntersectionObserver
  • IntersectionObserver
    原生 IntersectionObserver 是 JavaScript 原生浏览器 API,不属于 React、Vue、jQuery 等框架,vue/react都没有自带或者封装它。用来监听某个元素是否进入或离开视口(或另一个指定元素),常用于:
    懒加载图片、视频、iframe
    无限滚动
    进入视口时动画播放
    页面曝光率埋点
    ⚠️注意
    不能监听 display: none 的元素
    滚动容器若是自定义元素,需要设置 overflow: auto/scroll
    IE11 不支持,需要用 IntersectionObserver polyfill
const target = document.querySelector('#myElement');
/*
第一个参数是回调函数,每当被观察的元素进入或离开视口时触发。
entries: 是一个数组,包含每个被观察元素的状态(IntersectionObserverEntry)。
observer: 当前的 IntersectionObserver 实例本身。第二个参数配置
root: 观察区域。null 表示是浏览器视口(viewport)。
threshold: 触发比例阈值,取值 0 ~ 1。0.1 表示当目标元素有 10% 可见时就触发回调。
*/
const observer = new IntersectionObserver((entries, observer) => {entries.forEach(entry => {if (entry.isIntersecting) {//元素已经进入观察区域(例如视口)console.log('元素进入视口');observer.unobserve(entry.target); // 一次性监听//观察器停止监听这个目标}});
}, {root: null, // 默认为视口threshold: 0.1, // 元素进入视口 10% 就触发
});observer.observe(target);//开始观察一个 DOM 元素 target,只要它进入视口就会执行前面的回调。//多个元素
// 选中所有需要懒加载的图片
const images = document.querySelectorAll('.lazy');
// 遍历每个元素,添加观察
images.forEach(img => observer.observe(img));

预加载

  • 应用场景
场景推荐方式
当前页面关键 JS/CSS/font<link rel="preload">webpackPreload
下个页面可能需要的组件webpackPrefetch / 动态 import()
静态图片<link preload> 或 JS 创建 Image
提前连接 CDN 或后端 API 域名dns-prefetch / preconnect
用户 hover/点击前加载手动 import()/fetch()
  • html文件
类型技术/方式说明
HTML 资源级别<link rel="preload">提前加载关键资源,支持 js/css/font/image/video 等。
<link rel="prefetch">低优先级加载未来可能用到的资源(如下一页)。
<link rel="dns-prefetch">提前进行 DNS 查询,加快第三方资源访问。
<link rel="preconnect">提前进行 TCP + TLS 握手。
<link rel="prerender">预渲染整个页面(较少使用,Chrome 支持有限)。
  • JS文件
    安装Webpack 的“魔法注释”写法,用于控制异步模块的加载优先级
    这类注释只在 Webpack 构建时生效,属于 Webpack 的“魔法注释”
    生成的 HTML 中会自动插入 <link rel="preload"> 或 <link rel="prefetch"> 标签
import(/* webpackPrefetch: true */ './HeavyComponent');
import(/* webpackPreload: true */ './CriticalComponent');

webpackPrefetch: 低优先级预加载,浏览器空闲时加载(推荐用于未来页面组件)
webpackPreload: 高优先级并行加载,立即加载(推荐用于当前页面关键模块)

  • vue/react懒加载+预加载组合,使加载更聪明
const Page = () => import(/* webpackPrefetch: true */ './Page.vue');const LazyPage = React.lazy(() => import(/* webpackPrefetch: true */ './Page'));// 可搭配使用:使用 prefetch 手动提前加载,否则空闲才加载 
import('./Page');
  • 图片
<link rel="preload" as="image" href="/images/banner.jpg">
const img = new Image();
img.src = '/images/banner.jpg';
  • 组件:vue/react也是通过提前触发 import() 方式实现(参考上方 webpackPrefetch),也可以组合搭配上懒加载
  • 视频
<video preload="auto" src="video.mp4" />
<!-- 
none	不预加载任何数据
metadata	只加载元数据
auto	浏览器自己决定(尽量预加载)
-->
  • 路由也是用路由预加载确实可以通过 Webpack 的魔法注释来实现搭配懒加载
  • 字体 也是<link rel="preload" as="font" href="font.woff2" type="font/woff2" crossorigin="anonymous">
  • 页面可见性触发
    结合 IntersectionObserver,提前加载资源
const observer = new IntersectionObserver((entries) => {entries.forEach(entry => {if (entry.isIntersecting) {fetch('/api/data.json'); // 或 import()observer.unobserve(entry.target);}});
});
observer.observe(document.querySelector('#future-content'));
http://www.dtcms.com/a/289885.html

相关文章:

  • NJU 凸优化导论(10) Approximation+Projection逼近与投影的应用(完结撒花)
  • InfluxDB 数据模型:桶、测量、标签与字段详解(二)
  • springboot --大事件--文章管理接口开发
  • 简洁高效的C++终端日志工具类
  • 响应式编程入门教程第七节:响应式架构与 MVVM 模式在 Unity 中的应用
  • SEO中关于关键词分类与布局的方法有那些
  • 【实战1】手写字识别 Pytoch(更新中)
  • Codes 通过创新的重新定义 SaaS 模式,专治 “原教旨主义 SaaS 的水土不服
  • 一文速通《二次型》
  • 复盘与导出工具最新版V27.0版本更新-新增财联社涨停,自选股,表格拖拽功能
  • Agentic-R1 与 Dual-Strategy Reasoning
  • Raspi4 切换QNX系统
  • cmake语法学习笔记
  • 模电基础-开关电路和NE555
  • 【2025西门子信息化网络化决赛】模拟题+技术文档+实验vrrp standby vxlan napt 智能制造挑战赛 助力国赛!
  • Linux之conda安装使用
  • 【数据结构】栈和队列(接口超完整)
  • 实践教程:基于RV1126与ZeroTier的RTSP摄像头内网穿透与远程访问
  • InfluxDB 数据模型:桶、测量、标签与字段详解(一)
  • iptables -m connlimit导致内存不足
  • 数据存储方案h5py
  • jdk9 -> jdk17 编程方面的变化
  • Product Hunt 每日热榜 | 2025-07-20
  • Feign远程调用
  • LWJGL教程(2)——游戏循环
  • VMware中mysql无法连接端口3306不通
  • 暑假训练之动态规划---动态规划的引入
  • PrimeTime:高级片上变化(AOCV)
  • 1948. 删除系统中的重复文件夹
  • 16.TaskExecutor启动