Performance Optimization of a Vue2 + ElementUI Cloud Management Platform
This article describes how a legacy Vue2‑based cloud management system was profiled with Lighthouse and webpack‑bundle‑analyzer, then optimized through static asset compression, dead‑code removal, tree‑shaking, code‑splitting, async loading and server tweaks, achieving a three‑fold reduction in bundle size and a 13.6‑second improvement in first‑contentful‑paint time.
Background
The project is a third‑party purchased Vue2 + ElementUI cloud management platform that has been in development for over ten years, resulting in heavily bloated and inefficient code. The leadership demanded a drastic reduction in page load time because the current opening time exceeded ten seconds, threatening end‑of‑year targets.
How to verify that the optimization is effective?
1. Lighthouse Chrome extension
Open the DevTools (F12) and select the Lighthouse panel. Choose the Performance category and click Analyze page load . The report provides metrics such as First Contentful Paint (FCP) and Largest Contentful Paint (LCP) with a score.
2. webpack‑bundle‑analyzer
Install the analyzer with npm install --save-dev webpack-bundle-analyzer and add the plugin to webpack.config.js :
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
// ... other configuration ...
plugins: [
new BundleAnalyzerPlugin()
]
};Running the build generates a static site that visualizes the size of each module.
Optimization Results (with screenshots)
Performance metric explanation (Lighthouse): FCP measures the time until the browser renders the first DOM content; LCP measures when the largest visible element is rendered. The focus was on reducing FCP, which also improves LCP.
1. Pre‑optimization FCP
FCP was 15.8 seconds.
2. Pre‑optimization bundle size
Raw source size: 76.5 MB (Stat), 80.5 MB after webpack parsing, 13.5 MB gzipped. The first‑screen JavaScript (chunk‑vendors.js + app.js) accounted for the majority of the load.
Total Size
First‑Screen Size
Stat
76.5M
21.1M
Parsed
80.5M
24.2M
Gzipped
13.5M
5.9M
3. Post‑optimization bundle size
The total size dropped to 30.2 MB (Stat) and the gzipped size to 4.3 MB, a reduction of roughly 64 MB.
Total Size
First‑Screen Size
Stat
30.2M
15.2M
Parsed
16.6M
6.2M
Gzipped
4.3M
1.9M
4. Post‑optimization FCP
FCP improved by 13.6 seconds, bringing the load time down to roughly 2.2 seconds for a first visit. Subsequent visits benefit from browser caching and can achieve near‑instant loads.
How the optimization was performed
1. Static asset compression
Compressed JavaScript, CSS, images and SVGs. An oversized 1.5 MB SVG was replaced with a smaller iconfont, saving about 2.5 MB.
2. Remove unused routes and libraries, enable tree‑shaking
Deleted dead routes and unused third‑party libraries, then set mode: 'production' in webpack 4.46.0 to activate tree‑shaking.
3. Code‑splitting with async components
Only the home page component is bundled into app.js ; all other routes are loaded asynchronously using dynamic import() with explicit webpackChunkName comments.
import Home from '@views/Home.vue'
const router = [
// Home page – eager load
{ path: '/home', component: Home },
// Other pages – lazy load
{ path: '/xx', component: () => import(/* webpackChunkName: "xx" */ '@/views/xx.vue') }
];4. Defer non‑critical CSS/JS
Moved unrelated stylesheet and script tags out of the initial HTML and loaded them after the DOMContentLoaded event using JavaScript.
document.addEventListener('DOMContentLoaded', () => {
['../plugins/js/plugin.js', '../luckysheet.umd.js'].forEach(item => {
const script = document.createElement('script');
script.defer = true;
script.src = item;
document.body.appendChild(script);
});
['../plugins/css/pluginsCss.css', '../plugins/plugins.css', '../luckysheet.css', '../iconfont.css'].forEach(item => {
const link = document.createElement('link');
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = item;
document.head.appendChild(link);
});
});5. Server‑side improvements
Enabled HTTP/2 and Gzip compression on the server, which further reduced transfer time.
6. UI enhancements
Replaced ordinary loading spinners with skeleton screens to improve perceived performance.
Final Outcome
The optimized application shows dramatically lower bundle size, fewer network requests, and a first‑screen load time of 1.59 seconds (combined chunk‑vendors.js and app.js). The performance gains helped meet the end‑of‑year targets.
Conclusion
Through systematic profiling, asset compression, dead‑code elimination, tree‑shaking, code‑splitting, async loading, and server tweaks, a decade‑old Vue2 project was transformed into a fast, lightweight application.
Rare Earth Juejin Tech Community
Juejin, a tech community that helps developers grow.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.