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

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

目录

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

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

懒加载

组件

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

  • 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.xdnf.cn/news/15819.html

相关文章:

  • AI绘画生成东汉末年赵云全身像的精细提示词
  • 四、多频技术与复杂场景处理
  • 基于卷积傅里叶分析网络 (CFAN)的心电图分类的统一时频方法
  • SpringBoot3集成MapstructPlus
  • GaussDB select into和insert into的用法
  • 基于智慧经营系统的学校住宿登记报表分析与应用探究-毕业论文—仙盟创梦IDE
  • Qt--Widget类对象的构造函数分析
  • 上电复位断言的自动化
  • 网络安全初级(前端页面的编写分析)
  • Java 递归方法详解:从基础语法到实战应用,彻底掌握递归编程思想
  • C++STL系列之list
  • Spring Boot 第一天知识汇总
  • UE5多人MOBA+GAS 26、为角色添加每秒回血回蓝(番外:添加到UI上)
  • redis-plus-plus安装与使用
  • 【vue-7】Vue3 响应式数据声明:深入理解 reactive()
  • 敏捷开发的历史演进:从先驱实践到全域敏捷(1950s-2025)
  • ubuntu 24.04 xfce4 钉钉输入抢焦点问题
  • XSS的学习笔记
  • ChatIM项目语音识别安装与使用
  • 拓展面试题之-rabbitmq面试题
  • [Python] -项目实战8- 构建一个简单的 Todo List Web 应用(Flask)
  • pip关于缓存的用法
  • Python Web框架详解:Flask、Streamlit、FastAPI
  • Pinia 核心知识详解:Vue3 新一代状态管理指南
  • 算法-递推
  • 在通信仿真场景下,Python 和 MATLAB 的性能差异主要体现在运行效率、并行计算、库支持、开发效率等方面。以下是基于最新资料的对比总结
  • AS32X601 系列 MCU 硬件最小系统设计与调试方案探析
  • Web-SQL注入数据库类型用户权限架构分层符号干扰利用过程发现思路
  • 基于SHAP的特征重要性排序与分布式影响力可视化分析
  • 两个路由器通过不同的网段互联