当前位置: 首页 > 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.lryc.cn/news/594038.html

相关文章:

  • 笔试——Day13
  • 群组功能实现指南:从数据库设计到前后端交互,上班第二周
  • SmartyPants
  • git fork的项目远端标准协作流程 仓库设置[设置成upstream]
  • [硬件电路-55]:绝缘栅双极型晶体管(IGBT)的原理与应用
  • Elasticsearch 简化指南:GCP Google Compute Engine
  • windows + phpstorm 2024 + phpstudy 8 + php7.3 + thinkphp6 配置xdebug调试
  • Qt 应用程序入口代码分析
  • QT无边框窗口
  • 学习C++、QT---30(QT库中如何自定义控件(自定义按钮)讲解)
  • 在vue中遇到Uncaught TypeError: Assignment to constant variable(常亮无法修改)
  • Ajax简单介绍及Axios请求方式的别名
  • 最简单的 Android TV 项目示例
  • Request和Response相关介绍
  • SparseTSF:用 1000 个参数进行长序列预测建模
  • 分享如何在Window系统的云服务器上部署网站及域名解析+SSL
  • [数据库]Neo4j图数据库搭建快速入门
  • 理解操作系统
  • Leetcode 06 java
  • 深入理解设计模式:访问者模式详解
  • VSCode中Cline无法正确读取终端的问题解决
  • 详解Mysql Order by排序底层原理
  • 金融大前端中的 AI 应用:智能投资顾问与风险评估
  • Facebook 开源多季节性时间序列数据预测工具:Prophet 快速入门 Quick Start
  • Centos卷挂载失败系统无法启动
  • 【Java项目安全基石】登录认证实战:Session/Token/JWT用户校验机制深度解析
  • Android系统5层架构
  • 手推OpenGL相机的正交投影矩阵和透视投影矩阵(附源码)
  • Java 大视界 -- Java 大数据在智能安防门禁系统中的权限动态管理与安全审计(353)
  • LeetCode第337题_打家劫舍III