javascript实现页面加载进度条需手动跟踪资源:拦截script/img/link请求并计数,用performanceobserver监听resource获取真实耗时,ajax内容需绑定fetch/readablestream或xmlhttprequest.onprogress,css用transform: scalex()避免重排。

怎么用 JavaScript 监听页面资源加载进度
原生 HTML 没有内置的全局加载进度条机制,window.onload 和 DOMContentLoaded 都是“全有或全无”的事件,无法反映 0% → 100% 的连续进度。真要实现进度条,必须自己跟踪资源加载状态。
最可行的方式是拦截所有外部资源请求(主要是 script、img、link[rel="stylesheet"]),给每个创建一个加载标记,再用 Promise.all 或计数器汇总进度。
- 不要依赖
document.readyState—— 它只分 loading / interactive / complete 三态,无法提供百分比 - 动态插入的资源(如懒加载图片、异步
import())必须单独注册监听,否则进度会卡在 95% -
fetch()加载的数据不计入传统“页面加载”,需手动纳入进度计算逻辑
用 PerformanceObserver 捕获真实加载耗时(现代方案)
Chrome 80+ 支持通过 PerformanceObserver 监听 "navigation" 和 "resource" 类型的性能条目,能拿到每个脚本、样式表、图片的实际加载起止时间,比手动钩子更可靠。
注意:它不触发实时进度更新,但可用来校准进度条节奏——比如发现某张大图占了总加载时间的 60%,就该给它分配更高权重。
立即学习“前端免费学习笔记(深入)”;
- 必须在
尽早初始化,否则错过早期资源记录 - 监听
"resource"时,过滤掉initiatorType === "xmlhttprequest"的条目,避免混淆 API 请求和页面资源 -
entry.duration是毫秒值,但entry.startTime是相对 navigationStart 的偏移,需统一基准才能算占比
XMLHttpRequest 或 fetch 加载主内容时怎么同步进度条
如果页面主体内容由 AJAX 获取(比如 SPA 的首屏数据),那么进度条逻辑应绑定到这个请求,而不是 DOM 解析过程。此时 XMLHttpRequest 的 onprogress 事件可提供字节级进度,fetch 则需配合 ReadableStream 手动读取。
常见错误是把 fetch 当成黑盒,直接 .then() 等结果,完全丢失中间状态。
-
XMLHttpRequest要设xhr.responseType = "arraybuffer"才能触发onprogress(文本响应不触发) -
fetch+ReadableStream示例中,别忘了用controller.desiredSize控制 chunk 大小,否则可能一次读完全部,进度跳变 - 服务端必须返回
Content-Length,否则event.loaded和event.total都为 0
CSS 进度条结构怎么写才不拖慢渲染
进度条本身要是“不影响主线程”的——不能用 setTimeout 频繁重绘,也不能用大尺寸 box-shadow 或 filter 导致合成层爆炸。
推荐用单个 <div> + <code>transform: scaleX() 实现宽度变化,GPU 加速且无重排。
- 别用
width百分比动画,会触发 layout;scaleX()只走合成管线 - 初始状态建议设
opacity: 0.001而非display: none,避免后续显示时触发回流 - 移动端要注意
will-change: transform可能导致内存占用上升,仅在进度活跃时添加











