普通视图

发现新文章,点击刷新页面。
今天 — 2026年3月6日首页

移动端调试工具VConsole初始化时的加载阻塞问题

2026年3月5日 21:00

问题复现(场景:小程序应用)

将VConsole下载到本地进行,在main.js中进行初始化,当上线后,页面首次加载会出现卡顿空白页,刷新之后显示正常


import Vue from 'vue'

import App from './App.vue'

import router from './router'

import ElementUI from 'element-ui'

import 'element-ui/lib/theme-chalk/index.css'

import VConsole from 'vconsole'

new VConsole();

new Vue({

render: h => h(App),

router,

}).$mount('#app')

阻塞原因

首次加载无缓存 + VConsole 初始化抢占主线程,阻塞了页面渲染;第二次刷新有缓存,VConsole 加载 / 初始化耗时骤降,不再阻塞

「第一次卡顿白屏」

当在 main.js 里直接 new VConsole() 时,会发生下面过程:

  • ✅ 资源无缓存:第一次进页面,浏览器要从网络下载 vconsole.js 源码(约 150KB),占网络带宽,拖慢页面 JS 加载;
  • ✅ 抢占主线程:VConsole 初始化时,会做「重写 console、插 DOM 面板、监听网络请求」等操作,这些操作和 Vue 初始化、页面 DOM 渲染抢同一根「主线程」,浏览器顾此失彼,页面来不及渲染就白屏;
  • ✅ 时序冲突:VConsole 初始化和 Vue 挂载($mount('#app'))同时执行,甚至更早,直接打乱页面渲染节奏,导致首屏出不来。

2.「第二次就正常」

第二次进页面时:

  • ✅ 资源有缓存:浏览器已经把 vconsole.js 存在本地,不用再从网络下载,加载耗时从几百毫秒降到几毫秒;
  • ✅ 初始化变快:VConsole 初始化的核心资源(如样式、面板模板)都在缓存里,主线程占用时间大幅减少,不会再阻塞 Vue 渲染和页面显示。

即使下载依赖到本地,只要在main.js立刻初始化同样会造成阻塞


加延迟让vue先完初始化,console再进行加载

加延迟解决卡顿

import { createApp } from 'vue'

import App from './App.vue'

// 1. 先挂载 Vue 应用

const app = createApp(App)

app.mount('#app')

// 2. 延迟初始化 VConsole(仅开发环境)

if (process.env.NODE_ENV === 'development') {

setTimeout(() => {

import('vconsole').then(({ default: VConsole }) => {

new VConsole()

})

}, 100)

}

虽然加延迟能解决卡顿,但是看不到初始化运行时加载的其他js文件

利用async和preload解决卡顿问题,但是会丢失少部分初始化最开始的加载日志文件

比如这样:、

<head>

<!-- VConsole异步加载 -->

<script src="https://cdn.bootcdn.net/ajax/libs/vConsole/3.15.0/vconsole.min.js" async></script>

<!-- 项目JS正常引入(也可加async) -->

<script src="./js/chunk-vendors.js"></script>

<script src="./js/app.js"></script>

<script>

// 等页面所有资源加载完,再初始化VConsole(避免卡顿)

window.addEventListener('load', () => {

if (window.VConsole) { // 检查VConsole是否加载完成

new window.VConsole({ disableLogScrolling: true });

console.log('VConsole初始化完成(async方案)');

// 此时执行你的日志打印逻辑

window.printNewJS();

}

});

// 你的printNewJS等逻辑保留

window.printedJS = new Set();

window.printNewJS = function() 

</script>

</head>

终极解决方案:先完成console的初始化再引入打包配的.js文件

<head>

<!-- 预加载VConsole,加速下载 -->

<link rel="preload" href="https://cdn.bootcdn.net/ajax/libs/vConsole/3.15.0/vconsole.min.js" as="script">

<script>

// 先加载并初始化VConsole

const scriptVConsole = document.createElement('script');

scriptVConsole.src = "https://cdn.bootcdn.net/ajax/libs/vConsole/3.15.0/vconsole.min.js";

scriptVConsole.onload = () => {

new VConsole();

console.log('VConsole初始化完成');

// VConsole就绪后,动态引入项目JS(保留日志)

loadProjectJS();

};
document.head.appendChild(scriptVConsole);

// 动态引入项目JS(原逻辑)

function loadProjectJS() {

const projectJS = ['./js/chunk-vendors.js', './js/app.js'];

projectJS.forEach(path => {

const script = document.createElement('script');

script.src = path;

document.body.appendChild(script);

});

}

</script>

</head>

但是这样有一个缺点:会有一个短暂的空白,所以可以给idnex.html中加入一个loading提示过渡,这样就可以查看项目运行过程中整个所有加载的文件运行状态结果

❌
❌