注册
web

为什么面试官这么爱问性能优化?

笔者是一个六年前端,没有大厂经历,也没有什么出彩的项目,所以今年以来,前端现在这种行情下并没有收到多少面试,但是为数不多的面试中,百分之九十都问到了性能优化的问题,而且问题都出奇的一致:



平时的工作中你有做过什么性能优化?



对于这个问题其实我的内心os是(各位轻喷~):



你们怎么都这么爱问性能优化的问题?我的简历中也没有写到这个啊。


你们的业务都这么复杂吗?怎么动不动就要性能优化?


你们的代码写的这么拉吗?不优化都不能使用吗?


性能优化是一个高级前端的必要技能吗?



首先客观现实是笔者平时工作中的业务并不复杂,需要性能优化的地方确实不多,一些存在性能瓶颈的大多是使用了其他团队开发的东西,比如播放直播视频的SDK、3D地图引擎等,也找过他们进行优化,但是没用,他们也优化不动。


所以每次被问到这个问题我就很尴尬,说工作中没有遇到过性能问题,估计面试官也不信,直接说没有做过性能优化,那又显得我这个六年经验的前端太水了,连这个都不做,所以每次我只能硬说。


没吃过猪肉,还没见过猪跑吗?其实性能优化的文章我也看过很多,各种名词我还是知道一点的,比如:



  • 性能问题排查:


1.数据埋点上报


2.使用控制台的NetWork、Performance等工具


3.webpack-bundle-analyzer插件分析打包产物




  • http相关:


1.gzip压缩


2.强缓存、协商缓存




  • 图片相关:


1.图片压缩


2.图片懒加载


3.雪碧图、使用字体图标、svg




  • webpack相关:


1.优化文件搜索


2.多进程打包


3.分包


4.代码压缩


5.使用CDN




  • 框架相关:


1.vue性能优化、react性能优化


2.异步组件


3.tree shaking


4.服务端渲染




  • 代码实现


1.按需加载,逻辑后移,优先保证首屏内容渲染


2.复杂计算使用web worker


3.接口缓存、计算结果缓存


4.预加载


5.骨架屏


6.虚拟滚动



等等。


但这些绝大部分我并没有实践过,所以我都说不出口,说我没有机会实践也行,说我没有好奇心不好学不爱思考不主动发现问题也行,总之结果就是没有经验。


所以通常我硬着头皮只能说出以下这些:


1.开发前会花点时间梳理业务,全局视角过一遍交互和视觉,思考组件划分,找出项目中相似的部分,提取为公共组件和通用逻辑。


2.代码开发中尽量保证写出的代码清晰、可维护,比如:清晰的目录和文件结构、添加必要的注释、提取公共函数公共组件、组件单向数据流、组件功能尽量单一等。


3.时刻关注可能会存在性能问题的部分,比如:



路由组件异步加载


动态加载一些初始不需要用到的资源


频繁切换的组件使用KeepAlive进行缓存


缓存复杂或常用的计算结果


对实时性不高的接口进行缓存


同一个接口多次请求时取消上一次没有完成的请求


页面中存在很多接口时进行优先级排序,优先请求页面重要信息的接口,并关注同一时刻请求的接口数量,如果过多进行分批请求


对于一些确实比较慢的接口使用loading或骨架屏


懒加载列表,懒加载图片,对移出可视区的图片和dom进行销毁


关注页面中使用到的图片大小,推动后端进行图片压缩


地图撒点时使用聚合减少地图引擎渲染压力


对于一些频繁的操作使用防抖或节流


使用三方库或组件库尽量采用按需加载,减少打包体积


组件卸载时取消事件的监听、取消组件中的定时器、销毁一些三方库的实例



我工作中的实践也就以上这些,其实就是写代码的基本要求,另外我觉得如果业务复杂,以上这些也并不能阻止性能问题的出现,更多的还是当出现了问题,去思考如何解决。


比如我开源的一个思维导图项目mind-map,当节点数量多了会非常卡,调试分析思考后发现原因是做法不合理,每次画布上有操作后都是清空画布上的所有元素,然后重新创建所有元素,数据驱动视图,原理非常简单,但是因为是通过svg实现,所以就是DOM节点,这玩意我们都知道,当节点数量非常多以后,删除节点和创建节点都是非常耗时的,所以数据驱动视图的框架,比如Vue会通过虚拟DOM的diff算法对比来找出最小的更新部分,但是我没有做。。。所以。。。那么我就自然的做了一些优化,比如:



思维导图场景,大部分情况下操作的其实就是其中一个或部分节点,所以不需要重新删除创建所有元素,那么就可以通过节点复用的方式来优化,将真实节点缓存起来,渲染时通过数据唯一的id来检查是否存在可复用节点,如果没有,那么代表是新增节点,那么创建新节点即可;如果有,那么就判断节点数据是否发生改变,没有改变直接复用,如果发生了改变那么判断是否可以进行更新,如果更新成本高那么直接重新创建;另外也需要和上一次的缓存进行对比,找出本次渲染不需要的节点进行删除;当然,为了避免缓存节点数量无限膨胀,也通过LRU缓存算法来管理


对于不影响其他节点的操作只更新被操作的节点


通过setTimeout异步渲染节点,留一些中间时间来响应页面其他操作


将触发渲染的任务放到队列中,在下一帧进行处理,合并掉一些中间状态


对于鼠标移动和滚动的场景,通过节流来优化


进行一些取舍,早期节点激活时可以修改节点的所有样式,导致激活操作需要重新计算节点大小,更新节点样式,在多选和全选操作下非常耗时,所以后期改为只允许修改不改变节点大小的样式属性


其他一些细节优化:对于数据没有改变的操作不触发赋值或函数调用,一些不起眼的操作可能也是需要耗费时间的;改变了不涉及节点大小的属性不触发节点大小重新计算等



经过以上这些修改后,性能确实有了很大程度的提升,不过有些项目可以通过不断的优化来提升性能,但是有些可能就是设计缺陷,比如我开源的另一个白板项目,更好的方式其实是重做它。


写到这里其实并没有解决本文标题提出的问题:



为什么面试官这么爱问性能优化?



因为我没有怎么做过面试官,甚至面试经验其实都不太多,写这篇文章目的主要有两个:


1.想听听有面试官经验的各位的想法或建议


2.想看看和我有类似情况的面试者面对这个问题,或者说类似的问题是如何回答的


最后再牢骚几句:



有时会感慨时间过的真快,一转眼,作为一个前端已经工作了六年,即将三十而立却立不起来,这么多年的工作,更多的只是收获了六年的经历,但是并没有六年的能力,回过头看,当初的有些选择确实是错误的,也许这就是人生把。


作为一个普通的前端,在如今的行情下面试确实很艰难,尤其是我这种不擅长面试的人,不过话说回来,改变哪有不痛苦的,除了面对也没有其他办法。



作者:街角小林
来源:juejin.cn/post/7239267216805838903

0 个评论

要回复文章请先登录注册