JavaScript 的性能分析与提升

JavaScript 的性能分析与提升

对于 JavaScript/前端来说,性能的提升主要有两大方面:

  1. 页面初始化的优化

    这一方面主要涉及到非代码结构上,但是能够提升用户体验感的优化,如,提升用户看到页面的速度、减少用户等待与页面交互的事件。

    如 lazy loading 就是一个比较知名的初始化上的优化,购物网站也好,视频网站也好,这种 2C 的页面会载入大量的数据,如果让用户等到所有的数据都加载成功,再和页面交互,那肯定是会因为使用体验感太差而造成用户流失。

    是否在页面初始化的时候存在太多的 HTTP 请求,以及 HTTP 请求的文件是否太大,这些都会导致加载速度变慢,从而影响用户体验感。

  2. 页面运行时的优化

    这块大部分涉及到结构和实现上的优化,影响到代码实际上的运行速度和性能。

    如页面上如果要使用 3D 功能,那 3D 的渲染是否流畅,是否会阻塞页面的渲染。如果用户点击页面上的可点击部分,是否会造成延迟等。代码的实现是否会造成内存泄露,导致 reference 无法被 GC 正常清理,导致使用的 cache 越来越大,最终页面加载、运行越来越缓慢等。

    有一个比较少提及,但是又的确是问题的方面就是,是不是做了太多的为优化(micro-optimizations)。以 React 为例,useMemouseCallback 是两个内置的 memoization 的 hooks,用这两个 hooks,React 会在每次渲染的时候去比较状态是否有变化,如果有的话,才会重新计算。当计算被 memoized 值的成本高于重新渲染时,那么 memoized 的过程就是没有必要的,这种 micro-optimizations 反而会降低整体页面渲染的效率。

顺便,如果 CSS 很花哨,或者无意义的 HTML 太多,那么有的时候降低页面渲染速度的可能不是 JS,而是 CSS 和 HTML。在不少用了比较炫的 CSS & CSS Animation 的页面,其实 CSS 吃渲染的比重还挺大的。

可选的 performance 工具

测试 performance 的话,除了 devtools 之外其实还有一些其他的工具,不过因为这里不会一一列出,只会大概提一下百度/Google 的范围:

  • JavaScript 自身提供的一些计算表现的函数

    具体可以查看一下 Performance APIPerformanceEntry Object,这个适用于开发环境下使用,因为有一些函数会产生 log,在开发环境下反而会影响 performance。

  • benchmar.js

    这个可能需要自己实现,不过在 Stack Overflow 上找到一个代替品:https://jsbench.me/

    本质上来说,这是一个网站可以接受两个 snippets,然后分别运行并且比较 performance。

    Stack Overflow 上面的回答是:

    jsperf is based on benchmarkjs so using an online code editor (like jsfiddle, jsbin, plunker etc…) and including benchmarkjs as a library will do.

    如果需要对大段的代码进行分析的话,可能说找一个相关的 node 包配置一下比较好。

  • 一些可以测试网站综合性能的 API 或是网页

    https://www.webpagetest.org/,看需求,这可能会是一个付费服务,pricing 如下:

    在这里插入图片描述

    这种网站唯一麻烦的地方就在于,要测试的服务必须要已经有 domain 才可以测试,如果是私网的 beta 版本,可能会有一定的局限性。

    另外,Google 也有对应的 API 可以进行测试,所以我猜国内的一些 cloud service 应该也会有吧

  • devtools

    下面会稍微详细介绍的部分,这里主要说的是 chrome devtools,目前来说最好用

    其他的浏览器也有提供相似的服务(我指的是 Firefox,常用的就这两种)

devtools

network snapshots

它看起来大概是这个样子的:

在这里插入图片描述

具体打开的方式是点击 capture screenshots,随后使用 ⌘ R 去录制,就会有上面的效果。

对于我来说,加载 csdn 的 html 文件就要一秒多:

在这里插入图片描述

1.31s 的时候一些 JS 的文件和海量的图片都下载好了:

在这里插入图片描述

诸如次来的,有 screenshots 看起来会方便一点,因为会有当前的 snapshots:

在这里插入图片描述

不然的话直接看 waterfall 也不是不可以。

network 还有另外一个功能就是对网页进行限速(throttling),这样可以模拟网速慢的情况,网站的表现如何。

performance

performance insight 好像是新推出的:

在这里插入图片描述

所以这里就优先使用 performance 了,其结果如下:

在这里插入图片描述

对于 performance 来说,除了 network throttle 之外还可以使用 cpu throttle,这样可以模拟并分析当前页面在比较老的设备上的性能。

当 record 一部分片段的时候,能够通过 performance 这块比较明显的看出当前页面的性能:

在这里插入图片描述

大致分析一下几个比较重要的时间点:

  • 在大概 700ms 的时候,浏览器开始 FP(First Paint),即浏览器开始渲染初始页面。
  • 在大概 800ms 的时候,浏览器开始 FCP(First Contentful Paint),即开始渲染页面上的第一个内容(有可能是文字、图片等)。
  • 在大概 1700ms 的时候,浏览器完成了 DCL(DomContentLoaded)。这个时候,浏览器已经完成了所有 DOM 节点的渲染,接下来就是依靠客户端去执行操作。
  • 在大概 2800ms 的时候,浏览器完成了 LCP(Largest Contentful Paint)的渲染。
  • 在大概 3000ms 的时候,浏览器完成了加载(load)

在这里插入图片描述

滑动窗口也能够看到在某个区间最耗时的部分是什么。

之前就有碰到一个情况,说是前端的页面渲染太慢,最后通过 profiling 看了一下,主要是 idle(XHR)的时间太长了,所以愉快的把锅甩给了后端(❓)

memory

这里可以查看并对比内存之间的 snapshots,如:

在这里插入图片描述

在这里插入图片描述

这是对比了两次 YouTube 首页刷新的状态,可以看到删除合新建的结点是一样的(YouTube 的首页布局肯定是不变的),因此相对变化为 0(# Delta)。在进行 DOM 节点操作的时候,就可以使用 memory 进行对比。

举个例子,如果删除了 list 一个结点,但是# Delta 变化过大,就有可能是整个 list 被删除了并重新渲染了,这个时候就可以考虑在这里做一些优化。

又或者是添加/删除的时候 # delta 没有变化,那就就代表了某个结点在未被创建的时候就存在了(添加的情况),或是应该被删除了 GC 却没有能够顺利地清理(删除的情况),二者都代表可能会出现内存泄露问题。

lighthouse

在这里插入图片描述

lighthouse 是一个可以跑 audit 的工具,基本上可以分析一下该页面的表现情况,以及在 Google 的 SEO 表现情况,如:

在这里插入图片描述

在这里插入图片描述

如果是 2C 的项目,可以根据这些问题进行修改。

reference

猜你喜欢

转载自blog.csdn.net/weixin_42938619/article/details/131298959