vue2组件懒加载浅析javascript
1、 什么是懒加载html
懒加载也叫延迟加载,即在须要的时候进行加载,随用随载。vue
2、为何须要懒加载java
在单页应用中,若是没有应用懒加载,运用webpack打包后的文件将会异常的大,形成进入首页时,须要加载的内容过多,延时过长,不利于用户体验,而运用懒加载则能够将页面进行划分,须要的时候加载页面,能够有效的分担首页所承担的加载压力,减小首页加载用时webpack
3、如何与webpack配合实现组件懒加载web
一、在webpack配置文件中的output路径配置chunkFilename属性vue-router
1
2
3
4
5
6
|
output: {
path: resolve(__dirname,
'dist'
),
filename: options.dev ?
'[name].js'
:
'[name].js?[chunkhash]'
,
chunkFilename:
'chunk[id].js?[chunkhash]'
,
publicPath: options.dev ?
'/assets/'
: publicPath
},
|
chunkFilename路径将会做为组件懒加载的路径vuex
二、配合webpack支持的异步加载方法npm
1
|
npm install --save-dev babel-core babel-loader babel-plugin-syntax-dynamic-
import
babel-preset-es2015
|
1
2
3
4
5
6
7
|
use: [{
loader:
'babel-loader'
,
options: {
presets: [[
'es2015'
, {modules:
false
}]],
plugins: [
'syntax-dynamic-import'
]
}
}]
|
4、具体实例中实现懒加载编程
一、路由中配置异步组件
1
2
3
4
5
6
7
8
9
10
|
export
default
new
Router({
routes: [
{
mode:
'history'
,
path:
'/my'
,
name:
'my'
,
component: resolve => require([
'../page/my/my.vue'
], resolve),
//懒加载
},
]
})
|
二、实例中配置异步组件
1
2
3
4
|
components: {
historyTab: resolve => {require([
'../../component/historyTab/historyTab.vue'
], resolve)},
//懒加载
//historyTab: () => import('../../component/historyTab/historyTab.vue')
},
|
三、全局注册异步组件
1
2
3
|
Vue.component(
'mideaHeader'
, () => {
System.
import
(
'./component/header/header.vue'
)
})
|
5、配置异步组件实现懒加载的问题分析
一、屡次进出同一个异步加载页面是否会形成屡次加载组件?
答:否,首次须要用到组件时浏览器会发送请求加载组件,加载完将会缓存起来,以供以后再次用到该组件时调用
二、在多个地方使用同一个异步组件时是否形成屡次加载组件?如:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
//a页面
export
default
{
components: {
historyTab: resolve => {require([
'../../component/historyTab/historyTab.vue'
], resolve)},
//懒加载
},
}
//b页面
export
default
{
components: {
historyTab: resolve => {require([
'../../component/historyTab/historyTab.vue'
], resolve)},
//懒加载
},
}
|
答:否,理由同上
三、若是在两个异步加载的页面中分别同步与异步加载同一个组件时是否会形成资源重用? 如:
//a页面 import historyTab from '../../component/historyTab/historyTab.vue'; export default { components: { historyTab }, } //b页面 export default { components: { historyTab: resolve => {require(['../../component/historyTab/historyTab.vue'], resolve)},//懒加载 }, }
答: 会, 将会形成资源重用, 根据打包后输出的结果来看, a页面中会嵌入historyTab组件的代码, b页面中的historyTab组件仍是采用异步加载的方式, 另外打包chunk;
解决方案: 组件开发时, 若是根页面没有导入组件的状况下,而是在其余异步加载页面中同时用到组件, 那么为实现资源的最大利用,在协同开发的时候所有人都使用异步加载组件
四、在异步加载页面中载嵌入异步加载的组件时对页面是否会有渲染延时影响?
答:会, 异步加载的组件将会比页面中其余元素滞后出现, 页面会有瞬间闪跳影响;
解决方案:由于在首次加载组件的时候会有加载时间, 出现页面滞后, 因此须要合理的进行页面结构设计, 避免首次出现跳闪现象;
6、懒加载的最终实现方案
一、路由页面以及路由页面中的组件全都使用懒加载
优势:(1)最大化的实现随用随载
(2)团队开发不会由于沟通问题形成资源的重复浪费
缺点:(1)当一个页面中嵌套多个组件时将发送屡次的http请求,可能会形成网页显示过慢且渲染良莠不齐的问题
二、路由页面使用懒加载, 而路由页面中的组件按需进行懒加载, 即若是组件不大且使用不太频繁, 直接在路由页面中导入组件, 若是组件使用较为频繁使用懒加载
优势:(1)可以减小页面中的http请求,页面显示效果好
缺点:(2)须要团队事先交流, 在框架中分别创建懒加载组件与非懒加载组件文件夹
三、路由页面使用懒加载,在不特别影响首页显示延迟的状况下,根页面合理导入复用组件,再结合方案2
优势:(1)合理解决首页延迟显示问题
(2)可以最大化的减小http请求, 且作其余他路由界面的显示效果最佳
缺点:(1)仍是须要团队交流,创建合理区分各类加载方式的组件文件夹
7、采用第三种方案进行目录结构设计
8、具体代码实现设计
一、路由设计:
import Router from 'vue-router'; import Vue from 'vue'; Vue.use(Router); export default new 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,最优化提升开发效率
直接贴上代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
/**
* Created by ZHANZF on 2017-3-20.
*/
//vuex配置
import
Vue from
'vue'
;
import
Vuex from
'vuex'
;
Vue.use(Vuex);
export
default
new
Vuex.Store({
state: {
//路由组件存储器
routers: {}
},
getters: {
routers: state => {
return
state.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
})
}
};<br><br>
//页面使用路由导航
|
openAnyPage() {
midea.registerRouter('module', resolve => {require(['../module/module.vue'], resolve)});//懒加载
this.$router.push({path: '/home/module', query: {title: this.title}});
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
//页面中使用动态组件 <template> <component :is="currentRouter" :moduleName="title"></component> </template><br><script src="./any.js">
export
default
{
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: {
}
}
</script>
|
2、动态组件的设计
直接用即用即加的方式在实例或路由中直接配置异步组件