说在前面
为什么需要按需加载和按需打包?
打包很好理解,就是执行npm run build
得到的dist
文件夹,和我们添加压缩包一个道理,如果打包了一些本来不需要的资源,就会使得打包的最终文件变大,最终影响前端项目的加载效率。
按需加载,比如我们的系统有5个模块,如果我们不做任何介入,Vue,React
等框架默认的加载逻辑是把资源都下载到本地,然后执行后面的交互,如此一来,确实可以通过牺牲首次加载的时长换取后续运行的流畅性(因为不需要再次从网络端获取资源),但是如果本次用户只会用到其中一个模块A,那么其他模块资源的加载则会白白浪费带宽,并且影响项目的首屏加载。
现身说法
按需打包:
项目采用 Vue + ElementUI
。引入ElementUI
有两种方式,全局引入和按需引入,然后大家可以看一下两种引入方式的区别,代码中我只使用了ElementUI
的Button组件。
全局引入Element UI
组件:
按需引入Button
组件:
整整差了2MB
!
按需加载
点击不同的模块,可以动态加载对应模块的资源,如果本次操作不涉及Car
模块,则不会加载car.2847c660.js
文件。
实现方案:
按需打包:
借助 babel-plugin-component,我们可以只引入需要的组件,以达到减小项目体积的目的。
npm install babel-plugin-component -D
然后,将 babel.config.js
(如果没有,在根目录下新建同名文件并复制内容)修改为:
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset',
["@babel/preset-env", { "modules": false }]
],
"plugins": [
[
"component",
{
"libraryName": "element-ui",
"styleLibraryName": "theme-chalk"
}
]
]
}
实现按需打包跟引入方式有很大的关系,如果直接
import Element from 'element-ui'
Vue.use(Element)
这种引入方式就属于全部引入,不管你用没用到某个组件,他都会打包到我们build之后的项目里。
import {Button} from 'element-ui'
Vue.component(Button.name, Button);
// 或者Vue.use(Button)
上述写法就可以只打包Button
组件相关的内容。
通过查看打包后的文件可以发现,打包时确实只引用了包中的一个文件
"webpack:///./node_modules/element-ui/lib/button.js"
打包后的引入方式为:
Vue.use(Button)
所以,我们在main.js
中,最好直接写成上述格式,我觉得还能省下一步转换的过程。
按需打包的效果可以参考 开门见山 里的截图。
按需加载:
Vue
项目实现按需加载比较简单,基于Vue-cli
创建的项目,会帮助我们配置很多打包选项,实际使用过程中,只需要一句话就可以实现按需加载。
一般我们会在router/route.js
中声明组件以及路由的映射关系:
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/car',
name: 'Car',
component: () => import(/* webpackChunkName: "car" */ '../views/Car.vue')
}]
如上述代码:Home
组件就不是按需加载的,他会在项目在浏览器中初始化时就把相关的文件资源加载到缓存中,而Car
组件,则是点击(如上图所示)Car
选项后才会主动去加载。至于为什么会被命名为car.xxx.js
,这个和配置的webpackChunkName
有关,后面会针对webpack
配置单独出一个系列博客,欢迎关注。
说到最后
以上。