vue组件懒加载浅析

一、 什么是懒加载

      懒加载也叫延迟加载,即在需要的时候进行加载,随用随载。

二、为什么需要懒加载

      在单页应用中,如果没有应用懒加载,运用webpack打包后的文件将会异常的大,造成进入首页时,需要加载的内容过多,延时过长,不利于用户体验,而运用懒加载则可以将页面进行划分,需要的时候加载页面,可以有效的分担首页所承担的加载压力,减少首页加载用时

三、如何与webpack配合实现组件懒加载

  1、在webpack配置文件中的output路径配置chunkFilename属性

output: {

        path: resolve(__dirname, 'dist'),

        filename: options.dev ? '[name].js': '[name].js?[chunkhash]',

        chunkFilename: 'chunk[id].js?[chunkhash]',

        publicPath: options.dev ? '/assets/': publicPath

    },

chunkFilename路径将会作为组件懒加载的路径

2、配合webpack支持的异步加载方法

resolve => require([URL], resolve), 支持性好

() => system.import(URL) , webpack2官网上已经声明将逐渐废除, 不推荐使用

() => import(URL), webpack2官网推荐使用, 属于es7范畴, 需要配合babel的syntax-dynamic-import插件使用, 具体使用方法如下

npm install --save-dev babel-core babel-loader babel-plugin-syntax-dynamic-importbabel-preset-es2015

use: [{

        loader: 'babel-loader',

        options: {

          presets: [['es2015', {modules: false}]],

          plugins: ['syntax-dynamic-import']

        }

      }]

四、具体实例中实现懒加载

  1、路由中配置异步组件

exportdefaultnewRouter({

    routes: [

        {

            mode: 'history',

            path: '/my',

            name: 'my',

            component:  resolve => require(['../page/my/my.vue'], resolve),//懒加载

        },

    ]

})

2、实例中配置异步组件

components: {

        historyTab: resolve => {require(['../../component/historyTab/historyTab.vue'], resolve)},//懒加载

        //historyTab: () => import('../../component/historyTab/historyTab.vue')

    },

3、全局注册异步组件

Vue.component('mideaHeader', () => {

    System.import('./component/header/header.vue')

})

五、配置异步组件实现懒加载的问题分析

1、多次进出同一个异步加载页面是否会造成多次加载组件?

  答:否,首次需要用到组件时浏览器会发送请求加载组件,加载完将会缓存起来,以供之后再次用到该组件时调用

  2、在多个地方使用同一个异步组件时是否造成多次加载组件?如:

//a页面

exportdefault{

    components: {

        historyTab: resolve => {require(['../../component/historyTab/historyTab.vue'], resolve)},//懒加载

    },

}

//b页面

exportdefault{

    components: {

        historyTab: resolve => {require(['../../component/historyTab/historyTab.vue'], resolve)},//懒加载

    },

}

  答:否,理由同上

  3、如果在两个异步加载的页面中分别同步与异步加载同一个组件时是否会造成资源重用? 如:

//a页面import historyTab from '../../component/historyTab/historyTab.vue';

export default {

    components: {

        historyTab

    },

}//b页面exportdefault {

    components: {

        historyTab: resolve => {require(['../../component/historyTab/historyTab.vue'], resolve)},//懒加载    },

}

  答: 会, 将会造成资源重用, 根据打包后输出的结果来看, a页面中会嵌入historyTab组件的代码, b页面中的historyTab组件还是采用异步加载的方式, 另外打包chunk;

  解决方案: 组件开发时, 如果根页面没有导入组件的情况下,而是在其他异步加载页面中同时用到组件, 那么为实现资源的最大利用,在协同开发的时候全部人都使用异步加载组件

  4、在异步加载页面中载嵌入异步加载的组件时对页面是否会有渲染延时影响?

  答:会, 异步加载的组件将会比页面中其他元素滞后出现, 页面会有瞬间闪跳影响;

  解决方案:因为在首次加载组件的时候会有加载时间, 出现页面滞后, 所以需要合理的进行页面结构设计, 避免首次出现跳闪现象;

六、懒加载的最终实现方案

  1、路由页面以及路由页面中的组件全都使用懒加载

  优点:(1)最大化的实现随用随载

     (2)团队开发不会因为沟通问题造成资源的重复浪费

  缺点:(1)当一个页面中嵌套多个组件时将发送多次的http请求,可能会造成网页显示过慢且渲染参差不齐的问题

2、路由页面使用懒加载, 而路由页面中的组件按需进行懒加载, 即如果组件不大且使用不太频繁, 直接在路由页面中导入组件, 如果组件使用较为频繁使用懒加载

  优点:(1)能够减少页面中的http请求,页面显示效果好

  缺点:(2)需要团队事先交流, 在框架中分别建立懒加载组件与非懒加载组件文件夹

  3、路由页面使用懒加载,在不特别影响首页显示延迟的情况下,根页面合理导入复用组件,再结合方案2

  优点:(1)合理解决首页延迟显示问题

     (2)能够最大化的减少http请求, 且做其他他路由界面的显示效果最佳

  缺点:(1)还是需要团队交流,建立合理区分各种加载方式的组件文件夹

七、采用第三种方案进行目录结构设计

八、具体代码实现设计

1、路由设计:

import Router from 'vue-router';

import Vue from 'vue';

Vue.use(Router);

export defaultnew Router({

    routes: [

        {

            mode: 'history',

            path: '/home',

            name: 'home',

            component:  resolve => require([URL], resolve),//懒加载            children: [

                {

                    mode: 'history',

                    path: '/home/:name',

                    name: 'any',

                    component:  resolve => require(['../page/any/any.vue'], resolve),//懒加载                },

            ]

        },

        {

            mode: 'history',

            path: '/store',

            name: 'store',

            component:  resolve => require(['../page/store/store.vue'], resolve),//懒加载,            children: [

                {

                    mode: 'history',

                    path: '/store/:name',

                    name: 'any',

                    component:  resolve => require(['../page/any/any.vue'], resolve),//懒加载                },

            ]

        },

        {

            mode: 'history',

            path: '/my',

            name: 'my',

            component:  resolve => require(['../page/my/my.vue'], resolve),//懒加载,            children: [

                {

                    mode: 'history',

                    path: '/my/:name',

                    name: 'any',

                    component:  resolve => require(['../page/any/any.vue'], resolve),//懒加载                },

            ]

        },

    ]

})

(1)首层的路由根组件分别对应的tab页面

  (2)根目录后跟着各个子路由页面,子路由采用动态路由配合路由的编程式导航再加上vuex,最优化提高开发效率

  直接贴上代码:

//vuex配置

importVue from 'vue';

importVuex from 'vuex';

Vue.use(Vuex);

exportdefaultnewVuex.Store({

    state: {

        //路由组件存储器

        routers: {}

    },

    getters: {

        routers: state => {

            returnstate.data;

        }

    },

    mutations: {

        //动态增加路由

        addRouter: (state, data) => {

            state.routers = Object.assign({}, state.routers, {

                [data.name]: data.component

            });

        }

    },

    actions: {

        acMethods({commit}) {


        }

    },

})


//根目录中注册路由组件

window.midea = {

    registerRouter(name, component) {

        Store.commit('addRouter', {

            name: name,

            component: component

        })

    }

};

//页面使用路由导航

openAnyPage() {

    midea.registerRouter('module', resolve => {require(['../module/module.vue'], resolve)});//懒加载

    this.$router.push({path: '/home/module', query: {title: this.title}});

//页面中使用动态组件   

exportdefault{

    data () {

        return{

            routeName: '',

            currentRouter: '',

            title: '',

        }

    },

    created() {

        this.routeName = this.$route.params.name;

        this.title = this.$route.query.title;

        this.currentRouter = this.$store.state.routers[this.routeName];

    },


    methods: {


    }

}

二、动态组件的设计

  直接用即用即加的方式在实例或路由中直接配置异步组件

转载至:https://www.cnblogs.com/zhanyishu/p/6587571.html

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,080评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,422评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,630评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,554评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,662评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,856评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,014评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,752评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,212评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,541评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,687评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,347评论 4 331
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,973评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,777评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,006评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,406评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,576评论 2 349

推荐阅读更多精彩内容