精华内容
下载资源
问答
  • Vue 项目性能优化

    2019-09-12 11:26:48
    没有完美的技术,我们能做的就是尽可能的去完善它,因此我整理了目前遇到的可优化的以及观摩别人的文档做的笔记,在此整合,不足之处,多多指教! 代码包的优化 1、屏蔽 sourceMap 项目开发完成,进行...

    最近一直在转发更新,许久没有整理自己的总结了,今天忙里偷闲,整理一下目前出于主流的 VUE !

    Vue 框架通过双向数据绑定和虚拟 DOM 技术,进行数据渲染,DOM 操作等;没有完美的技术,我们能做的就是尽可能的去完善它,因此我整理了目前遇到的可优化的以及观摩别人的文档做的笔记,在此整合,不足之处,多多指教!

     

    代码包的优化

    1、屏蔽 sourceMap

         项目开发完成,进行打包准备上线时,需要对项目开发中的各种提示信息进行屏蔽,一是可以减少代码包的大小,二是为了保证安全性,使用 vue-cli 脚手架会默认是允许 sourceMap 打包,所以需在配置文件中将 productionSourceMap 改为 false

    2、对项目中的 JS/CSS/IMG 文件进行 gzip 压缩

         在vue-cli脚手架的配置信息中,有对代码进行压缩的配置项,productionGzip设置为true

    3、对路由组件进行懒加载

          在路由配置文件里,如果使用同步的方式加载组件,在首屏加载时会对网络资源加载加载比较多,资源比较大,加载速度比较慢。所以设置路由懒加载,按需加载会加速首屏渲染。但是进行懒加载之后,实现按需加载,那么项目打包不会把所有js打包进app.[hash].js里面,优点是可以减少app.[hash].js体积,缺点就是会把其它js分开打包,造成多个js文件,会有多次https请求。如果项目比较大,需要注意懒加载的效果。

     

     

    关于代码的那些事

    1、v-if  与 v-show

          v-show 会预渲染DOM,所以除需要预先渲染或者频繁切换显示效果,都尽量使用 v-if

          v-if 是真正的条件渲染,它可以保证在事件切换中当前条件内的事件监听器和子组件适当的被销毁和重建;

          v-if 如果在初始化时候为false,那它则不会执行当前代码,直至条件为true,所以渲染(初始化)较快

    2、v-for

          v-for 使用时一定记得写 key ,此时已使用 v-for 避免使用 v-if

    3、细分 vuejs 组件

          在项目开发过程中,一般是把所有的功能写在一个组件中,当数据变更时,由于组件代码较大,数据渲染视图变慢。所以需把组件细分,比如一个组件可细分成轮播组件、列表组件、分页组件等等。

    4、computed 和 watch 

          computed 是计算属性,同时存在缓存,所以只有他依赖的属性值发生变化,下一次获取 computed 的值后才会重新计算。所以在需要做数据计算同时也要依赖其他数据时,可使用 computed(利用其缓存属性,避免多次重新计算)

          watch 做观察用,类似监听回调,每当监听的数据出现变化都会执行回调及其后的函数操作。当组件某个数据变更后需要对应的 state 进行变更、需要异步处理数据或者开销较大时,会使用 watch 监听相应的数据变更并绑定事件。当 watch 的数据较小时,性能消耗不明显,但当数据较大,系统会出现卡顿现象。所以如需要可采用事件中央总线或者 vuex 进行数据的操作变更

    5、图片的按需加载、长列表的性能优化

          尽量对图片进行按需加载,如果图片过多,可以使用 v-lazy 之类的懒加载库或者 scroll 事件等

          如图片需要裁减,一般使用二倍图即可

          Vue 会通过 Obj.defineProperty 对数据进行劫持,便于实现数据渲染视图。但在仅需要数据展示而不操作时,是不需要 Vue 的数据劫持的(数据量较大,利于减少初始化时间),此时推荐使用 Obj.freeze 来冻结一个对象,被冻结的对象是不能修改的

          如果项目中存在非常长或者无限滚动的列表,可使用 窗口化 来优化项目性能,可参考开源项目,如: vue-virtual-scroll-list、vue-virtual-scroller

    6、资源提前请求

          vue 项目中各个文件的加载顺序为 router.js   main.js   App.vue   [-page-].vue   [compontent].vue 

          如果 [-page-].vue 的文件较多,可以在页面挂载、渲染的同时去请求数据接口

    7、异步路由、路由懒加载

          建议主页面直接 import ,其他非主页面使用异步路由

          使用异步路由可以根据 URL 自动加载所需页面的资源,并不会造成页面阻塞,更适用于移动端

          因为 Vue 为单页面应用,所以会大量使用 import 引入路由,这样在 webpack 打包后文件会很大,比如首页很可能出现白屏情况,此时就需要根据不同路由对应的组件分割成不同的代码块,然后当路由被访问时才加载对应的组件,会提高效率(此方式虽然可能减少首页白屏的时间,但可能会是个别页面的访问效率降低),建议考虑实际情况

          例如:

                      const Foo = () => import('./Foo.vue')

          const router = new VueRouter({

               routes: [

                  { path: '/foo', component: Foo }

               ]

          })

    8、异步组件

          不需要首屏加载的组件建议都使用异步组件的方式加载,包括要触发条件的动作也使用异步组件,如弹框等

          使用 v-if 来控制显示时机,再引入组件的 Promise 即可

    9、SSR--服务端渲染

          如果项目较大,首屏无论如何优化都会出现黑屏或者闪屏的话,建议考虑使用 SSR 

    10、事件的销毁

            Vue组件销毁时,会自动清理它与其它实例的连接,解绑它的全部指令及事件监听器,但是仅限于组件本身的事件。
    也就是说,在js内使用addEventListener等方式是不会自动销毁的,我们需要在组件销毁时手动移除这些事件的监听,以免造成内存泄露

    11、第三方插件的按需引入

           开发中我们经常需要引入第三方插件,一般我们不会需要整个插件的全部功能,如果直接引入整个插件会导致项目的体积过大,所以可使用 babel-plugin-component ,只引入需要的组件,减少整个项目的体积

           例如:以 element-ui 为例

                      1)安装 babel-plugin-component :npm install babel-plugin-component -D

                      2)修改  .babelrc 

            { "presets": [["es2015", { "modules": false }]], "plugins": [ [ "component", { "libraryName": "element-ui", "styleLibraryName": "theme-chalk" } ] ]}

                      3)在 main.js 中引入部分组件:

                            import Vue from 'vue'

                            import {Buttom,Select} from 'element-ui'

                            Vue.use(Button)

                            Vue.use(Select)

    12、服务端渲染 SSR 、预渲染

     

           服务端渲染是指 Vue 在客户端将标签渲染成的整个 HTML 片段的工作在服务端完成,服务端形成的 html 片段直接返回给客户端的过程叫做服务端渲染                

     

    未完待续。。。

     

     

     

     

     

    展开全文
  • Vue 项目打包优化

    2021-06-24 11:05:35
    参考以下文章: 图片优化总括:介绍常用的几种方式 图片优化一:图片压缩和使用iconfont 图片优化二:预加载和懒加载的使用 使用懒加载会遇到的问题 图片优化三:用image-webpack-loader插件压缩图片 ...
    展开全文
  • vue项目性能优化总结

    千次阅读 2018-07-05 20:01:41
    vue作为目前主流的前端框架,在github上拥有147kstar,作为vue开发大军的一员这篇文章分享一下自己使用过程中的主要针对vue项目的一些优化经验,欢迎大家一起交流(持续更新中......) 一.代码优化 1.v-if和v-show...

    vue作为目前主流的前端框架,在github上拥有147kstar,作为vue开发大军的一员这篇文章分享一下自己使用过程中的主要针对vue项目的一些优化经验,欢迎大家一起交流(持续更新中......)

     

    一.代码优化

    1.v-if和v-show使用场景

    v-if 是条件渲染,条件为false时,不会在dom上渲染元素,条件判断的是否渲染该元素

    v-show 是显示与否,只是css层面上通过条件判断display的属性值

    所以,v-if适用于运行时很少改变条件的情况,v-show适用于需要频繁切换条件的场景

    2.v-for遍历添加key,并避免和v-if同时使用

    使用v-for更新已渲染的元素列表时,默认用就地复用策略;列表数据修改的时候,他会根据key值去判断某个值是否修改,如果修改,则重新渲染这一项,否则复用之前的元素;给每一项item添加唯一的key可以更快定位diff,更高效的更新虚拟dom

    v-for优先级高于v-if,同时使用意味着每一次遍历都要进行判断,影响速度

    1.如果是根据遍历数据控制是否遍历当前元素,可以在computed中对v-for的数据进行过滤

    2.如果是控制整个遍历数据的判断,可以把v-if写在v-for外层

    3.合理使用computed 和 watch

    一个值受多个值影响用computed,一个值影响多个值用watch

    可以参考这篇文章https://blog.csdn.net/qq_24510455/article/details/81057261

    4.异步组件(按需加载)

    有时候需要根据某一个状态来判断到底使用哪个组件,这时候并不需要加载所有可能的组件,所以就要对组件进行按需加载

     components: {
        BindBank: () => import('./modules/bind-bank.vue'),
        BindAilpay: () => import('./modules/bind-alipay.vue'),
        Bindwechat: () => import('./modules/bind-wechat.vue'),
      },
      computed: {
        componentAndNotice(){
          let active = 0 // 0 1 2
          let components = [BindBank,BindAilpay,Bindwechat]
          return {
            component: components[active],
          }
        }
      }

    5.长列表优化

    在vue中,会对数据进行劫持,但是对于很多大量数据列表很多时候只是纯粹的数据显示,不需要做视图响应,为了减少组件初始化的时间,可以通过 Object.freeze 方法来冻结一个对象,一旦被冻结的对象就再也不能被修改了

    6.状态管理

    对于每个项目来说,状态管理是少不了的,对于vue项目来说,有很多种方式可以进行状态管理

    1.父子组件之间---props和this.$emit()

    2.vuex--适用于中大型SPA项目,所以千万不要一提到vue的状态管理就说vuex,也需要严格控制vuex中的数据,需要分析什么样的项目和数据需要使用vuex

    3.Vue.observable( object )--2.6.0新增API

    通过使用这个api我们可以应对一些简单的跨组件数据状态共享的情况。

    store.js

    import Vue from "vue";
    
    export const store = Vue.observable({ count: 0 });
    
    export const mutations = {
      setCount(count) {
        store.count = count;
      }
    };
    
    

    在组件中引用

    <template>
      <div id="app">
        <img width="25%" src="./assets/logo.png">
        <p>count:{{count}}</p>
        <button @click="setCount(count+1)">+1</button>
        <button @click="setCount(count-1)">-1</button>
      </div>
    </template>
    
    <script>
    import { store, mutations } from "./store";
    export default {
      name: "App",
      computed: {
        count() {
          return store.count;
        }
      },
      methods: {
        setCount: mutations.setCount
      }
    };
    </script>
    
    <style>
    

    4.父孙组件之间-provide / inject--2.2.0新增API

    这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效。如果你熟悉 React,这与 React 的上下文特性很相似。只要在上一层级的声明的provide,那么下一层级无论多深都能够通过inject来访问到provide的数据,可以理解为加强版的props

    这么做也是有明显的缺点的,在任意层级都能访问导致数据追踪比较困难,不知道是哪一个层级声明了这个或者不知道哪一层级或若干个层级使用了

    <template>
    	<div class="test">
    		<son prop="data"></son>
    	</div>
    </template>
     
    <script>
    export default {
    	name: 'Test',
    	provide: {
    		name: 'Garrett'
    	}
    }
    <template>
    	<div>
    		{{name}}
    	</div>
    </template>
     
    <script>
    export default {
    	name: 'Grandson',
    	inject: [name]
    }
    </script>

    5.发布订阅模式

    属于行为型模式的一种,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态变化时,会通知所有的观察者对象,使他们能够自动更新自己。 vue的双向绑定原理就是数据劫持+发布订阅模式实现的

    7.巧用作用域插槽

    vue中插槽 分为 默认插槽、具名插槽、作用域插槽,对于前两种较为常用的就不多介绍,这里主要说一下作用域插槽

    2.6.0以后作用域插槽和具名插槽统一使用v-slot,原有slot和slot-scope依然可以使用

    作用域插槽:父组件能接收来自子组件的slot传递过来的参数,大概的使用场景,接口返回了一组列表数据,但是在不同页面可能需要不同的样式,如果写多套组件当然也没问题,但是一旦数据发生变化就意味着要维护大量的组件,这时候就可以考虑使用作用域插槽,简单来说就是子组件负责提供数据,父组件负责显示样式

    //子组件
    <template>
      <div>
        <ul>
          <slot :data='item' v-for="(item,index) in list" :key="index"></slot>
        </ul>
      </div>
    </template>
     
    <script>
    export default {
      data () {
        return {
          list:['Webkit','Gecko','Trident','Blink']
        }
      }
    }
    </script>
    // 父组件
    <template>
      <div>
        <!--标准写法v-slot:default="a"->
        <!--单个插槽可直接绑定在元素上 不需要<template v-slot="a"></template>-->
        <child v-slot="a">
          <li v-text="a.data"></li>
        </child>
      </div>
    </template>
    
    <script>
      import child from './child';
      export default {
        name: 'app',
        components: {
          child
        }
      }
    </script>

    另外注意,如果使用v-slot,出现多个插槽必须使用完整的基于<template>的语法,

    具名插槽写法由<div slot="header">可变为<div v-slot:"header"> 也可缩写为<div #header>

    具体可参考https://cn.vuejs.org/v2/guide/components-slots.html

    8.适当选择混入mixin

    使用场景:比如同级的两个模块需要根据某个状态判断到底进入哪个,两个模块具有大部分相同的业务逻辑,可能都需要在某几个生命周期或者data中进行相同的操作,那这时候选择mixin会是一种好的方式

    同名钩子函数将会混合为一个数组,都将被调用到,但是混入对象的钩子将在组件自身钩子之前调用。

    mixin的数据对象和组件的数据发生冲突时以组件数据优先。

    使用mixin会导致数据难以追踪,代码可读性也会较差,所以谨慎使用

    9.不要给每个vue组件的style标签添加scoped

    新建vue组件的时候会给style标签默认添加scoped属性,当编译之后会给dom节点加了一个不重复的data属性来表示唯一性,在css选择器末尾添加了data选择器来实现私有化(深度作用选择器),保证组件样式不相互污染。但是会导致组件样式权重加重,外部修改组件内部样式需要更高的权重,层级过深会极大增加复杂度,对于一个多人长期开发的项目来说,修改样式将会成为一个令人头疼的问题

    建议对样式使用场景单一,很少来自外部的样式修改的组件使用scoped,其他组件建议使用和组件name属性相同的class对组件最外层包裹,内部样式以嵌套方式书写

    10.及时销毁事件

    Vue 组件销毁时,会自动清理它与其它实例的连接,解绑它的全部指令及事件监听器,但是仅限于组件本身的事件。如果在 js 内使用 addEventListene 等方式是不会自动销毁的,我们需要在组件销毁时手动移除这些事件的监听,以免造成内存泄露。为了准确移除监听,尽量不要使用匿名函数或者已有的函数的绑定来直接作为事件监听函数。

    created() {
      addEventListener('click', this.click, false)
    },
    beforeDestroy() {
      removeEventListener('click', this.click, false)
    }

    ​​

    二.webpack优化

    1.图片压缩

    使用image-webpack-loader压缩图片,并设置 limit 大小来对图片处理,对小于 limit 的图片转化为 base64 格式,其余的不做操作。

    2.优化Loader配置

    loader对文件的转换操作是很耗时的,所以尽量让更少的文件参与loader处理。

    1.优化正则匹配,如果项目源码中只有js文件,就不要写成/\.jsx?$/,以提升正则表达式的性能 test: /\.js$/

    2.通过cacheDirectory选项开启缓存,默认值是false。如果设置了这个参数,被转换的结果将会被缓存起来。当webpack再次编译时,将会首先尝试从缓存中读取转换结果,以此避免资源浪费。

    3.通过include、exclude来减少被处理的文件

    module.exports = {
      module:{
        rules:[
          {
            //如果项目源码中只有js文件,就不要写成/\.jsx?$/,以提升正则表达式的性能
            test:/\.js$/,
            //babel-loader支持缓存转换出的结果,webpack再次编译时,将会首先尝试从缓存中读取转换结果,以此避免资源浪费
            loader:'babel-loader?cacheDirectory=ture',
            //只在src文件夹下查找
            include:[resolve('src')],
            //不会去查找的路径
            exclude:/node_modules/
          }
        ]
      }
    }

    3.优化resolve.alias配置

    在导入语句没带文件后缀时,Webpack 会在自动带上后缀后去尝试询问文件是否存在。默认是:extensions :[‘. js ‘,’. json ’] 。也就是说,当遇到require ( '. /data ’)这样的导入语句时,Webpack会先去寻找./data .js 文件,如果该文件不存在,就去寻找./data.json 文件,如果还是找不到就报错。如果这个列表越长,或者正确的后缀越往后,就会造成尝试的次数越多,所以 resolve .extensions 的配置也会影响到构建的性能。 

    4.使用uglifyjs-webpack-plugin压缩代码文件

    使用uglifyjs-webpack-plugin压缩代码文件,删除console语句、注释等

    5.使用purgecss-webpack-plugin删除多余的css

    对于一些大型老旧多人维护的项目,会发现很多css其实都已经是没有再使用,但是由于分布在很多文件中导致手动删除几乎很难完成,PurgeCSS 是一个能够通过字符串对比,来决定移除不需要的 CSS 的工具,同时也可以对不需要移出的添加白名单

    具体可参考https://www.purgecss.com/with-webpack

    6.优化SourceMap

    我们在项目进行打包后,会将开发中的多个文件代码打包到一个文件中,并且经过压缩,去掉多余的空格,且babel编译化后,最终会用于线上环境,那么这样处理后的代码和源代码会有很大的差别,当有bug的时候,我们只能定位到压缩处理后的代码位置,无法定位到开发环境中的代码,对于开发不好调式,因此sourceMap出现了,它就是为了解决不好调式代码问题的。

    webpack 在构建中提供了不少于7种的sourcemap模式,其中eval模式虽然可以提高构建效率,但是构建后的脚本较大,因此生产上并不适用。而source-map 模式可以通过生成的 .map 文件来追踪脚本文件的 具体位置,进而缩小脚本文件的体积,这是生产模式的首选,并且在生产中,我们需要隐藏具体的脚本信息,因此可以使用 cheap 和module 模式来达到目的。

    7.开启Gzip压缩

    gzip 是 GNUzip 的缩写,最早用于 UNIX 系统的文件压缩。HTTP 协议上的 gzip 编码是一种用来改进 web 应用程序性能的技术,web 服务器和客户端(浏览器)必须共同支持 gzip。目前主流的浏览器,Chrome,firefox,IE等都支持该协议。常见的服务器如 Apache,Nginx,IIS 同样支持,gzip 压缩效率非常高,通常可以达到 70% 的压缩率,也就是说,如果你的网页有 30K,压缩之后就变成了 9K 左右

    以下为部分示例代码是基于cli3(node>=8 webpack=4)

    千万不要忘记npm i ** -save-dev

    const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
    const BASE_URL = process.env.NODE_ENV === 'production' ? './' : './'
    const path = require('path')
    const CompressionPlugin = require("compression-webpack-plugin")
    const isPro = process.env.NODE_ENV === 'production'
    
    const resolve = dir => {
      return path.join(__dirname, dir)
    }
    
    module.exports = {
      publicPath: BASE_URL,
      outputDir: 'dist', // 打包输出目录
      assetsDir: 'assets', // 静态资源目录
      indexPath: 'index.html',
      filenameHashing: true,
      lintOnSave: true,
      // productionSourceMap: true, // 生产环境是否生成 sourceMap 文件 在cli3中好像并没有效果
    
      chainWebpack: config => {
        if (isPro) {
          config.mode = 'production'
          config.devtool = 'source-map' // sourceMap
          return {
            plugins: [new CompressionPlugin({
              test: /\js$|\.htm1$|\.css/, // 匹配文件名
              threshold: 10240, // 对超过10K的数据进行压缩
              deleteriginalAssets: false // 是否删除原文件
            })]
          }
        }
        // 图片压缩插件
        config.module
          .rule('images')
          .use('image-webpack-loader')
          .loader('image-webpack-loader')
          .options({
            bypassOnDebug: true
          })
          .end()
        config.module
          .rule('images')
          .use('url-loader')
          .loader('url-loader')
          .options({
            limit: 1024 * 500 // 图片文件高于500K不转base64
          })
        // key,value自行定义,比如.set('@@', resolve('src/components'))
        config.resolve.alias
          .set('@', resolve('src')) // @在cli3中已内置,也可重定义
          .set('_c', resolve('src/components'))
      },
    
      configureWebpack: {
        optimization: {
          minimizer: [
            new UglifyJsPlugin({
              uglifyOptions: {
                beautify: false, // 最紧凑的输出
                comments: false, // 删除所有的注释
                compress: {
                  drop_console: true, // console
                  drop_debugger: false,
                  pure_funcs: ['console.log'] // 移除console
                }
              }
            })
          ]
        }
      }
    }
    

     

    三.web优化

    1.使用CDN

    使用cdn可以使下载文件的并发连接数大大增加,且CDN 具有更好的可用性,更低的网络延迟和丢包率 。

    对于项目中使用的一些静态资源可以选择使用cdn来加载,比如jq、axios等工具库、element等大体积的ui库

    推荐两个静态资源库

    https://cdn.baomitu.com/

    https://www.bootcdn.cn/

    展开全文
  • vue项目性能优化方案

    千次阅读 2020-10-17 15:44:43
    项目采用vue cli3搭建,集成前端组件以及地图效果,导致项目打包后资源包文件特别大,打包速度慢,首屏渲染耗时长,甚至出现左右界面图表数据不渲染的问题。 优化前准备: 首先我们需要先排查影响性能、导致打包资源...

    背景
    项目采用vue cli3搭建,集成前端组件以及地图效果,导致项目打包后资源包文件特别大,打包速度慢,首屏渲染耗时长,甚至出现左右界面图表数据不渲染的问题。

    优化前准备
    首先我们需要先排查影响性能、导致打包资源文件过大的原因,以及代码的使用率

    • webpack-bundle-analyzer:
    npm install webpack-bundle-analyzer
    
    // vue.config.js文件(vue cli3根目录下的文件,如果没有,可创建此文件,用于webpack配置)
    
    module.exports = {
        chainWebpack: config => {
            /* 添加分析工具 */
            if (process.env.NODE_ENV === 'production') {
                if (process.env.npm_config_report) {
                    config
                        .plugin('webpack-bundle-analyzer')
                        // eslint-disable-next-line global-require
                        .use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin)
                        .end();
                    config.plugins.delete('prefetch');
                }
            }
        },
    };
    

    通过命令 npm run build --report 会在打包完成后本地启动一个服务,自动打开127.0.0.1:8888网页,可以查看打包后各个依赖包占用的资源大小,我们可以针对各个依赖包的相关大小作出体积的优化,如果开源库过大可以考虑按需引入,不要全部引入,如果是自己公司封装的私有组件库、类库,可以排查哪部分占用文件过大,打包进行优化处理,如下图:
    在这里插入图片描述
    在这里插入图片描述

    • coverage:
      通过打开控制台(F12),ctrl+shift+p,搜索coverage,然后选中,然后点击开始录制,之后做一些操作,比如刷新界面,开始录制,查看我们代码的实际使用率,也可以点击文件查看这个文件中具体未使用的那段代码(红色部分)
      在这里插入图片描述
      在这里插入图片描述
      优化方案:
    • gzip压缩:gzip压缩可以特别明显的提高我们的代码加载效果,提升效率5-6倍左右,它会把诸如js、css等文件进行压缩,并且让我们在加载时去请求那些gz文件而提升请求效率,这部分可以参考博主的另一篇文章 gzip压缩方案
    • 路由懒加载:实际来说,我们在首页就不需要加载其他路由的文件以及数据,而当我们执行到某个具体路由,再去加载当前路由的才是最正确的方案,所以路由懒加载是我们必须要做的,使用方法如下:

    这里拿home路由举例,博主每个页面都是分为左、右、中上、中下四个模块的,所以每个路由中都有四个组件,当然,路由懒加载写法是一样的,通过箭头函数返回一个组件,webpackChunkName就是最早的打包后的文件名,同一路由可以写同一个名字,推荐写路由名,方便我们知道是哪个路由下的。

    const MainLeft = () => import(/* webpackChunkName: "Home" */ '../components/Home/MainLeft.vue');
    const MainRight = () => import(/* webpackChunkName: "Home" */ '../components/Home/MainRight.vue');
    const MainCenterTop = () => import(/* webpackChunkName: "Home" */ '../components/Home/MainCenterTop.vue');
    const MainCenterBottom = () => import(/* webpackChunkName: "Home" */ '../components/Home/MainCenterBottom.vue');
    

    而在router.js里就是正常写法:

    routes: [
            {
                path: '/',
                name: 'Home',
                title: '首页',
                components: {
                    routerLeft: Home.MainLeft,
                    routerRight: Home.MainRight,
                    routerCenterTop: Home.MainCenterTop,
                    // routerCenterBottom: Home.MainCenterBottom,
                },
            },
    ]
    

    开启路由懒加载后,vue cli3项目还需要在vue.config.js文件中配置如下

    // vue.config.js文件(vue cli3根目录下的文件,如果没有,可创建此文件,用于webpack配置)
    module.exports = {
        chainWebpack: config => {
        	// 移除 prefetch 插件(避免会预先加载模块/路由)
            config.plugins.delete('prefetch');
        },
    };
    

    (注:之前博主遇到个小坑,项目中有个文件夹,里面写了一些全局封装并且全局注册的组件供其他页面使用,而有些组件中使用了require去动态加载图片导致打包后路由懒加载不生效没有生成对应路由的文件,大家留意一下即可,如果遇到此问题,可以找博主提供解决思路)

    • 组件库按需引入:这一点不需要过多赘述了,使用了诸如element ui等组件库的话,官网都有很详细的介绍如何按需加载
    • 图片压缩:安装此插件的时候有可能出现部分依赖安装失败,导致压缩失败,可以先卸载此插件然后用cnpm或淘宝源重新安装
    npm install image-webpack-loader
    
    // vue.config.js文件(vue cli3根目录下的文件,如果没有,可创建此文件,用于webpack配置)
    module.exports = {
        chainWebpack: config => {
            // 开启图片压缩
            // config.module
            //     .rule('images')
            //     .test(/\.(png|jpe?g|gif|svg)(\?.*)?$/)
            //     .use('image-webpack-loader')
            //     .loader('image-webpack-loader')
            //     .options({ bypassOnDebug: true });
        },
    };
    
    • map映射文件:vue打包会保留源文件的map映射,方便我们打包部署后依然可以通过控制台的source查看搜索源文件的代码,方便定位问题,但是多生成map文件会导致打包文件过大,所以仁者见仁智者见智,看各位是否需要打包部署后方便定位问题吧,不需要的话可以考虑不生成map文件
    module.exports = {
        productionSourceMap: true,
    }
    
    • 分包加载:vue打包后会把依赖包都打包到app.js文件里,这样会导致单文件过大,请求耗时,加载缓慢,所以可以考虑把各依赖单独拆分打包,实现多个小文件请求加载的方式,代码如下:
    // vue.config.js文件(vue cli3根目录下的文件,如果没有,可创建此文件,用于webpack配置)
    module.exports = {
        configureWebpack: {
            optimization: {
                runtimeChunk: 'single',
                splitChunks: {
                    chunks: 'all',
                    maxInitialRequests: Infinity,
                    minSize: 20000,
                    cacheGroups: {
                        vendor: {
                            test: /[\\/]node_modules[\\/]/,
                            name(module) {
                                // get the name. E.g. node_modules/packageName/not/this/part.js
                                // or node_modules/packageName
                                const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1];
                                // npm package names are URL-safe, but some servers don't like @ symbols
                                return `npm.${packageName.replace('@', '')}`;
                            },
                        },
                    },
                },
            },
        },
    };
    

    上述代码会把所有的包括异步请求的模块分割,针对大于20000k的文件,最终命名方式是npm.依赖包.js文件,比如npm.echarts.js,命名可以自定义。

    • 重复引用依赖包:封装了一个公共组件库(可通过npm下载),但是临时为了省事项目中也封装了一些组件单独放在一个文件夹中,最终一些相同的依赖就会被重复引用,比如组件库中用了amcharts图表,而项目中又安装使用了这个图表库,会导致此依赖被重复引用,解决方案:把项目中的组件挪到组件库中,这样同一份依赖就只会被使用一次。(不过我记得webpack有配置可以针对同一依赖多次引用的处理,把依赖进行缓存,避免被多次引用,感兴趣的童鞋可以去查阅下相关资料)
    • fps:之前项目中封装了一个方法,针对数据请求多的情况,做了fps处理,如果fps小于30就先不执行数据请求,先等现有数据、界面、地图等渲染完毕,fps稳定后再去执行下一部分数据请求、界面渲染,本身是为了能更好更流畅的渲染,但是如果电脑性能本身就很差,fps本身就很低,会导致一直数据不渲染(哈哈哈,给自己埋了个坑),最终定位问题后发现了这段不合理的处理。大家写代码也要多注意这些情况。

    完整的vue.config.js配置:

    const fs = require('fs');
    const CompressionPlugin = require('compression-webpack-plugin');
    
    let devServer = {};
    if (fs.existsSync('./dev-config.js')) {
        // eslint-disable-next-line global-require
        devServer = require('./dev-config');
    } else {
        console.error('!!!please create the dev-config.js file from dev-config-template.js');
    }
    
    module.exports = {
        lintOnSave: true,
        productionSourceMap: true,
        chainWebpack: config => {
            // 移除 prefetch 插件(避免会预先加载模块/路由)
            config.plugins.delete('prefetch');
            // Loader
            config.module
                .rule('svg')
                .test(/\.(swf|ttf|eot|svg|woff(2))(\?[a-z0-9]+)?$/)
                .use('file-loader')
                .loader('file-loader')
                .end();
            // 开启图片压缩
            // config.module
            //     .rule('images')
            //     .test(/\.(png|jpe?g|gif|svg)(\?.*)?$/)
            //     .use('image-webpack-loader')
            //     .loader('image-webpack-loader')
            //     .options({ bypassOnDebug: true });
            /* 添加分析工具 */
            if (process.env.NODE_ENV === 'production') {
                if (process.env.npm_config_report) {
                    config
                        .plugin('webpack-bundle-analyzer')
                        // eslint-disable-next-line global-require
                        .use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin)
                        .end();
                    config.plugins.delete('prefetch');
                }
            }
        },
        devServer,
        configureWebpack: {
            resolve: {
                alias: {
                    src: '@',
                    components: '@/components',
                    views: '@/views',
                },
            },
            plugins: [
                new CompressionPlugin({
                    algorithm: 'gzip', // 使用gzip压缩
                    test: /\.js$|\.html$|\.css$/, // 匹配文件名
                    filename: '[path].gz[query]', // 压缩后的文件名(保持原文件名,后缀加.gz)
                    minRatio: 1, // 压缩率小于1才会压缩
                    threshold: 10240, // 对超过10k的数据压缩
                    deleteOriginalAssets: false, // 是否删除未压缩的源文件,谨慎设置,如果希望提供非gzip的资源,可不设置或者设置为false(比如删除打包后的gz后还可以加载到原始资源文件)
                }),
            ],
            optimization: {
                runtimeChunk: 'single',
                splitChunks: {
                    chunks: 'all',
                    maxInitialRequests: Infinity,
                    minSize: 20000,
                    cacheGroups: {
                        vendor: {
                            test: /[\\/]node_modules[\\/]/,
                            name(module) {
                                // get the name. E.g. node_modules/packageName/not/this/part.js
                                // or node_modules/packageName
                                const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1];
                                // npm package names are URL-safe, but some servers don't like @ symbols
                                return `npm.${packageName.replace('@', '')}`;
                            },
                        },
                    },
                },
            },
        },
    };
    

    好了,以上就是博主自身项目中关于性能优化的一些处理,大家可以参考下。
    如有问题,请指出,接收批评。
    在这里插入图片描述

    个人微信公众号:
    在这里插入图片描述

    展开全文
  • vue cli 3.0中, 在vue.config.js中配置 configureWebpack:{ optimization: { minimizer: [ new UglifyJsPlugin({ uglifyOptions: { // 删除注释 output:{ comments:false }, // 删除console debugger 删除警告 ...
  • Vue项目架构优化

    2019-03-13 01:25:39
    这篇博客我将为你介绍vue的架构思想,当然这只是我根据遇到项目总结的vue架构,这是我发现的一个小三轮,如果你有好的架构也欢迎指教哦。 好了,我们开始聊吧! 以我手撸的一个小项目 低配饿了么外卖平台 为例:...
  • vue项目遇到优化

    2020-09-24 21:41:29
    一、webpack 常见的优化手段; 首先webpack 是一个资源处理工具,它的出现节省了我们的人力和时间; 可以对资源打包,解析,区分开发模式等等… 其中常见的优化手段: 分离第三方库(依赖),比如引入dll 引入多进程编译,...
  • vue项目打包上线前总会遇到一个问题就是开发过程中遗留的console代码,其实方法很简单: 下载依赖包 npm install babel-plugin-transform-remove-console --save-dev; 下载成功后在根目录的babel配置文件中,...
  • Vue项目优化

    2020-04-29 22:34:36
    vue打包上线移除 consols 方法1、 安装: npm install babel-plugin-transform-remove-console 然后配置在项目根目录下找 babel.config文件夹中找 再次运行 npm run build 命令,就不会有此类型的警告了 遇到的...
  • Vue项目优化心得分享

    2019-08-13 14:23:26
      本该继续更新【Vue探究】系列文章的,但今天我怀着激动的心情打算和大家分享下有关Vue项目优化的一点心得。   先说下我遇到的问题。手上的项目目前虽然只完成了三分之二,但已经有100多个页面,和20多个公共...
  • vue项目优化

    2021-03-03 11:46:19
    应用场景:项目使用webpack4.x进行打包,打包后静态资源通过nginx转发配置 安装包:compression-webpack-plugin vue.config.js配置: const CompressionPlugin = require('compression-webpack-plugin'); module....
  • 基于webpack 3、vue 2和vue-cli 2的性能优化。 gzip压缩,包括vue配置、nginx配置。 2.2.4.1、vue配置 compression-webpack-plugin参数说明: ...1、 打开config/index.js文件,修改: productionGzip: true, ...
  • Vue项目build优化以及其中的坑

    千次阅读 2019-06-02 13:28:35
    Vue项目build优化 不得不说,后台程序员看前端真的是知其然不知其所以然(坑比后台还多,哭辽) 1、开启gzip压缩 用vue-cli的孩子都知道有个config下的index.js配置文件,将productionGzip的值改成true就行,当然...
  • 路由问题: ...以上是写项目过程中遇到的部分问题及优化的地方,纯手打( •̀ ω •́ )y,有什么错误或者有更好的解决方法,欢迎各位老大不吝赐教~ ps:这个代码片都是一样颜色的么,明明已经设置了…
  • 1. vue项目白屏, 首屏加载内容优化 常用的vue项目首屏内容优化: 路由按需加载, 组件按需加载, 添加loading, 骨架屏等 但是一般没有特殊需求都是只使用按需加载即可 2.
  • 转自Vue项目Webpack优化实践,构建效率提高50% 公司的前端项目使用Vue框架,Vue框架使用Webpack进行构建,随着项目不断迭代,项目逐渐变得庞大,然而项目的构建速度随之变得缓慢,于是对Webpack构建进行优化变得...
  • 主要说的是,我在项目中,自己遇到的一些小问题和解决方案 图片 base64 问题 // 有一个 test 的组件 <template> <div class='icon'></div> </template> <style> .icon { ...
  • 19.Vue项目优化

    2021-03-05 10:11:05
    项目优化1.1项目优化策略1.2通过nprogress添加进度条1.3 解决serve命令中提示的警告1.4 在执行build命令时所有的console1.5 生成打包报告1.6 通过vue.config.js修改webpack的默认配置1.7 通过externals加载外部CND...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 11,720
精华内容 4,688
关键字:

vue项目遇到的优化

vue 订阅