You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现静态HTML页面的加载进度百分比显示?

实现带百分比的页面加载进度条

浏览器并没有原生API能直接获取页面所有待加载资源的总大小,所以没法直接精确计算真实的加载百分比。市面上的进度条大多采用以下两种可行方案:

方案1:视觉模拟进度条(最常用)

这种方案不需要统计真实资源加载量,通过流畅的动画模拟加载进度,最后在页面完全加载时直接跳至100%,用户感知自然,实现成本极低。

实现代码

<!-- 全屏加载遮罩,默认显示 -->
<div id="loader" style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: #fff; display: flex; flex-direction: column; align-items: center; justify-content: center; z-index: 9999;">
  <div style="width: 60%; height: 4px; background: #eee; border-radius: 2px; overflow: hidden;">
    <div id="progress-bar" style="width: 0%; height: 100%; background: #2196F3; transition: width 0.3s ease;"></div>
  </div>
  <p id="progress-text" style="margin-top: 16px; font-size: 14px; color: #666;">0%</p>
</div>

<!-- 页面内容,默认隐藏 -->
<div id="content" style="display: none;">
  <!-- 你的页面内容,比如图片、文本、脚本等 -->
  <img src="image1.jpg" alt="示例图1">
  <img src="image2.jpg" alt="示例图2">
  <script src="script.js"></script>
</div>

<script>
const loader = document.getElementById('loader');
const progressBar = document.getElementById('progress-bar');
const progressText = document.getElementById('progress-text');
const content = document.getElementById('content');

let currentProgress = 0;
// 定时递增进度,模拟加载波动
const progressTimer = setInterval(() => {
  currentProgress += Math.floor(Math.random() * 5) + 1;
  // 进度停在90%,留到最后加载完成再跳100%
  if (currentProgress > 90) currentProgress = 90;
  updateProgress(currentProgress);
}, 200);

// 更新进度条和文本
function updateProgress(percent) {
  progressBar.style.width = `${percent}%`;
  progressText.textContent = `${percent}%`;
}

// 监听页面所有资源加载完成
window.addEventListener('load', () => {
  updateProgress(100);
  // 等待动画完成后隐藏遮罩、显示内容
  setTimeout(() => {
    loader.style.display = 'none';
    content.style.display = 'block';
  }, 300);
  clearInterval(progressTimer);
});
</script>

说明

这种方式避免了真实加载可能出现的卡顿、停滞问题,用户体验流畅,是绝大多数网站的选择。

方案2:手动统计的真实进度条

如果需要真实反映资源加载进度,需要预先统计所有资源的大小,再逐个监听加载状态计算百分比。

实现代码

<div id="loader" style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: #fff; display: flex; flex-direction: column; align-items: center; justify-content: center; z-index: 9999;">
  <div style="width: 60%; height: 4px; background: #eee; border-radius: 2px; overflow: hidden;">
    <div id="progress-bar" style="width: 0%; height: 100%; background: #2196F3; transition: width 0.2s ease;"></div>
  </div>
  <p id="progress-text" style="margin-top: 16px; font-size: 14px; color: #666;">0%</p>
</div>

<div id="content" style="display: none;">
  <!-- 页面内容容器 -->
</div>

<script>
const loader = document.getElementById('loader');
const progressBar = document.getElementById('progress-bar');
const progressText = document.getElementById('progress-text');
const content = document.getElementById('content');

// 手动维护资源列表:URL + 文件大小(单位:字节)
const resources = [
  { url: 'image1.jpg', size: 123456 },
  { url: 'image2.jpg', size: 789012 },
  { url: 'script.js', size: 45678 },
  { url: 'style.css', size: 23456 },
  // 补充其他需要加载的资源
];

let totalSize = 0;
let loadedSize = 0;

// 计算总资源大小
resources.forEach(res => totalSize += res.size);

// 更新进度
function updateProgress() {
  const percent = Math.floor((loadedSize / totalSize) * 100);
  progressBar.style.width = `${percent}%`;
  progressText.textContent = `${percent}%`;
  
  // 所有资源加载完成
  if (percent >= 100) {
    setTimeout(() => {
      loader.style.display = 'none';
      content.style.display = 'block';
      // 这里可以初始化页面逻辑
    }, 300);
  }
}

// 加载单个资源
function loadResource(resource) {
  return new Promise((resolve) => {
    if (resource.url.match(/\.(jpg|png|gif)$/)) {
      // 加载图片
      const img = new Image();
      img.onload = img.onerror = () => {
        loadedSize += resource.size;
        updateProgress();
        resolve();
      };
      img.src = resource.url;
    } else if (resource.url.endsWith('.js')) {
      // 加载脚本
      const script = document.createElement('script');
      script.onload = script.onerror = () => {
        loadedSize += resource.size;
        updateProgress();
        resolve();
      };
      script.src = resource.url;
      document.body.appendChild(script);
    } else if (resource.url.endsWith('.css')) {
      // 加载样式
      const link = document.createElement('link');
      link.rel = 'stylesheet';
      link.onload = link.onerror = () => {
        loadedSize += resource.size;
        updateProgress();
        resolve();
      };
      link.href = resource.url;
      document.head.appendChild(link);
    }
    // 其他类型资源(如字体)可同理扩展
  });
}

// 批量加载所有资源
async function loadAllResources() {
  for (const res of resources) {
    await loadResource(res);
  }
}

// 启动加载流程
loadAllResources();
</script>

说明

这种方案能实现真实的加载百分比,但需要手动维护资源列表和大小,资源更新时需同步修改;另外如果资源被缓存,可能不会触发加载事件,需要额外处理缓存逻辑。

内容的提问来源于stack exchange,提问作者Manjesh R V

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 12:22:41