JavaScript 代码审查:审查内容及如何在实际中给予反馈

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

JavaScript 代码性能分析:寻找瓶颈

\n\n

当您的 Node.js 项目开始变慢时,第一反应可能是“我需要用 Rust 重写所有代码”。但别着急!大多数情况下,问题出在少数几行效率低下的代码上。在本文中,我们将详细讲解如何使用简单的性能分析工具来找到这些“瓶颈”。您将学习如何测量性能、构建火焰图,以及了解 CPU 时间都花在了哪里。

\n\n

为什么要分析代码?

\n\n

假设您的服务器每秒处理 100 个请求,但您需要它处理 500 个。您可以优化所有内容,但这需要数周时间。或者,您可以找到一个占用 80% 时间的函数,并在一个小时内修复它。性能分析恰恰能向您展示时间被花费在哪里。

\n\n

让我们考虑一下需要进行性能分析的主要场景:

\n
    \n
  • API 响应延迟高
  • \n
  • 内存泄漏
  • \n
  • 无明显原因的 CPU 高负载
  • \n
  • 处理大型数据数组速度缓慢
  • \n
\n\n

工具 1:内置的 Node.js 性能分析器 (--prof)

\n\n

最简单的方法是使用 --prof 标志运行 Node.js。它会收集执行统计信息,并将其保存到名为 isolate-*.log 的文件中。

\n\n

让我们创建一个包含瓶颈的测试脚本:

\n\n
// slow.js\nfunction heavyComputation() {\n    let sum = 0;\n    for (let i = 0; i < 1e7; i++) {\n        sum += Math.sqrt(i) * Math.sin(i);\n    }\n    return sum;\n}\n\nfunction fastFunction() {\n    return 42;\n}\n\nconsole.time('total');\nheavyComputation();\nfastFunction();\nconsole.timeEnd('total');\n
\n\n

运行性能分析:

\n
node --prof slow.js
\n\n

执行后,会生成一个名为 isolate-0x...-v8.log 的文件。要读取它,请使用 node --prof-process 工具:

\n
node --prof-process isolate-0x...-v8.log > profile.txt
\n\n

打开 profile.txt,您会看到一个包含时间百分比表格:

\n
[Summary]:\n   ticks  total  nonlib   name\n   785    78.5%  85.3%   JavaScript\n   215    21.5%  14.7%   C++\n   ...\n[Bottom up (heavy) profile]:\n  ticks parent  name\n   500   50.0%   LazyCompile: *heavyComputation slow.js:2:17\n   100   10.0%   Builtin: MathSqrt\n    50    5.0%   Builtin: MathSin\n
\n\n

我们可以看到 50% 的时间都花费在 heavyComputation 函数上。现在我们知道应该优先优化什么了。

\n\n

工具 2:Chrome DevTools (检查器)

\n\n

为了进行更直观的分析,让我们连接 Chrome DevTools。使用 --inspect 标志运行 Node.js:

\n
node --inspect slow.js
\n\n

打开 Chrome 并访问 chrome://inspect。点击“打开用于 Node 的专用 DevTools”。转到“分析器 (Profiler)”选项卡 → “开始 (Start)” → 运行脚本 → “停止 (Stop)”。

\n\n

您将看到一个火焰图——一种图表,其中块的宽度表示执行时间。块越宽,函数就越“热”。我们的 heavyComputation 将是一个巨大的矩形。

\n\n

提示: 使用某个函数上的“聚焦选定项 (Focus selected)”过滤器来查看其内部调用。例如,您可能会注意到 Math.sqrt 被调用了 1000 万次——也许预先计算平方根是值得的。

\n\n

工具 3:perf_hooks — 代码中的精确测量

\n\n

有时您需要测量特定代码段,而无需运行外部工具。为此,请使用内置的 perf_hooks 模块。

\n\n

测量函数执行时间的示例:

\n\n
const { performance } = require('perf_hooks');\n\nfunction processData(items) {\n    let result = [];\n    for (let item of items) {\n        // Simulating complex processing\n        for (let j = 0; j < 1000; j++) {\n            result.push(item * j);\n        }                

博客

书籍推荐