随着各种工具链的完善,用户硬件设备和带宽的提升,之前的一些性能问题也不再是问题,而且很多优化工作,脚手架工具链等都已经帮我们做好了,开发者只需聚焦在业务层面即可。
每当答辩或者面试时,聊到性能优化时,很多人包括我在内,都不知道该说些什么,这些优化工作都让脚手架底层和框架本身做完了。除非一些特定的业务场景,可能会用到特殊的优化手段。
大概在 10 几年前,IE6、IE7 等还大行其道,各个浏览器的标准还不统一,工具链和脚手架也不像现在这么丰富。为了给用户提供更好体验,前端开发者在性能优化上做了很多工作,包括但不限于:
- 雪碧图:将各种小图拼成一个大图,减少 HTTP 请求次数,提升加载速度;
- 图片懒加载:监听页面滚动事件,判断图片是否可见再进行加载;
- 压缩静态资源:通过压缩和合并静态资源,减少请求体积;
- 减少重绘和重排:重排和重绘是浏览器中相对比较耗时的动作,应尽可能减少这些操作,不过现在似乎很少关注这个了;
- 事件委托:将多个子元素的事件,统一挂载到父级元素上;
- CSS 放前面,JavaScript 放后面;
看到这些优化措施,是不是感到很亲切。不过很多工作脚手架都帮我们做好了。比如小图会自动编译为 Base64;想要首屏速度,可以使用 Next.js 或 Nuxt.js 等服务端渲染框架;脚手架配置麻烦?从 grunt 到 gulp,然后再到 rollup 和 webpack,现在又有了 vite 和 Turbopack。有些工具编译起来太慢,再用 Rust 重写一次。
想要拆分代码?React 和 webpack 已经帮忙做了;想图片懒加载,但监听滚动事件不好判断?好,给到getBoundingClientRect()
和IntersectionObserver()
;事件挂载太多?React 框架中的事件本身就挂载在根节点上。等等。
同时,服务端领域也不甘寂寞,相继出现了 Node.js、Deno 和 Bun。有的号称天然支持 typescript,有的声明自己是一体式解决方案、编译快;有的是起步早、生态好。
各个工具和类库,也都在互相吸引对方的优点,尽可能地提升自己的优势,帮助开发者更好、更快地完成工作。
可是自己作为开发者,总是想做出点啥性能优化的措施呀,要不然答辩和面试不好回答呀。说前面的那些?工具链和框架已经帮忙做好了,而且也有比较成熟的解决方案了,即便用上解决了问题,总感觉还是差点意思,不像是自己的功劳。那还能说点啥呢?
大致是从两个方面开始思考:
- 虽然现在市面上也有不少类似的框架,但我实现的某一点上,他们就没有,或者即便他们这些框架有,性能和可用性上也比不过我的;
- 特定场景里的需求:大部分框架都是普遍性的,那我特定场景里的需求,他们肯定没有实现;我就基于我这个独有的场景实现一些措施;
第 2 种情形通常都有场景壁垒,只有在指定的运行环境或者指定的业务中,才可能会出现一些优化措施。正因为没有普适性,才能做出一些意想不到的性能优化措施。
工具链做得更好、更多,运行起来更快,本身是为了给开发者更好地使用体验。但相对地,留给开发者的性能优化手段已经不多了。而单纯地讲业务,又体现不出自身技术的深度。开发者就得需要寻找其他方面来体现自己了。