当我们项目开发到后期的时候,可能就要谈及到去优化下项目了,比如经常碰见的:打包体积过大,首屏加载太慢,还有性能的问题,这其实跟我们平时开发的时候息息相关,代码写的怎么样还得是看个人了。下面就介绍一下优化方式
Vue2项目中一般搭配element-ui比较多,这里就以这个为例;其他ui库的也都是一样的,官网应该都有按需引入说明
咱们一般使用element-ui的时候,直接在min.js全局引入了 ,如下:
- import Vue from 'vue';
- import ElementUI from 'element-ui';
- import 'element-ui/lib/theme-chalk/index.css';
-
- Vue.use(ElementUI);
这样引入使用起来确实是方便,想用什么用什么,缺点就是,我们在项目中没用到的组件也都会打包进去,这样就会导致打包体积变大,所以改成按需引入就按照下方步骤:
npm install babel-plugin-component -D
- module.exports = {
- presets: ["@vue/cli-plugin-babel/preset"],
- plugins: [
- [
- "component",
- {
- "libraryName": "element-ui",
- "styleLibraryName": "theme-chalk"
- }
- ]
- ]
- };
- import Vue from 'vue';
- import {
- Pagination,
- Dialog,
- Autocomplete,
- Dropdown,
- DropdownMenu,
- DropdownItem,
- Menu,
- Submenu,
- MenuItem,
- MenuItemGroup,
- Input,
- InputNumber,
- Radio,
- RadioGroup,
- RadioButton,
- Checkbox,
- CheckboxButton,
- CheckboxGroup,
- Switch,
- Select,
- Option,
- OptionGroup,
- Button,
- ButtonGroup,
- Table,
- TableColumn,
- DatePicker,
- TimeSelect,
- TimePicker,
- Popover,
- Tooltip,
- Breadcrumb,
- BreadcrumbItem,
- Form,
- FormItem,
- Tabs,
- TabPane,
- Tag,
- Tree,
- Alert,
- Slider,
- Icon,
- Row,
- Col,
- Upload,
- Progress,
- Spinner,
- Badge,
- Card,
- Rate,
- Steps,
- Step,
- Carousel,
- CarouselItem,
- Collapse,
- CollapseItem,
- Cascader,
- ColorPicker,
- Transfer,
- Container,
- Header,
- Aside,
- Main,
- Footer,
- Timeline,
- TimelineItem,
- Link,
- Divider,
- Image,
- Calendar,
- Backtop,
- PageHeader,
- CascaderPanel,
- Loading,
- MessageBox,
- Message,
- Notification
- } from 'element-ui';
-
- Vue.use(Pagination);
- Vue.use(Dialog);
- Vue.use(Autocomplete);
- Vue.use(Dropdown);
- Vue.use(DropdownMenu);
- Vue.use(DropdownItem);
- Vue.use(Menu);
- Vue.use(Submenu);
- Vue.use(MenuItem);
- Vue.use(MenuItemGroup);
- Vue.use(Input);
- Vue.use(InputNumber);
- Vue.use(Radio);
- Vue.use(RadioGroup);
- Vue.use(RadioButton);
- Vue.use(Checkbox);
- Vue.use(CheckboxButton);
- Vue.use(CheckboxGroup);
- Vue.use(Switch);
- Vue.use(Select);
- Vue.use(Option);
- Vue.use(OptionGroup);
- Vue.use(Button);
- Vue.use(ButtonGroup);
- Vue.use(Table);
- Vue.use(TableColumn);
- Vue.use(DatePicker);
- Vue.use(TimeSelect);
- Vue.use(TimePicker);
- Vue.use(Popover);
- Vue.use(Tooltip);
- Vue.use(Breadcrumb);
- Vue.use(BreadcrumbItem);
- Vue.use(Form);
- Vue.use(FormItem);
- Vue.use(Tabs);
- Vue.use(TabPane);
- Vue.use(Tag);
- Vue.use(Tree);
- Vue.use(Alert);
- Vue.use(Slider);
- Vue.use(Icon);
- Vue.use(Row);
- Vue.use(Col);
- Vue.use(Upload);
- Vue.use(Progress);
- Vue.use(Spinner);
- Vue.use(Badge);
- Vue.use(Card);
- Vue.use(Rate);
- Vue.use(Steps);
- Vue.use(Step);
- Vue.use(Carousel);
- Vue.use(CarouselItem);
- Vue.use(Collapse);
- Vue.use(CollapseItem);
- Vue.use(Cascader);
- Vue.use(ColorPicker);
- Vue.use(Transfer);
- Vue.use(Container);
- Vue.use(Header);
- Vue.use(Aside);
- Vue.use(Main);
- Vue.use(Footer);
- Vue.use(Timeline);
- Vue.use(TimelineItem);
- Vue.use(Link);
- Vue.use(Divider);
- Vue.use(Image);
- Vue.use(Calendar);
- Vue.use(Backtop);
- Vue.use(PageHeader);
- Vue.use(CascaderPanel);
-
- Vue.use(Loading.directive);
-
- Vue.prototype.$loading = Loading.service;
- Vue.prototype.$msgbox = MessageBox;
- Vue.prototype.$alert = MessageBox.alert;
- Vue.prototype.$confirm = MessageBox.confirm;
- Vue.prototype.$prompt = MessageBox.prompt;
- Vue.prototype.$notify = Notification;
- Vue.prototype.$message = Message;
import './plugins/element.js'
当然上面步骤3 是将element-ui中所有组件全部导入了,我们实际开发中,需要自己去里面手动添加,用到那些,添加哪些,这样即按需引入,还得自己去里面添加可能有点点儿的麻烦
除了上面的方式,还有CDN的方式引入,大家也可以了解一下
项目开发周期比较长的话,可能一个项目有三四个甚至更多的开发人员曾经开发过,之前用到的依赖现在可能都没有用到,或者需求导致不用了,这个时候就要把这些用不到依赖给删掉
可以采用npm uninstall的方式,也可以直接在package.json中将没用的依赖版本删除掉,然后重新npm install 装下依赖即可,如果装不上,有可能是package.lock.json这个文件的原因,里面可能有之前依赖的缓存,给它干掉即可
这里需要一个插件
npm i babel-plugin-transform-remove-console -D
- module.exports = {
- presets: ["@vue/cli-plugin-babel/preset"],
- plugins: [
- [
- "component",
- {
- "libraryName": "element-ui",
- "styleLibraryName": "theme-chalk"
- }
- ],
- 'transform-remove-console' // 去除控制台console信息
- ]
- };
但是babel.config.js是全局文件, 这样不管是运用时依赖还是开发时依赖都会移除console,所以我们这样写:
- const prodPlugins = []
- if(process.env.NODE_ENV === 'production') { // 生产环境下去除console信息
- prodPlugins.push('transform-remove-console')
- }
- module.exports = {
- presets: ["@vue/cli-plugin-babel/preset"],
- plugins: [
- [
- "component",
- {
- "libraryName": "element-ui",
- "styleLibraryName": "theme-chalk"
- }
- ],
- ...prodPlugins
- ]
- };
这样只会在生产环境中去掉console,开发环境下正常使用consloe调试
就是当我们打包后,在js包里面会有很多.map文件,一个js文件就会对应一个sourcemap文件。
那么这个source文件是干嘛用的呢?
什么是 Sourcemap?
Sourcemap 本质上是一个信息文件,里面储存着代码转换前后的对应位置信息。它记录了转换压缩后的代码所对应的转换前的源代码位置,是源代码和生产代码的映射。 Sourcemap 解决了在打包过程中,代码经过压缩,去空格以及 babel 编译转化后,由于代码之间差异性过大,造成无法debug的问题
Sourcemap文件的作用 ?
简单说 Sourcemap 构建了处理前以及处理后的代码之间的一座桥梁,方便定位生产环境中出现 bug 的位置。因为现在的前端开发都是模块化、组件化的方式,在上线前对 js 和 css 文件进行合并压缩容易造成混淆。如果对这样的线上代码进行调试,肯定不切实际,sourceMap 的作用就是能够让浏览器的调试面版将生成后的代码映射到源码文件当中,开发者可以在源码文件中 debug,这样就会让程序员调试轻松、简单很多
sourcemap文件会占很大一部分的包体积,并且一般来讲,对我们前端来说基本是用不到sourcemap文件的,所以我们可以添加配置 ,在打包的时候不生成这些sourcemap文件,可以大大减小包体积的大小,配置也很简单,如下:
在vue.config.js中设置:
- module.exports = {
- productionSourceMap: false, // 打包时不会生成 .map 文件,加快打包速度
- }
将其设置为false即可
其实上面讲的一些方式也有属于首屏加载优化部分,就像按需加载ui库等,另外我们要使用路由懒加载的方式,等真正到某个页面的时候,再去加载对应的js文件, 首屏加载事件太长也有可能是图片过大,可以采用图片懒加载的方式,也有可能是代码的问题,逻辑太复杂,但是处理的不够完美都是有可能的,页面使用骨架屏也是挺好的方式,延迟加载js脚本等等;总之导致首屏加载太慢的因素有很多,还需要一点点的定位
这里附上两位博友的首屏优化方案链接
还可以通过 图片压缩、CSS压缩和提取、JS提取......
再其他的就是跟我们平时开发的时候息息相关了,这个就看个人了;这里举几个例子
我们在Vue2项目中定义变量的时候,真正需要用到且需要有响应式的再往data里面去定义,如果没用到或者我们的变量只在数据层面用到,就没必要写在data中了,因为一旦定义到data中,就会加入到vue中的响应式系统中,会经过一系列的层层递归操作才观察每个变量的变化,当变量改变的时候,再去更新视图,即便是我们再视图上没有用到改变量,它同样会在响应式系统中被实时的监听劫持,这就造成性能上的损耗。
还有一些就是比如我们使用了setInterval定时器、addEventListener监听、或者使用了websocket连接又或者mqtt等等,那么我们在离开页面的时候就要去移除定时器、移除监听、断开连接等等,也就是在destroyed钩子函数中做这些事情,防止造成内存泄漏;
还有就是防抖、节流的使用,当碰到连续事件、频繁触发的时候就要考虑到防抖、节流来限制一下
还有闭包的使用,闭包可以保存变量、不被销毁、防止变量被污染,但如果使用闭包太多也不见得是一件多好的事情,保存变量是占有一定内存的,所以这个大家也需要主要下
再就是平时写的一些逻辑,尽可能的处理的完美一些吧,举个简单的例子,我们for循环一个list,可能当达到某一条件时,我们的目的就达到了,后面就不需要再去循环了,这时候我们会使用break跳出循环,这确实是一个小小的细节,但是一个项目的性能问题往往都是这么小细节累积起来的,所以我们在平时开发的时候,把每一次的细节都处理好,我相信我们的项目不会差!
这次就先说这么多,可能不全,也给大家做个参考,希望能帮到有需要的朋友们儿😊