HTML5原生不提供页面加载进度条,progress标签需手动控制value和max;可用document.readyState+setTimeout粗略模拟,或PerformanceObserver监听资源加载,但均属估算而非精确反映。

HTML5 原生不提供页面加载进度条
直接说结论: 标签本身不监听页面资源加载,它只是个空壳控件,需要你手动控制 value 和 max。浏览器不会自动把 HTML 解析、JS 加载、图片下载这些过程映射到它上面。
所以“页面加载进度条”本质是「模拟」或「估算」,不是真实反映 DOMContentLoaded 或 load 事件的精确百分比。
用 document.readyState + setTimeout 做粗略模拟
适合对精度要求不高、想快速上线一个视觉反馈的场景。原理是:在 DOMContentLoaded 触发前,按时间推移逐步增加 的 value,等真正加载完成时跳到 100%。
-
document.readyState === 'loading'时启动计时器,每 50ms 增加 1~2 - 遇到
document.readyState === 'interactive'(DOM 解析完)立即设为 80% 左右 - 监听
window.addEventListener('load', ...),此时设value = 100 - 注意避免重复触发:计时器要在
load后clearTimeout或clearInterval
示例片段:
立即学习“前端免费学习笔记(深入)”;
用 PerformanceObserver 监听资源加载更靠谱
如果你真想反映资源加载状态(比如 JS、CSS、图片),得靠 PerformanceObserver 订阅 'resource' 类型事件。但它不能告诉你“还剩几个没加载完”,只能告诉你“又完成了一个”。所以你需要预先统计关键资源数量。
- 先用
document.querySelectorAll('script, link[rel="stylesheet"], img')数出待加载资源数(注意排除data-src懒加载图) - 用
PerformanceObserver监听resource,每次回调检查entry.initiatorType是否匹配目标类型 - 每完成一个,就递增计数器并更新
;全部完成再补上最后 5~10% 给其他开销(如渲染、JS 执行) - 兼容性注意:
PerformanceObserver在 IE 完全不可用,Safari 11+、Chrome 59+ 支持
第三方库如 nprogress 为什么更常用
因为手写容易漏掉边界情况:比如异步 JS 动态插入的 script、fetch 请求、字体加载、Web Worker 初始化……这些都不会触发 load 事件,但用户感知上仍是“页面还没准备好”。
-
nprogress默认在pushState、ajaxStart等钩子自动增减进度,也支持手动NProgress.start()/NProgress.done() - 它用的是
opacity+transform实现顶部细条,不依赖,样式更可控 - 但要注意:它不解决“真实加载耗时”问题,只是交互节奏管理——这点和原生
一样,只是封装得更稳
真正难的不是画一条进度条,而是定义“加载完成”的语义:是 DOM 就绪?首屏渲染?还是某个核心 API 返回成功?这个判断点一旦错位,进度条就会卡在 99% 或闪退——比没进度条还误导人。










