提升 React 应用程序的 TS 性能
几年前,Sentry 在他们的 React 应用程序上遇到了大问题。他们不久前刚刚将其迁移到 TypeScript。并且这个应用是一个大型单体仓库的一部分。
但是 IDE 的性能很慢。你常常需要等待几秒钟,以后对 TypeScript 语言服务器进行更新。运行tsc
也需要很长时间。
现在,对于一个大型 TypeScript 代码库来说,这并不罕见。但是 Sentry 团队有种预感,觉得有些不对劲。问题与代码库的大小不成比例。
结果表明,问题,如 Jonas 所概述的,归咎于单一模式。
如何拖垮你的 React 应用的 TS 性能
在 Sentry 的代码库的许多地方,他们都在扩展 React 中的 HTML 类型。例如,定义ButtonProps
将如下所示:
import React from "react";
type ButtonProps =
React.HTMLAttributes<HTMLButtonElement> & {
extraProp: string;
};
const Button = ({ extraProp, ...props }: ButtonProps) => {
console.log(extraProp);
return <button {...props} />;
};
这意味着你可以传入所有<button>
元素可以接受的props
,再加上一个extraProp
:
<Button
extraProp="whatever"
onClick={(e) => {
// (parameter) e: React.MouseEvent<HTMLButtonElement, MouseEvent>
}}
/>;
但事实证明,这种模式异常缓慢。因此 Jonas,遵循 TypeScript 性能 Wiki 的建议,将它们中的每一个都改为使用interface
:
import React from "react";
interface ButtonProps
extends React.HTMLAttributes<HTMLButtonElement> {
extraProp: string;
}
突然间,事情变得更加迅速了。TypeScript 语言服务器更快了,tsc
运行也更快了。仅仅是一点语法的改变。为什么呢?
为什么会这样?
你可能听说过interface
比type
稍微快那么一点。这其实并不完全正确。事实上,interface extends
稍微比&
快一些。
在这篇文章的早期版本中,基于一些模糊的思考,我发表了一篇解释,感谢我以前的同事 Mateusz Burzyński,现在我明白了那是错误的。
问题比我意识到的要复杂 —— 查看这个 Thread 了解他的批评和我们的调查。
希望,我能再次更新这篇文章,用一个明确的描述来解释为什么会这样 —— 但当涉及到 TypeScript 性能时,没有什么是简单的。
总而言之 —— interface extends
通常比&
快,这个案例也证明了这一点。
原文:https://www.totaltypescript.com/react-apps-ts-performance
作者:Matt Pocock