-
Notifications
You must be signed in to change notification settings - Fork 8.7k
FEATURE: 能否用 PerformanceObserver API 实现资源加载进度百分比 #7767
Copy link
Copy link
Open
Description
Version
Vben Admin V5
Description
不知道是否可行
这里有个演示,用 PerformanceObserver API 实现的资源加载进度百分比效果
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>真实字节加载进度</title>
<style>
#app-loading {
position: fixed;inset: 0;background:#fff;z-index:999999;
display:flex;align-items:center;justify-content:center;
transition:all 0.5s;
}
#app-loading.fade-out {
opacity:0;visibility:hidden;
}
.wrap { width:380px;display:flex;flex-direction:column;gap:20px }
.item { display:flex;flex-direction:column;gap:6px }
.txt { display:flex;justify-content:space-between;font-size:14px;color:#333 }
.bar { height:6px;background:#f2f2f2;border-radius:6px;overflow:hidden }
.fill { height:100%;width:0%;transition:width 0.15s linear }
.css .fill { background:#42b983 }
.js .fill { background:#1677ff }
</style>
</head>
<body>
<div id="app-loading">
<div class="wrap">
<div class="item css">
<div class="txt"><span>CSS 加载</span><span id="cssPct">0%</span></div>
<div class="bar"><div id="cssBar" class="fill"></div></div>
</div>
<div class="item js">
<div class="txt"><span>JS 加载</span><span id="jsPct">0%</span></div>
<div class="bar"><div id="jsBar" class="fill"></div></div>
</div>
</div>
</div>
<div id="app"></div>
<script>
const cssBar = document.getElementById('cssBar')
const jsBar = document.getElementById('jsBar')
const cssPct = document.getElementById('cssPct')
const jsPct = document.getElementById('jsPct')
const loading = document.getElementById('app-loading')
let cssTotal = 0, cssLoaded = 0
let jsTotal = 0, jsLoaded = 0
console.log('🚀 初始化加载监听')
// ==============================================
// 🔥 核心:使用 initiatorType 判断资源类型
// ==============================================
function handleEntry(entry) {
console.log('==================== 资源 Entry ====================')
console.log(entry)
const isResource = entry.entryType === 'resource'
const isCSS = entry.initiatorType === 'link'
const isJS = entry.initiatorType === 'script'
const size = entry.encodedBodySize || 0
console.log('✅ 处理资源:',
isCSS ? 'CSS' : isJS ? 'JS' : '其他',
' | initiatorType:', entry.initiatorType,
' | 大小:', size,
' | URL:', entry.name
)
if (!isResource) return
if (isCSS) {
cssTotal += size
cssLoaded += size
updateCSS()
}
if (isJS) {
jsTotal += size
jsLoaded += size
updateJS()
}
}
// ==============================================
// PerformanceObserver 监听
// ==============================================
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
handleEntry(entry)
}
})
observer.observe({ entryTypes: ['resource'] })
// ==============================================
// 进度更新
// ==============================================
function updateCSS() {
const p = cssTotal ? Math.min(100, (cssLoaded / cssTotal * 100) | 0) : 0
cssBar.style.width = p + '%'
cssPct.innerText = p + '%'
}
function updateJS() {
const p = jsTotal ? Math.min(100, (jsLoaded / jsTotal * 100) | 0) : 0
jsBar.style.width = p + '%'
jsPct.innerText = p + '%'
}
// ==============================================
// 页面完全加载后,强制完成
// ==============================================
window.addEventListener('load', () => {
console.log('🌍 页面完全加载')
setTimeout(() => {
cssBar.style.width = '100%'
cssPct.innerText = '100%'
jsBar.style.width = '100%'
jsPct.innerText = '100%'
setTimeout(() => loading.classList.add('fade-out'), 300)
}, 400)
})
</script>
</body>
</html>注意
这个API有安全策略,好象只能监听同源资源
The Content Security Policy directive 'upgrade-insecure-requests' is ignored when delivered in a report-only policy.
Proposed Solution
无
Alternatives Considered
No response
Additional Context
No response
Validations
- Read the docs
- Ensure the code is up to date. (Some issues have been fixed in the latest version)
- I have searched the existing issues and checked that my issue does not duplicate any existing issues.
Reactions are currently unavailable