如何实现页面加载进度条? 羽霏 ☘︎ 提问于 2026-03-02 12:11:18 阅读 13 优化 我在做项目首页,想加个顶部的加载进度条,但不知道怎么监听整体资源加载进度。 试过用 window.onload,但只能知道什么时候加载完,没法拿到中间的进度。也查了 performance.getEntriesByType('resource'),但感觉拿不到实时百分比啊。 现在用的是 Vue 3 + Vite,有没有办法在路由切换或初始加载时显示一个平滑的进度条?比如像 NProgress 那种,但我想自己实现核心逻辑。 体验优化加载进度 我来解答 赞 12 收藏 分享 生成中... 手机扫码查看 复制链接 生成海报 反馈 发表解答 您需要先 登录/注册 才能发表解答 1 条解答 上官天朝 Lv1 说实话,真实的资源加载进度基本拿不到精确值,浏览器的 API 限制就在那。实际项目中大多数进度条都是"假装"在加载,用一个定时器模拟进度,真正加载完了直接跳到 100%。 你用 Vue 3 + Vite 的话,分两个场景处理。 第一个场景是路由切换,这个好办,用 Vue Router 的导航守卫配合一个简单的进度条组件就行。写个简单的实现: // progress.js import { ref } from 'vue' const progress = ref(0) let timer = null let isDone = false export function useProgress() { const start = () => { progress.value = 0 isDone = false timer = setInterval(() => { if (isDone) return // 模拟进度,越往后越慢 const increment = Math.random() * 10 * (1 - progress.value / 100) progress.value = Math.min(95, progress.value + increment) }, 100) } const done = () => { isDone = true clearInterval(timer) progress.value = 100 setTimeout(() => { progress.value = 0 }, 300) } return { progress, start, done } } 路由守卫里这样用: // router/index.js import { createRouter, createWebHistory } from 'vue-router' import { useProgress } from './progress' const router = createRouter({ /* 你的路由配置 */ }) const { start, done } = useProgress() router.beforeEach((to, from, next) => { start() next() }) router.afterEach(() => { done() }) 第二个场景是首次加载,这个稍微麻烦点。你可以在 index.html 里内联一段 CSS 和 JS,让进度条在 Vue 还没挂载前就显示。Vite 打包后会有一个入口 JS,用 document.readyState 或者监听 load 事件来判断页面加载完成。 有几个安全点要注意。定时器一定要清理,不然内存泄漏,组件销毁时记得 clearInterval。还有进度条组件尽量用固定定位,别让其他元素影响它。如果你用用户输入来控制进度条(虽然不太可能),要做校验,防止恶意注入。 另外,如果你项目里有异步请求依赖,比如路由组件里要 fetch 数据,可以在组件里手动调 start 和 done,配合 Suspense 或者 loading 状态一起用。 基本上这样就能实现一个类似 NProgress 的效果了,代码也不多,自己掌控也更灵活。 回复 点赞 2026-03-02 12:15 加载更多 相关推荐 2 回答 16 浏览 为什么我的CSS旋转加载动画在页面加载时会突然卡顿一下? 我在做一个简单的旋转加载组件,用CSS3动画实现图标旋转。但每次页面加载时,图标会先显示0.5秒的静态状态,然后才开始旋转。我尝试过把animation-delay设为0和调整will-change属... 司马翌岍 组件 2026-02-16 18:11:24 1 回答 20 浏览 React中如何实现渐进增强的图片懒加载兼容旧浏览器? 我在用React做图片懒加载时遇到了问题,用IntersectionObserver实现的方案在IE11完全失效,基础图片都不显示了。我试过在组件里这样写: function LazyImage({ ... ლ雨诺 优化 2026-02-12 12:21:26 2 回答 20 浏览 Vue项目中使用IntersectionObserver实现加载进度条导致滚动卡顿怎么办? 在Vue项目里想用IntersectionObserver检测关键资源加载进度,然后发现滚动时页面卡顿,特别是资源较多时更明显。我尝试给每个资源元素添加了观察器,然后在回调里计算总进度: const ... 设计师硕辰 优化 2026-02-12 05:37:22 2 回答 38 浏览 React骨架屏组件在动态数据加载时如何保持布局一致性? 我在用Skeleton骨架屏实现列表加载效果时遇到了问题。当异步数据加载完成,真实内容替换骨架屏时,页面布局会突然跳动一下。 我已经尝试给Skeleton和真实内容都设置了相同的固定高度,但实际渲染后... 司马士媛 组件 2026-02-10 21:52:29 2 回答 46 浏览 预获取(prefetch)在单页应用中如何正确使用?为什么我的页面加载反而变慢了? 我在开发一个Vue单页应用时,尝试给下一页的图片列表页面添加预获取。按文档写了类似下面的代码,但发现首页加载反而变慢了,控制台显示预加载了大量图片资源。这是不是预获取用错了? <template... 西门智颖 优化 2026-01-27 23:52:24 2 回答 38 浏览 React中如何实现移动端图片列表的按需加载? 在开发移动端图片列表时,我尝试用Intersection Observer实现按需加载,但发现滚动到可视区时图片没及时加载。我按教程写了代码,但控制台报"Uncaught TypeError: obs... UE丶艳艳 移动 2026-01-27 20:46:25 2 回答 73 浏览 预加载图片时如何避免内存占用过高导致页面卡顿? 在做移动端图片列表页时,用Intersection Observer做预加载,但发现滚动时内存飙升,页面偶尔卡顿。我设置了同时加载5张临近图片,但测试发现已滑出屏幕的图片元素并未被回收... 尝试过在... 极客爱香 移动 2026-01-26 20:51:26 1 回答 24 浏览 步骤进度条加载状态怎么同步到每个步骤? 我在做一个多步骤表单,想在每个步骤切换时显示加载状态,但进度条的 activeIndex 和 loading 状态总是对不上。比如点“下一步”后 loading 是 true,但进度条却还没更新到下一... A. 春豪 交互 2026-03-05 07:10:19 1 回答 10 浏览 Webpack缓存没生效,页面还是重新加载了? 我用 Webpack 搭了个 React 项目,明明配置了 cache 缓存,但每次改点代码,整个页面都重新加载,连组件状态都没保住,是不是哪里配错了? 我试过在 webpack.config.js ... 开发者亚会 工具 2026-03-03 21:00:21 1 回答 9 浏览 智能预加载怎么判断用户下一步要访问哪个页面? 最近在做 React 项目性能优化,想实现“智能预加载”——比如用户在首页滚动到某个区域时,就提前加载商品详情页的资源。但我发现很难准确预测用户下一步会点哪里,目前只是简单地在 hover 时 pre... Mc.富水 优化 2026-03-03 17:05:20
你用 Vue 3 + Vite 的话,分两个场景处理。
第一个场景是路由切换,这个好办,用 Vue Router 的导航守卫配合一个简单的进度条组件就行。写个简单的实现:
路由守卫里这样用:
第二个场景是首次加载,这个稍微麻烦点。你可以在 index.html 里内联一段 CSS 和 JS,让进度条在 Vue 还没挂载前就显示。Vite 打包后会有一个入口 JS,用 document.readyState 或者监听 load 事件来判断页面加载完成。
有几个安全点要注意。定时器一定要清理,不然内存泄漏,组件销毁时记得 clearInterval。还有进度条组件尽量用固定定位,别让其他元素影响它。如果你用用户输入来控制进度条(虽然不太可能),要做校验,防止恶意注入。
另外,如果你项目里有异步请求依赖,比如路由组件里要 fetch 数据,可以在组件里手动调 start 和 done,配合 Suspense 或者 loading 状态一起用。
基本上这样就能实现一个类似 NProgress 的效果了,代码也不多,自己掌控也更灵活。