乐趣区

vue项目优化

1. 代码包优化

  • 屏蔽 sourceMap

    • 待下项目开发完成。进行打包源码上线环节,需要对项目开发环节的开发提示信息以及错误信息进行屏蔽,一方面可以减少上线代码包的大小;另一方面提高系统的安全性。在 vuejs 项目的 config 目录下有三个文件 dev.env.js(开发环境配置文件)、prod.env.js(上线配置文件)、index.js(通用配置文件)。vue-cli 脚手架在上线配置文件会自动设置允许 sourceMap 打包,所以在上线前可以屏蔽 sourceMap。如下所示,index.js 的配置如下, 通用配置文件分别对开发环境和上线环境做了打包配置分类,在 build 对象中的配置信息中,productionSourceMap 修改成 false:
'use strict'
// Template version: 1.3.1
// see http://vuejs-templates.github.io/webpack for documentation.

const path = require('path')

module.exports = {
  dev: {

    // Paths
    assetsSubDirectory: 'static',
    assetsPublicPath: '/',
    proxyTable: {},

    // Various Dev Server settings
    host: 'localhost', // can be overwritten by process.env.HOST
    port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
    autoOpenBrowser: false,
    errorOverlay: true,
    notifyOnErrors: true,
    poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-

    
    /**
     * Source Maps
     */

    // https://webpack.js.org/configuration/devtool/#development
    devtool: 'cheap-module-eval-source-map',

    // If you have problems debugging vue-files in devtools,
    // set this to false - it *may* help
    // https://vue-loader.vuejs.org/en/options.html#cachebusting
    cacheBusting: true,

    cssSourceMap: true
  },

  build: {
    // Template for index.html
    index: path.resolve(__dirname, '../dist/ndindex.html'),

    // Paths
    assetsRoot: path.resolve(__dirname, '../dist'),
    assetsSubDirectory: 'static',
    assetsPublicPath: './',

    /**
     * Source Maps
     */

    productionSourceMap: false,
    // https://webpack.js.org/configuration/devtool/#production
    devtool: '#source-map',

    // Gzip off by default as many popular static hosts such as
    // Surge or Netlify already gzip all static assets for you.
    // Before setting to `true`, make sure to:
    // npm install --save-dev compression-webpack-plugin
    productionGzip: true,
    productionGzipExtensions: ['js', 'css','svg'],

    // Run the build command with an extra argument to
    // View the bundle analyzer report after build finishes:
    // `npm run build --report`
    // Set to `true` or `false` to always turn it on or off
    bundleAnalyzerReport: process.env.npm_config_report
  }
}
  • 对项目代码中的 JS/CSS/SVG(*.ico) 文件进行 gzip 压缩

    • 在 vue-cli 脚手架的配置信息中,有对代码进行压缩的配置项,例如 index.js 的通用配置,productionGzip 设置为 true,但是首先需要对 compress-webpack-plugin 支持,所以需要通过 npm install –save-dev compression-webpack-plugin(如果 npm install 出错了,就使用 cnpm install 安装。可能网络比较差 npm install 会出现频率比较大),gzip 会对 js、css 文件进行压缩处理;对于图片进行压缩问题,对于 png,jpg,jpeg 没有压缩效果,对于 svg,ico 文件以及 bmp 文件压缩效果达到 50%,在 productionGzipExtensions: [‘js’, ‘css’,’svg’] 设置需要进行压缩的什么格式的文件。对项目文件进行压缩之后,需要浏览器客户端支持 gzip 以及后端支持 gzip。下面可以查看成功支持 gzip 状态:
'use strict'
// Template version: 1.3.1
// see http://vuejs-templates.github.io/webpack for documentation.
const path = require('path')
module.exports = {
  build: {
    // Template for index.html
    index: path.resolve(__dirname, '../dist/ndindex.html'),

    // Paths
    assetsRoot: path.resolve(__dirname, '../dist'),
    assetsSubDirectory: 'static',
    assetsPublicPath: './',

    /**
     * Source Maps
     */

    productionSourceMap: false,
    // https://webpack.js.org/configuration/devtool/#production
    devtool: '#source-map',

    // Gzip off by default as many popular static hosts such as
    // Surge or Netlify already gzip all static assets for you.
    // Before setting to `true`, make sure to:
    // npm install --save-dev compression-webpack-plugin
    productionGzip: true,
    productionGzipExtensions: ['js', 'css','svg'],

    // Run the build command with an extra argument to
    // View the bundle analyzer report after build finishes:
    // `npm run build --report`
    // Set to `true` or `false` to always turn it on or off
    bundleAnalyzerReport: process.env.npm_config_report
  }
}
  • ResponseHeader- content-encoding:”gzip”

  • 对路由组件进行懒加载

    • 在路由配置文件里,这里是 router.js 里面引用组件。如果使用同步的方式加载组件,在首屏加载时会对网络资源加载加载比较多,资源比较大,加载速度比较慢。所以设置路由懒加载,按需加载会加速首屏渲染。在没有对路由进行懒加载时,在 Chrome 里 devtool 查阅可以看到首屏网络资源加载情况(6requests 3.8MB transfferred Finish:4.67s DOMContentLoaded 2.61s Load 2.70s)。在对路由进行懒加载之后(7requests 800kb transffered Finish2.67s DOMContentLoaded 1.72s Load 800ms), 可以看见加载速度明显加快。但是进行懒加载之后,实现按需加载,那么项目打包不会把所有 js 打包进 app.[hash].js 里面,优点是可以减少 app.[hash].js 体积,缺点就是会把其它 js 分开打包,造成多个 js 文件,会有多次 https 请求。如果项目比较大,需要注意懒加载的效果。
    // 实现懒加载方式
      import Vue from "vue";
      import Router from "vue-router";
      Vue.use(Router);
      export default new Router({
      mode: "history",
      base: "/facex/district/",
      routes: [{ path: "/", redirect: "index"},
        {
        path: "/",
        name: "home",
        component: resolve=>require(["@/views/home"],resolve),
        children: [
          {
            // 员工查询
            path: "/employees",
            component: resolve=>require(["@/components/employees"],resolve)
          },
        {
          // 首页
          path: "/index",
          component: resolve=>require(["@/views/index"],resolve)
        },
        {
          // 访客查询
          path: "/visitorlist",
          component: resolve=>require(["@/components/visitorlist"],resolve)
        },
        {
          path: "/department",
          component: resolve=>require(["@/views/department"],resolve)
        },
        // 识别查询
        {
          path: "/discriminate",
          component: resolve=>require(["@/components/discriminate"],resolve)
        },
        {
          path: "/addDevice",
          component: resolve=>require(["@/views/addDevice"],resolve)
        },
        {
          path: "/districtNotice",
          component: resolve=>require(["@/components/districtNotice"],resolve)
        }
      ]
    },
    {
      path: "/noticeList",
      name: "noticeList",
      component: resolve=>require(["@/views/noticeList"],resolve)
      },
      {
        path: "/login",
        name: "login",
        component: resolve=>require(["@/views/login"],resolve)
      },
      {
        path: "/register",
        name: "register",
        component: resolve=>require(["@/views/register"],resolve)
      },
      {
        path: "/setaccount",
        name: "setaccount",
        component:resolve=>require(["@/views/setaccount"],resolve)
      },
      {
        path: "/addGroup",
        name: "addGroup",
        component:resolve=>require(["@/views/addGroup"],resolve)
      },
      {
        path: "/guide",
        name: "guide",
        component:resolve=>require(["@/components/guide"],resolve)
      },
      {
        path: "/addNotice",
        name: "addNotice",
        component: resolve=>require(["@/views/addNotice"],resolve)
        }
      ]
    });i

2. 源码优化

  • v-if 和 v-show 选择调用

    • v-show 和 v -if 的区别是:v-if 是懒加载,当状态为 true 时才会加载,并且为 false 时不会占用布局空间;v-show 是无论状态是 true 或者是 false,都会进行渲染,并对布局占据空间对于在项目中,需要频繁调用,不需要权限的显示隐藏,可以选择使用 v -show,可以减少系统的切换开销。
  • 为 item 设置唯一 key 值,

    • 在列表数据进行遍历渲染时,需要为每一项 item 设置唯一 key 值,方便 vuejs 内部机制精准找到该条列表数据。当 state 更新时,新的状态值和旧的状态值对比,较快地定位到 diff。
  • 细分 vuejs 组件

    • 在项目开发过程之中,第一版本把所有的组件的布局写在一个组件中,当数据变更时,由于组件代码比较庞大,vuejs 的数据驱动视图更新比较慢,造成渲染比较慢。造成比较差的体验效果。所以把组件细分,比如一个组件,可以把整个组件细分成轮播组件、列表组件、分页组件等。
  • 减少 watch 的数据

    • 当组件某个数据变更后需要对应的 state 进行变更,就需要对另外的组件进行 state 进行变更。可以使用 watch 监听相应的数据变更并绑定事件。当 watch 的数据比较小,性能消耗不明显。当数据变大,系统会出现卡顿,所以减少 watch 的数据。其它不同的组件的 state 双向绑定,可以采用事件中央总线或者 vuex 进行数据的变更操作。
  • 内容类系统的图片资源按需加载

    • 对于内容类系统的图片按需加载,如果出现图片加载比较多,可以先使用 v -lazy 之类的懒加载库或者绑定鼠标的 scroll 事件,滚动到可视区域先再对数据进行加载显示,减少系统加载的数据。
  • SSR(服务端渲染)

    • 如果项目比较大,首屏无论怎么做优化,都出现闪屏或者一阵黑屏的情况。可以考虑使用 SSR(服务端渲染),vuejs 官方文档提供 next.js 很好的服务端解决方案,但是局限性就是目前仅支持 Koa、express 等 Nodejs 的后台框架,需要 webpack 支持。目前自己了解的就是后端支持方面,vuejs 的后端渲染支持 php,其它的不太清楚。

3. 用户体验优化

  • better-click 防止 iphone 点击延迟

    • 在开发移动端 vuejs 项目时,手指触摸时会出现 300ms 的延迟效果,可以采用 better-click 对 ipone 系列的兼容体验优化。
  • 菊花 loading

    • 菊花 loading,在加载资源过程之中,可以提供 loading。此菊花 loading 不是那菊花。所以可以自由选择自己喜欢的菊花。
  • 骨架屏加载

    • 在首屏加载资源较多,可能会出现白屏和闪屏的情况。体验不好。使用骨架屏进行首屏在资源数据还没有加载完成时显示,给很好的体验效果。
退出移动版