• vuejs项目性能优化总结


    vuejs项目性能优化总结

    Evtion关注

    32018.07.20 15:19:00字数 2,136阅读 27,268

    在使用elementUI构建公司管理系统时,发现首屏加载时间长,加载的网络资源比较多,对系统的体验性会差一点,而且用webpack打包的vuejs的vendor包会比较大。所以通过搜集网上所有对于vuejs项目的性能优化,做了有关3方面的优化建议,主要包括:上线代码包打包、源码编写优化、用户体验优化。(下面的优化建议只在vue-cli脚手架下做过测试,详情请参考)

    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不是那菊花。所以可以自由选择自己喜欢的菊花。
      • 太帅

    • 骨架屏加载
      • 在首屏加载资源较多,可能会出现白屏和闪屏的情况。体验不好。盗图一波,小米商城使用骨架屏进行首屏在资源数据还没有加载完成时显示,给很好的体验效果。

         

        2018052209545810.gif

    引用参考:
    Vue页面骨架屏的实现方法
    浅谈 Vue 项目优化
    Vue 初始化性能优化
    Vue 性能优化经验总结
    路由懒加载
    VUE2组件懒加载浅析
    基于VUE的SPA单页应用开发-加载性能篇

  • 相关阅读:
    HOWTO re
    数据类型
    字符串
    最大公约数
    this
    tip 2:找最小公倍数之Boost
    tip 1:一个简单的将int型转换成char的方法
    Item47
    成员函数模板
    item44:将与参数无关的代码抽离template
  • 原文地址:https://www.cnblogs.com/grj001/p/12223234.html
Copyright © 2020-2023  润新知