Frontend Performance Optimization for SCM Application
By shrinking HTML to under 14 KB, replacing large global packages with selective imports, introducing dynamic and lazy loading, externalizing stable libraries via CDN, and caching menu data, the SCM frontend’s common bundle dropped from 1.4 MB to below 200 KB, dramatically improving first‑paint rates and overall page‑load performance.
The SCM (Supply Chain Management) backend has grown increasingly complex, leading to slow page load times and a poor user experience.
Analysis of performance metrics showed that the first‑paint (FMP) rate was below 20% before optimization, with noticeable fluctuations after each release.
Diagnostic Tools
We used Chrome DevTools Performance to identify bottlenecks, webpack‑bundle‑analyzer to inspect bundle composition, and added --report to vue-cli-service or ANALYZE=1 to umi builds.
Static Resource Optimization
HTML size was reduced to under 14 KB to fit a single TCP packet, and the runtime chunk was removed from the HTML, shrinking it from 18 KB to ~1 KB.
Bundle analysis revealed that the @du/earth package occupied ~40% of the common bundle. By replacing global registration with selective component imports, the chunk‑libs size dropped from 1.4 MB to 730 KB.
Dynamic imports were introduced for rarely used components, e.g.:
import Vue from 'vue'
// before
import VueBarcode from '@xkeshi/vue-barcode'
Vue.component('barcode', VueBarcode)
// after
Vue.component('barcode', () => import('@xkeshi/vue-barcode'))We also addressed oversized dependencies such as @du/umi-request by collaborating with maintainers to adjust its import strategy.
Assets Bundling
To leverage CDN caching, we configured externals for stable libraries and used Webpack’s DllPlugin to pre‑bundle them:
{
externals: {
'vue': 'Vue',
'vuex': 'vuex',
'vue-router': 'VueRouter'
}
} {
pluginOptions: {
dll: {
entry: { vendor: ['vue', 'vue-router', 'vuex', '@du/element-ui'] },
output: { path: path.resolve(__dirname, './dll'), filename: '[name].js' },
inject: false
}
}
}These DLL files are uploaded to a CDN and referenced in index.html via CopyWebpackPlugin and HtmlWebpackPlugin .
Layout Rendering Improvements
We cached menu data to avoid a 200 ms API call during initial render and moved the layout out of a nested route, allowing the main UI to render immediately.
function getMenuList() {
return new Promise(resolve => {
const cache = getMenuListFromCache()
if (cache) { resolve(cache); store.dispatch('app/menuList', cache); return }
getMenuListFromApi(res => { setMenuListCache(res.data); store.dispatch('app/menuList', res.data); })
})
}Long‑task analysis highlighted excessive component initialization and reactive menu processing. Solutions included lazy‑loading components and freezing static menu data:
const frozenMenu = Object.freeze(menuData)
store.dispatch('app/menuList', frozenMenu)Performance timing via performance.now() was used to verify improvements:
const t1 = performance.now()
// heavy code
console.log(performance.now() - t1)After applying these optimizations, the common bundle size fell below 200 KB, and the overall page load experience improved noticeably.
DeWu Technology
A platform for sharing and discussing tech knowledge, guiding you toward the cloud of technology.
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.