Vue中如何在initiator、assets资源加载完成后执行console.log("all resource done ")
实现initiator、assets类型资源加载完成后执行指定代码
下面分常规前端和Vue场景给出具体实现方案:
常规前端场景
方案1:用PerformanceObserver自动监听资源加载
适合不知道具体资源URL的场景,通过监听浏览器性能条目筛选目标资源:
// 定义需要监听的资源类型(可根据实际需求调整) const targetRules = { // assets类型:图片、样式表、字体等静态资源 assetInitiators: ['img', 'stylesheet', 'font'], // 指定的initiator类型:脚本、fetch请求等 targetInitiators: ['script', 'fetch'] }; const completedResources = new Set(); const observer = new PerformanceObserver((entryList) => { entryList.getEntries().forEach(entry => { // 判断当前资源是否属于目标类型 const isAsset = targetRules.assetInitiators.includes(entry.initiatorType); const isTargetInitiator = targetRules.targetInitiators.includes(entry.initiatorType); if (isAsset || isTargetInitiator) { // responseEnd > 0 说明资源已加载完成 if (entry.responseEnd > 0 && !completedResources.has(entry.name)) { completedResources.add(entry.name); checkIfAllDone(observer); } } }); }); // 启动监听资源加载事件 observer.observe({ entryTypes: ['resource'] }); function checkIfAllDone(observer) { // 获取所有符合条件的目标资源总数 const allTargetResources = performance.getEntriesByType('resource').filter(entry => { const isAsset = targetRules.assetInitiators.includes(entry.initiatorType); const isTargetInitiator = targetRules.targetInitiators.includes(entry.initiatorType); return isAsset || isTargetInitiator; }); // 已完成数量等于总数时执行代码 if (completedResources.size === allTargetResources.length) { console.log("all resource done "); observer.disconnect(); // 停止监听,避免重复触发 } } // 页面load后兜底检查,防止遗漏 window.addEventListener('load', () => setTimeout(checkIfAllDone, 0));
方案2:手动跟踪已知资源URL
如果清楚需要等待的资源具体地址,可逐个监听加载状态:
// 列出所有需要等待的目标资源URL const targetResources = [ '/static/img/banner.jpg', '/static/css/main.css', '/static/js/utils.js' ]; let doneCount = 0; function markResourceDone() { doneCount++; if (doneCount === targetResources.length) { console.log("all resource done "); } } targetResources.forEach(url => { if (url.match(/\.(jpg|png|gif)$/)) { const img = new Image(); img.src = url; img.onload = markResourceDone; img.onerror = markResourceDone; // 加载失败也计入完成,可根据需求修改 } else if (url.endsWith('.css')) { const link = document.createElement('link'); link.rel = 'stylesheet'; link.href = url; link.onload = markResourceDone; link.onerror = markResourceDone; document.head.appendChild(link); } else if (url.endsWith('.js')) { const script = document.createElement('script'); script.src = url; script.onload = markResourceDone; script.onerror = markResourceDone; document.body.appendChild(script); } });
Vue框架场景
方案1:在根组件中使用PerformanceObserver
在App.vue的mounted钩子中实现,确保页面挂载后开始监听:
<template> <div id="app"> <!-- 你的应用内容 --> </div> </template> <script> export default { mounted() { const targetRules = { assetInitiators: ['img', 'stylesheet', 'font'], targetInitiators: ['script', 'fetch'] }; const completedResources = new Set(); const observer = new PerformanceObserver((entryList) => { entryList.getEntries().forEach(entry => { const isAsset = targetRules.assetInitiators.includes(entry.initiatorType); const isTargetInitiator = targetRules.targetInitiators.includes(entry.initiatorType); if (isAsset || isTargetInitiator) { if (entry.responseEnd > 0 && !completedResources.has(entry.name)) { completedResources.add(entry.name); this.checkCompletion(completedResources, targetRules, observer); } } }); }); observer.observe({ entryTypes: ['resource'] }); window.addEventListener('load', () => { setTimeout(() => this.checkCompletion(completedResources, targetRules, observer), 0); }); }, methods: { checkCompletion(completed, rules, observer) { const allTargets = performance.getEntriesByType('resource').filter(entry => { const isAsset = rules.assetInitiators.includes(entry.initiatorType); const isTarget = rules.targetInitiators.includes(entry.initiatorType); return isAsset || isTarget; }); if (completed.size === allTargets.length) { console.log("all resource done "); observer.disconnect(); } } } }; </script>
方案2:等待项目内静态资源加载完成
如果是项目中通过@/assets引入的资源,可用Promise等待加载完毕:
<template> <div id="app"> <!-- 组件内容 --> </div> </template> <script> export default { async mounted() { // 列出需要等待的静态资源路径 const resourcePaths = [ require('@/assets/logo.png'), require('@/assets/global.css') ]; // 把每个资源转为加载Promise const loadTasks = resourcePaths.map(path => { return new Promise(resolve => { if (path.match(/\.(png|jpg|svg)$/)) { const img = new Image(); img.src = path; img.onload = resolve; img.onerror = resolve; } else if (path.endsWith('.css')) { const link = document.createElement('link'); link.rel = 'stylesheet'; link.href = path; link.onload = resolve; link.onerror = resolve; document.head.appendChild(link); } }); }); // 等待所有资源加载完成 await Promise.all(loadTasks); console.log("all resource done "); } }; </script>
内容的提问来源于stack exchange,提问作者Sinan BENLİBAŞ
相关产品推荐
相关产品推荐

