zoukankan      html  css  js  c++  java
  • vue项目性能优化总结

    在使用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系列的兼容体验优化。



     原文链接:https://www.jianshu.com/p/41075f1f5297




  • 相关阅读:
    POJ 1681 Painter's Problem(高斯消元法)
    HDU 3530 Subsequence(单调队列)
    HDU 4302 Holedox Eating(优先队列或者线段树)
    POJ 2947 Widget Factory(高斯消元法,解模线性方程组)
    HDU 3635 Dragon Balls(并查集)
    HDU 4301 Divide Chocolate(找规律,DP)
    POJ 1753 Flip Game(高斯消元)
    POJ 3185 The Water Bowls(高斯消元)
    克琳:http://liyu.eu5.org
    WinDbg使用
  • 原文地址:https://www.cnblogs.com/xieli26/p/9989389.html
Copyright © 2011-2022 走看看