难度级别:中高级及以上 提问概率:75%
webpack打包优化主要的思想就是合理利用浏览器缓存、减小代码体积以及减少HTTP请求数量。尽管我们在开发阶段已经做了大量的优化工作,但开发阶段难免存在疏忽,而且源代码也不能直接部署到服务器。可以说开发阶段与webpack打包阶段的优化都很重要,相辅相成。接下来我们看一下webpack都可以帮我们做哪些性能优化相关的工作。
1 去除console.log代码
线上代码要去除console.log已经成为一种共识,它很可能会暴露网站的关键信息,使用不当还会造成内存泄漏。但开发阶段又不免使用console.log来调试代码,尽管大家都会注意使用完后手动删除,或者上线前整体查找一遍进行删除,但手动的工作总是避免不了疏忽。可以通过下载babel-plugin-transform-remove-console插件,来实现上线打包前去除所有的console.log代码。
2 严格区分开发依赖和线上依赖
很多工具代码上线后并不是必须的,例如webpack、babel、less这些,所以在安装的时候,一定要注意,仅仅是开发阶段所需的依赖包,在安装的时候加上-dev参数。一旦错误的把开发依赖放入线上依赖,必然会使上线文件体积增大。
3 忽略无用代码
在迭代开发过程中,总会有一些代码会变得无用。如果开发者自己比较清楚代码的来龙去脉,那么可以及时删除无用的代码。但如果项目存在人员更换的情况,后接手的开发者大多数时候会觉得多一事不如少一事,暂时用不到就先不管,万一删除后测试不到位,上线后又是有用的代码就会报错。久而久之,每个老项目都会存在这样的问题。在使用webpack打包的过程中,开启tree-shaking功能,可以有效忽略上下文中不需要的Javascript代码,从而减小文件体积。不过我们仍然需要思考的是,无用的CSS代码仍然会有这种问题,而且这种问题还会长久存在,试想一下,哪个即将要离职的开发人员还会兢兢业业的删除项目中无用的代码呢?
4 压缩文件体积
开发过程中的Javascript代码以及CSS代码体积都比较大,如果直接部署开发代码文件,会使文件下载时间变长,用户体验不友好。所以在webpack打包过程中,利用uglifyjs-webpack-plugin、optimize-css-assets-webpack-plugin等插件压缩Javascript以及CSS代码。
5 处理小图片
项目中如果包含体积比较小的icon图片,在项目加载过程中就会产生HTTP请求,一旦HTTP并发请求过多,就会阻塞很多重要的网络请求。除了将多个小icon图片合成一张大图片,前端使用background-position按位置获取对应小icon之外,还可以在webpack中设置,当图片小于一定体积的时候打包为base64图片,这两种做法都是为了减少不重要的HTTP请求,为重要网络请求留出下载空间。
6 路由懒加载
拿Vue单页面应用项目来说,如果多个路由页面都采用同步加载的方式,最终webpack打出文件会包含所有路由页面,当用户首次访问网站的时候,很多首页用不到的文件也会同时被下载下来,这样很容易阻塞首页急需被加载的文件。这种情况下,非首页路由采用import异步引入的方式,打包的时候就可以把非首页文件剥离出来。这样做在首页加载过程中不仅可以减小主文件体积,也可以避免因无用资源过多而产生网络阻塞的问题。
如果首页内容比较多,还应该按业务划分出首屏和非首屏组件,为非首屏组件设置延迟加载或滑动加载,最大限度的提升首屏内容渲染速度。需要注意的是,如果把非首屏组件设置为滑动加载,那么还需要添加开关变量,因为一旦非首屏文件加载过一次,这些文件就会被浏览器缓存,当用户再次刷新页面的时候,其实已经可以非常快速的加载这些文件了,就无需再滑动延迟加载了。
7 有效利用缓存
如果项目中使用了类似Vuex、jQuery这些第三方库,因为这些第三方库代码短时间内不会发生变化,所以应该有效利用浏览器缓存,将这些第三方文件部署到服务器一个稳定的目录下,不应该参与webpack打包。同理,为业务代码设置hash值,只有被更新的组件打包时才会产生新的hash文件,这样做同样是为了有效利用浏览器缓存,使没有被更改的文件可以更快速的被加载。
8 合理利用source-map
我们知道,代码上线后会进行压缩混淆,一旦程序运行报错,很难直接看出具体问题出在哪里,所以很多开发者希望放开source-map配置,可以在线上及时发现问题。如果是体量比较小的内部系统还好说,开发人员可以直接到现场排查问题,但如果是用户群体比较广的网站,程序运行过程中出现问题,开发者是无法现场解决问题的。所以更推荐采用错误采集上报的方式,把错误收集起来,到准生产环境复现并解决问题。除此之外,打开source-map配置之后,会生成体积比较大的map文件,这样做不仅会占用服务器存储空间,还有暴露源码的风险。
刷题思考
这道题考的比较全面,其实在面试中可以说的点非常多,求职者可以把本小节中的参考答案拆开说,多说一些知识点。
本书一直在强调,面试的时候求职者要避免指导性回答,意思就是不能简单的说,遇到本题这种答案比较多的要主动带有第一第二这种字眼,一来让自己可以回答的更有思路,二来让面试官知道自己具有比较清晰的逻辑。另外在回答的时候,没说到一个优化点的时候,如何做可以少回答一些,但这样优化的好处一定要着重说,最好是时常带有加速渲染、提升用户体验、增强用户留存这样的字眼。
类似考点
性能优化是前端面试中的高频考点,如果你已经掌握了本小节中的知识点,那么面试官很可能还会提出以下问题,例如请你说一说,如果刚上线的代码出现问题,都有哪些回退的方案?例如你知道打包过程中,如何把静态资源的路径改为CDN路径吗?例如在打包过程中,你发现主文件体积比较大,会如何优化?