前言
性能优化这个问题,在面试的过程中问道的概率还挺大的,特别是对有前端开发经验的面试者来说,基本会被面试官问道关于性能优化的问题。但是在我们做项目的过程中,可能业务比较简单,并没有复杂到需要专门去优化的程度,复杂的业务呢,可能也优化不动。在被问到时可能会被问住(根本不需要优化......)。但是性能优化确实是值得关注的问题,并不是业务复杂到某种程度才去专门做优化。我觉得在平时的编码过程中有良好的习惯,时刻想着怎么写能更好一点,也能达到一种优化的作用。
如何优化代码
一说到优化可能一些比较官方的名词就来了,比如:
-
减少HTTP请求: 合并和压缩CSS、JavaScript文件,使用CSS Sprites或图标字体来减少图片请求,以及避免不必要的资源加载,从而减少页面加载时间。
-
使用浏览器缓存: 设置适当的缓存头,以便浏览器可以在下次访问时从缓存中加载资源,减少重复的网络请求。
-
压缩资源: 使用压缩算法(如Gzip)压缩传输的CSS、JavaScript和HTML文件,减少文件大小,从而降低带宽消耗和加载时间。
-
延迟加载: 将页面上不必要的内容延迟加载,如将图片、广告或其他不紧急的资源推迟加载,从而加快初始页面加载。
-
使用异步加载: 使用异步加载(例如
async
和defer
属性)加载JavaScript,确保脚本不会阻塞页面的解析和渲染过程。 -
优化图片: 使用适当的图片格式(如WebP),调整图片质量和大小,使用响应式图片来适应不同屏幕尺寸,以减少图片加载时间。
-
最小化DOM操作: 减少对DOM的频繁操作,因为DOM操作通常会触发重排和重绘,影响页面性能。可以使用批量更新或虚拟DOM来优化。
-
减少重排和重绘: 避免频繁的样式更改,可以通过合并更改、使用CSS动画代替JavaScript动画等方式减少浏览器的布局和绘制操作。
-
代码拆分: 将代码拆分成多个模块或块,按需加载,以减少初始加载时间,特别是在较大的应用中。
-
使用CDN: 使用内容分发网络(CDN)来分发静态资源,这可以减少网络延迟,加快资源加载速度。
-
移除不必要的插件和库: 定期审查并移除不再使用的插件、库或功能,以减少页面的复杂性和加载时间。
-
性能监测和分析: 使用工具如Google PageSpeed Insights、Lighthouse、WebPageTest等来监测和分析页面性能,并根据建议进行优化。
-
服务端渲染(SSR)和预渲染: 对于某些应用场景,使用服务器端渲染或预渲染可以提前生成部分或全部页面内容,改善初始加载性能。
-
使用现代框架和技术: 现代前端框架如React、Vue等提供了优化性能的工具和技术,如虚拟DOM、组件化等。
-
优化移动端性能: 针对移动设备,考虑使用响应式设计、移动优化的图片和资源,以及避免不必要的操作和动画。
当然不止这些,这些方式肯定是一说到优化性能优化,就能想到的。其实在平时的业务开发中,用到这些也不是很多,我想说的是如何在平时的编码过程中如何尽可能的优化代码:
日常习惯
避免过多嵌套的DOM结构: 尽量保持浅层次的DOM结构,减少DOM元素的嵌套,从而提高渲染性能。
避免使用不必要的重复代码: 在代码中尽量避免重复的逻辑和代码块,可以考虑封装为函数或组件,以减少代码量和维护成本。
使用CSS Grid和Flexbox布局: 使用现代的布局技术,如CSS Grid和Flexbox,可以更轻松地创建复杂布局,减少额外的DOM元素。
利用浏览器缓存: 使用合适的缓存策略,充分利用浏览器的缓存机制,减少重复加载相同资源。
图片懒加载: 对于长页面或带有大量图片的页面,可以使用图片懒加载技术,只在图片进入视口时加载。
尽量减少使用JavaScript: 尽量使用HTML和CSS来实现一些效果,避免过多的JavaScript操作,从而减少性能开销。
精简第三方库: 如果你使用了第三方库,只导入你实际需要的功能,避免导入整个库。
减少DOM查询: 避免在循环中重复查询DOM元素,可以将查询结果缓存起来以提高性能。
延迟加载非必要的脚本: 将不必要的脚本标记为延迟加载,让页面能更快地呈现。
使用WebP格式图片: 如果浏览器支持,使用WebP格式图片,它通常比JPEG和PNG格式更小,加载更快。
使用字体图标或SVG代替图片: 字体图标和SVG图像通常比位图图像更小,同时可以在不失真的情况下进行缩放。
优化路由: 比如路由组件异步加载。对于单页应用,优化路由可以减少不必要的加载和渲染。
防抖与节流: 对于一些频繁的操作使用防抖或节流。
缓存: vue中频繁切换的组件使用KeepAlive进行缓存。react中比如memo,useMemo、useCallback等
使用内联样式: 对于页面上仅需要一次性使用的样式,可以考虑使用内联样式而不是外部CSS文件,减少额外的HTTP请求。
使用网络预取和预加载: 使用和来在空闲时间预取和预加载将来可能需要的资源。
**虚拟列表:**避免大数据量导致 DOM 操作量大。
**取消重复请求:**同一个接口多次请求时取消上一次没有完成的请求。
**loading加载:**对于一些确实比较慢的接口使用loading或骨架屏.
**卸载与取消:**组件卸载时取消事件的监听、取消组件中的定时器、销毁一些三方库的实例。
总结
总之,在日常写代码的过程中,无论业务复杂与否,养成好的习惯以及有固化的优化思想,一定很不错。在排查bug,或者后续的维护中能省力不少。