vue.js

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript类库 > vue.js > Vue首屏优化

Vue首屏加载出现白屏问题的优化实战

作者:非鱼牛马社

在实际开发中,Vue 应用首次加载时经常出现白屏问题,这严重影响了用户体验,本文将从多个角度出发,提供全面的解决方案,大家可以根据需要进行选择

一、背景

在实际开发中,Vue 应用首次加载时经常出现白屏问题,这严重影响了用户体验。本文将从多个角度出发,提供全面的解决方案。

二、问题分析

2.1 白屏原因

三、解决方案

3.1 路由懒加载优化

// 修改前
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 骨架屏方案

手动实现

<!-- 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 资源预加载优化

基础配置

<!-- index.html -->
<head>
  <!-- DNS预解析 -->
  <link rel="dns-prefetch" href="//api.example.com">
  
  <!-- 预加载关键资源 -->
  <link rel="preload" href="/fonts/important.woff2" as="font" crossorigin>
  
  <!-- 预加载组件 -->
  <link rel="prefetch" href="/js/non-critical.js">
</head>

预渲染方案

对于静态内容较多的页面,推荐使用 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 构建优化

体积分析与优化

推荐使用 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()
    ]
  }
}

构建速度优化

使用 hard-source-webpack-plugin 提升构建速度:

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 实现:

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
      })
    ]
  }
}

构建分析

使用 speed-measure-webpack-plugin 分析构建过程:

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 开发调试优化

Vue DevTools

性能分析工具

Chrome Lighthouse

webpack-dashboard

npm install webpack-dashboard -D
// vue.config.js
const DashboardPlugin = require('webpack-dashboard/plugin')

module.exports = {
  configureWebpack: {
    plugins: [
      new DashboardPlugin()
    ]
  }
}

3.6 服务端渲染 (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 静态资源 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" href="https://cdn.jsdelivr.net/npm/element-ui@2.15.7/lib/theme-chalk/index.css">
  <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 浏览器缓存优化

# nginx.conf
location / {
    add_header Cache-Control "public, max-age=31536000";
    
    # 配置协商缓存
    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 性能优化插件

vue-skeleton-webpack-plugin

npm install vue-skeleton-webpack-plugin -D

用于自动生成骨架屏,支持多路由页面的骨架屏配置。

prerender-spa-plugin

npm install prerender-spa-plugin -D

预渲染插件,适用于静态内容较多的页面。

compression-webpack-plugin

npm install compression-webpack-plugin -D

用于 Gzip 压缩,大幅减小文件体积。

webpack-bundle-analyzer

npm install webpack-bundle-analyzer -D

分析打包体积,找出大文件并优化。

hard-source-webpack-plugin

npm install hard-source-webpack-plugin -D

为模块提供中间缓存,大幅提升二次构建速度。

speed-measure-webpack-plugin

npm install speed-measure-webpack-plugin -D

分析 webpack 打包速度,找出耗时步骤。

4.2 开发调试工具

vue-devtools

Lighthouse

webpack-dashboard

npm install webpack-dashboard -D

优化 webpack 开发输出界面,提供更直观的信息。

五、性能检测与监控

5.1 性能指标

5.2 检测工具

// 性能监控示例
window.performance.mark('vue-init-start')

// Vue 初始化完成后
window.performance.mark('vue-init-end')
window.performance.measure(
  'vue-init',
  'vue-init-start',
  'vue-init-end'
)

六、最佳实践建议

七、总结

Vue 首屏白屏问题是一个复杂的性能优化课题,需要从多个层面进行优化:

选择合适的解决方案需要根据具体项目的情况来决定,建议从最容易实现且收益最大的方案开始着手优化。

到此这篇关于Vue首屏加载出现白屏问题的优化实战的文章就介绍到这了,更多相关Vue首屏优化内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文