提升 React 应用程序的 TS 性能

几年前,Sentry 在他们的 React 应用程序上遇到了大问题。他们不久前刚刚将其迁移到 TypeScript。并且这个应用是一个大型单体仓库的一部分。

但是 IDE 的性能很慢。你常常需要等待几秒钟,以后对 TypeScript 语言服务器进行更新。运行tsc也需要很长时间。

现在,对于一个大型 TypeScript 代码库来说,这并不罕见。但是 Sentry 团队有种预感,觉得有些不对劲。问题与代码库的大小不成比例。

结果表明,问题,如 Jonas 所概述的,归咎于单一模式。

如何拖垮你的 React 应用的 TS 性能

在 Sentry 的代码库的许多地方,他们都在扩展 React 中的 HTML 类型。例如,定义ButtonProps将如下所示:

  1. import React from "react";
  2. type ButtonProps =
  3. React.HTMLAttributes<HTMLButtonElement> & {
  4. extraProp: string;
  5. };
  6. const Button = ({ extraProp, ...props }: ButtonProps) => {
  7. console.log(extraProp);
  8. return <button {...props} />;
  9. };

这意味着你可以传入所有<button>元素可以接受的props,再加上一个extraProp

  1. <Button
  2. extraProp="whatever"
  3. onClick={(e) => {
  4. // (parameter) e: React.MouseEvent<HTMLButtonElement, MouseEvent>
  5. }}
  6. />;

但事实证明,这种模式异常缓慢。因此 Jonas,遵循 TypeScript 性能 Wiki 的建议,将它们中的每一个都改为使用interface

  1. import React from "react";
  2. interface ButtonProps
  3. extends React.HTMLAttributes<HTMLButtonElement> {
  4. extraProp: string;
  5. }

突然间,事情变得更加迅速了。TypeScript 语言服务器更快了,tsc运行也更快了。仅仅是一点语法的改变。为什么呢?

为什么会这样?

你可能听说过interfacetype稍微快那么一点。这其实并不完全正确。事实上,interface extends稍微比&快一些。

在这篇文章的早期版本中,基于一些模糊的思考,我发表了一篇解释,感谢我以前的同事 Mateusz Burzyński,现在我明白了那是错误的。

问题比我意识到的要复杂 —— 查看这个 Thread 了解他的批评和我们的调查。

希望,我能再次更新这篇文章,用一个明确的描述来解释为什么会这样 —— 但当涉及到 TypeScript 性能时,没有什么是简单的。

总而言之 —— interface extends通常比&快,这个案例也证明了这一点。

原文:https://www.totaltypescript.com/react-apps-ts-performance
作者:Matt Pocock