Vue首屏加載出現(xiàn)白屏問題的優(yōu)化實戰(zhàn)
一、背景
在實際開發(fā)中,Vue 應(yīng)用首次加載時經(jīng)常出現(xiàn)白屏問題,這嚴(yán)重影響了用戶體驗。本文將從多個角度出發(fā),提供全面的解決方案。
二、問題分析
2.1 白屏原因
- JavaScript 資源體積過大
- 首屏渲染機(jī)制的特點
- 資源加載順序不合理
- 服務(wù)端配置問題
- 瀏覽器緩存策略
三、解決方案
3.1 路由懶加載優(yōu)化
// 修改前
import UserDetails from './views/UserDetails.vue'
// 修改后 - 方案1:簡單懶加載
const UserDetails = () => import('./views/UserDetails.vue')
// 方案2:分組懶加載
const UserDetails = () => import(/* webpackChunkName: "user" */ './views/UserDetails.vue')
const UserProfile = () => import(/* webpackChunkName: "user" */ './views/UserProfile.vue')
3.2 骨架屏方案
手動實現(xiàn)
<!-- SkeletonComponent.vue -->
<template>
<div class="skeleton">
<div class="skeleton-header"></div>
<div class="skeleton-content">
<div class="skeleton-item"></div>
<div class="skeleton-item"></div>
</div>
</div>
</template>
<style scoped>
.skeleton {
padding: 15px;
}
.skeleton-header {
height: 20px;
background: #f2f2f2;
margin-bottom: 15px;
animation: skeleton-loading 1s infinite alternate;
}
.skeleton-item {
height: 60px;
background: #f2f2f2;
margin-bottom: 10px;
animation: skeleton-loading 1s infinite alternate;
}
@keyframes skeleton-loading {
from { opacity: 0.6; }
to { opacity: 1; }
}
</style>
自動化方案
推薦使用 vue-skeleton-webpack-plugin 插件:
npm install vue-skeleton-webpack-plugin -D
配置示例:
// vue.config.js
const SkeletonWebpackPlugin = require('vue-skeleton-webpack-plugin')
module.exports = {
configureWebpack: {
plugins: [
new SkeletonWebpackPlugin({
webpackConfig: {
entry: {
app: path.join(__dirname, './src/skeleton.js'),
},
},
minimize: true,
quiet: true,
router: {
mode: 'hash',
routes: [
{ path: '/', skeletonId: 'skeleton1' },
{ path: '/about', skeletonId: 'skeleton2' }
]
}
})
]
}
}
3.3 資源預(yù)加載優(yōu)化
基礎(chǔ)配置
<!-- index.html --> <head> <!-- DNS預(yù)解析 --> <link rel="dns-prefetch" > <!-- 預(yù)加載關(guān)鍵資源 --> <link rel="preload" href="/fonts/important.woff2" as="font" crossorigin> <!-- 預(yù)加載組件 --> <link rel="prefetch" href="/js/non-critical.js"> </head>
預(yù)渲染方案
對于靜態(tài)內(nèi)容較多的頁面,推薦使用 prerender-spa-plugin:
npm install prerender-spa-plugin -D
配置示例:
// vue.config.js
const PrerenderSPAPlugin = require('prerender-spa-plugin')
module.exports = {
configureWebpack: {
plugins: [
new PrerenderSPAPlugin({
staticDir: path.join(__dirname, 'dist'),
routes: ['/', '/about', '/contact'],
renderer: new PrerenderSPAPlugin.PuppeteerRenderer({
renderAfterDocumentEvent: 'render-event'
})
})
]
}
}
3.4 Webpack 構(gòu)建優(yōu)化
體積分析與優(yōu)化
推薦使用 webpack-bundle-analyzer 分析打包體積:
npm install webpack-bundle-analyzer -D
// vue.config.js
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
module.exports = {
configureWebpack: {
plugins: [
new BundleAnalyzerPlugin()
]
}
}
構(gòu)建速度優(yōu)化
使用 hard-source-webpack-plugin 提升構(gòu)建速度:
npm install hard-source-webpack-plugin -D
// vue.config.js
const HardSourceWebpackPlugin = require('hard-source-webpack-plugin')
module.exports = {
configureWebpack: {
plugins: [
new HardSourceWebpackPlugin()
]
}
}
Gzip 壓縮
使用 compression-webpack-plugin 實現(xiàn):
npm install compression-webpack-plugin -D
// vue.config.js
const CompressionWebpackPlugin = require('compression-webpack-plugin')
module.exports = {
configureWebpack: {
plugins: [
new CompressionWebpackPlugin({
test: /\.(js|css|html|svg)$/,
threshold: 10240
})
]
}
}
構(gòu)建分析
使用 speed-measure-webpack-plugin 分析構(gòu)建過程:
npm install speed-measure-webpack-plugin -D
// vue.config.js
const SpeedMeasurePlugin = require("speed-measure-webpack-plugin")
const smp = new SpeedMeasurePlugin()
module.exports = {
configureWebpack: smp.wrap({
// ... 其他配置
})
}
3.5 開發(fā)調(diào)試優(yōu)化
Vue DevTools
- 安裝:通過 Chrome 插件商店安裝
- 功能:
- 組件樹分析
- 性能分析
- 狀態(tài)管理
- 路由調(diào)試
性能分析工具
Chrome Lighthouse
- 內(nèi)置于 Chrome DevTools
- 提供性能評分
- 給出優(yōu)化建議
- 生成詳細(xì)報告
webpack-dashboard
npm install webpack-dashboard -D
// vue.config.js
const DashboardPlugin = require('webpack-dashboard/plugin')
module.exports = {
configureWebpack: {
plugins: [
new DashboardPlugin()
]
}
}
3.6 服務(wù)端渲染 (SSR)
// entry-server.js
import { createApp } from './app'
export default context => {
return new Promise((resolve, reject) => {
const { app, router, store } = createApp()
router.push(context.url)
router.onReady(() => {
const matchedComponents = router.getMatchedComponents()
if (!matchedComponents.length) {
return reject({ code: 404 })
}
Promise.all(matchedComponents.map(Component => {
if (Component.asyncData) {
return Component.asyncData({
store,
route: router.currentRoute
})
}
})).then(() => {
context.state = store.state
resolve(app)
}).catch(reject)
}, reject)
})
}
3.7 靜態(tài)資源 CDN 加速
// vue.config.js
module.exports = {
chainWebpack: config => {
config.externals({
'vue': 'Vue',
'vuex': 'Vuex',
'vue-router': 'VueRouter',
'axios': 'axios'
})
}
}
<!-- index.html --> <head> <link rel="stylesheet" > <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script> <script src="https://cdn.jsdelivr.net/npm/vuex@3.6.2"></script> <script src="https://cdn.jsdelivr.net/npm/vue-router@3.5.3"></script> <script src="https://cdn.jsdelivr.net/npm/axios@0.24.0"></script> </head>
3.8 瀏覽器緩存優(yōu)化
# nginx.conf
location / {
add_header Cache-Control "public, max-age=31536000";
# 配置協(xié)商緩存
etag on;
if_modified_since exact;
# 開啟gzip
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
}
四、推薦插件和工具
4.1 性能優(yōu)化插件
vue-skeleton-webpack-plugin
npm install vue-skeleton-webpack-plugin -D
用于自動生成骨架屏,支持多路由頁面的骨架屏配置。
prerender-spa-plugin
npm install prerender-spa-plugin -D
預(yù)渲染插件,適用于靜態(tài)內(nèi)容較多的頁面。
compression-webpack-plugin
npm install compression-webpack-plugin -D
用于 Gzip 壓縮,大幅減小文件體積。
webpack-bundle-analyzer
npm install webpack-bundle-analyzer -D
分析打包體積,找出大文件并優(yōu)化。
hard-source-webpack-plugin
npm install hard-source-webpack-plugin -D
為模塊提供中間緩存,大幅提升二次構(gòu)建速度。
speed-measure-webpack-plugin
npm install speed-measure-webpack-plugin -D
分析 webpack 打包速度,找出耗時步驟。
4.2 開發(fā)調(diào)試工具
vue-devtools
- Chrome 插件商店安裝
- 用于組件調(diào)試和性能分析
Lighthouse
- Chrome 開發(fā)者工具內(nèi)置
- 提供全面的性能評分和優(yōu)化建議
webpack-dashboard
npm install webpack-dashboard -D
優(yōu)化 webpack 開發(fā)輸出界面,提供更直觀的信息。
五、性能檢測與監(jiān)控
5.1 性能指標(biāo)
- First Paint (FP)
- First Contentful Paint (FCP)
- Time to Interactive (TTI)
- Total Blocking Time (TBT)
5.2 檢測工具
- Vue DevTools
- Chrome Lighthouse
- webpack-bundle-analyzer
- Performance API
// 性能監(jiān)控示例
window.performance.mark('vue-init-start')
// Vue 初始化完成后
window.performance.mark('vue-init-end')
window.performance.measure(
'vue-init',
'vue-init-start',
'vue-init-end'
)
六、最佳實踐建議
- 合理使用路由懶加載,避免一次性加載過多組件
- 使用骨架屏提升用戶體驗
- 關(guān)鍵資源預(yù)加載,非關(guān)鍵資源延遲加載
- webpack 配置優(yōu)化,合理分包
- 考慮引入服務(wù)端渲染
- 利用瀏覽器緩存機(jī)制
- 持續(xù)監(jiān)控性能指標(biāo)
七、總結(jié)
Vue 首屏白屏問題是一個復(fù)雜的性能優(yōu)化課題,需要從多個層面進(jìn)行優(yōu)化:
- 代碼層面:路由懶加載、組件按需加載
- 構(gòu)建層面:webpack 優(yōu)化、資源壓縮
- 架構(gòu)層面:SSR、骨架屏
- 網(wǎng)絡(luò)層面:CDN、緩存策略
選擇合適的解決方案需要根據(jù)具體項目的情況來決定,建議從最容易實現(xiàn)且收益最大的方案開始著手優(yōu)化。
到此這篇關(guān)于Vue首屏加載出現(xiàn)白屏問題的優(yōu)化實戰(zhàn)的文章就介紹到這了,更多相關(guān)Vue首屏優(yōu)化內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue2使用思維導(dǎo)圖jsmind的詳細(xì)代碼
jsMind是一個基于Js的思維導(dǎo)圖庫,jsMind是一個純JavaScript類庫,用于創(chuàng)建、展示和操作思維導(dǎo)圖,這篇文章主要給大家介紹了關(guān)于vue2使用思維導(dǎo)圖jsmind的詳細(xì)代碼,需要的朋友可以參考下2024-06-06
Vue3.0中Ref與Reactive的區(qū)別示例詳析
在vue3中對響應(yīng)式數(shù)據(jù)的聲明官方給出了ref()和reactive()這兩種方式,這篇文章主要給大家介紹了關(guān)于Vue3.0中Ref與Reactive區(qū)別的相關(guān)資料,需要的朋友可以參考下2021-07-07
Vue使用openlayers實現(xiàn)繪制圓形和多邊形
這篇文章主要為大家詳細(xì)介紹了Vue如何使用openlayers實現(xiàn)繪制圓形和多邊形,文中的示例代碼講解詳細(xì),感興趣的小伙伴快跟隨小編一起動手嘗試一下2022-06-06
el-table表頭根據(jù)內(nèi)容自適應(yīng)完美解決表頭錯位和固定列錯位
這篇文章主要介紹了el-table表頭根據(jù)內(nèi)容自適應(yīng)完美解決表頭錯位和固定列錯位,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01
Vuejs 組件——props數(shù)據(jù)傳遞的實例代碼
本篇文章主要介紹了Vuejs 組件——props數(shù)據(jù)傳遞的實例代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下。2017-03-03
淺談一下Vue生命周期中mounted和created的區(qū)別
每一個vue實例從創(chuàng)建到銷毀的過程,就是這個vue實例的生命周期,在這個過程中,他經(jīng)歷了從開始創(chuàng)建、初始化數(shù)據(jù)、編譯模板、掛載Dom、渲染→更新→渲染、卸載等一系列過程,那么這些過程中,具體vue做了些啥,我們今天來了解一下2023-05-05

