<progress>标签本身不自动监听资源加载,需手动跟踪资源、计算进度并安全更新DOM;常见失效原因包括value/max类型错误、属性更新方式不当、主线程阻塞及未覆盖全部资源类型。

直接用 <progress> 标签加不了真实页面加载进度条——它不监听任何资源,只等你手动赋值。 响应式模板里塞个 <progress value="30" max="100">,页面照样白屏三秒、进度条纹丝不动。真要让进度条动起来,得自己跟踪资源、控制节奏、避开渲染陷阱。
为什么 <progress> 在响应式模板里常“不动”
响应式模板通常含大量 CSS、字体、图片、异步 JS,但 <progress> 对这些完全无感。常见失效原因:
-
value和max写成字符串(如value="50"),部分浏览器转为 0 或忽略 - 只设
value="70"没设max="100",max默认是 1,结果直接显示 100% - 用
el.setAttribute("value", "50")更新——改的是 HTML attribute,不触发 UI 重绘 - 在
for循环里连续写bar.value = i++,主线程卡死,页面假死 - 把
document.readyState的三态("loading"/"interactive"/"complete")硬映射成百分比,不同模板结构下进度跳变极大
用 PerformanceObserver 抓真实资源加载(现代方案)
这是目前最可靠的方式,但必须在 <head> 最早位置初始化,否则错过首屏关键资源(比如 main.css 或 logo.png):
将 Markdown 文章转换为微信公众号兼容的纯 HTML 格式。当用户要求"转成微信格式"、"生成公众号文章 HTML"、"排版到微信草稿箱"、"微信粘贴格式"时触发。输出带内联样式的纯 HTML,微信编辑器可直接渲染,无需额外适配。支持标题、段落、列表、粗体、行内代码、表格、引用块、代码块、配图的完整转换。
- 监听
"resource"类型条目,过滤掉initiatorType === "xmlhttprequest"或"fetch"的条目(它们是 API 请求,不算页面加载资源) - 初始资源数建议用
document.querySelectorAll('script, link[rel="stylesheet"], img:not([data-src])')统计,再配合 observer 计数完成量 - 别直接用
entry.duration算占比——要用entry.startTime和entry.duration都相对于navigationStart的偏移,统一基准后算加权比例 - 最后 5–10% 必须留白:JS 执行、布局计算、字体渲染无法被 observer 捕获,硬填会导致进度卡在 95%
响应式场景下更新 DOM 的安全写法
响应式模板常带媒体查询、flex/grid 布局,DOM 更新稍不注意就触发重排或样式错乱:
立即学习“前端免费学习笔记(深入)”;
- 更新
<progress>时,必须用el.value = Math.round(percentage * 100),不能用setAttribute - 若用
<div>模拟进度条,推荐transform: scaleX(0.73)而非width: 73%—— 更平滑、硬件加速友好,且避免 flex 容器内 width 百分比失效问题 - iOS 15 之前对
scaleX(0)有渲染 bug,起始值建议设为scaleX(0.001) - 所有更新必须包在
requestAnimationFrame里,别用setTimeout,尤其别设固定 50ms 间隔——响应式切换时帧率波动大,容易丢帧 - 动态插入的资源(如懒加载图片、
import()异步模块)必须单独注册load事件并计入计数器,否则进度永远卡住
真正难的不是让进度条动起来,而是让它动得“可信”:既不能太快(让用户觉得假),也不能太慢(让用户失去耐心)。响应式模板里资源加载路径更复杂,CSS 媒体查询、字体加载、图片 srcset 切换都会影响实际耗时,这些都得进加权模型——没捷径,只能实测校准。


















