本文翻译自React团队核心成员Dan Abramov的技术博客。地址:https://overreacted.io/what-a...
本文首发于公众号:符合预期的CoyPan
我React团队工作的这段时间,很幸运能够看见 Jordan、Sebastian、Sophie 和其他团队成员是如何解决问题的。在本文中,我会把从他们身上学到的,浓缩为一篇较高层次的技术准则。这些准则未必详细。它们都是我对React团队的观察和整理 —— 其他团队成员或许有其他的观点。
UI优先于API
当我们把抽象概念大规模用于实践时,难免会有怪异之处。这些怪异之处是如何在用户界面上呈现的呢?你能看出一个应用中包含了哪些特定的抽象概念么?
抽象概念对用户体验有直接的影响 —— 它能创造好的、延续性的的体验或者限制某些东西。这也是为什么我们在设计API时,并不会从抽象本身开始。相反地,我们会从用户体验开始,然后再回到抽象概念。
有时候当我们回到抽象概念时,会发现必须更改整个方法,才能达到正确的用户体验。如果我们先从API下手,就无法察觉到这点。所以,我们将UI放在API之前考虑。
吸收复杂性
简化React内部的实现并不是我们的目标。如果产品开发者可以使用React写出更易于理解、易于修改的代码,我们乐于把React的内部实现变得复杂。
我们想把产品的开发变得更加职责分明,易于合作。这意味着我们必须把负责的部分封装在React的内部。React不能被切分为小规模、耦合松散的模块,因为这样便无法工作。React的使命是成为协调者的角色。
通过提升抽象层级,使得产品开发者更加有力。产品开发会从React的可预测的完备系统中受益。这意味着我们推出的每一个新功能,都必须兼容已经存在的功能。设计和实现React的新功能十分困难。这也是我们核心功能并没有收到太多开源贡献的原因。
我们吸收了复杂的部分,防止他们污染产品的代码。
从Hacks到Idioms
每一个Api都有一些局限性。有时,这些限制会妨碍我们打造良好的使用者体验。为此,我们提供了一些后路(escape hatches)以供需要时使用。
Hacks并不是长久之计,因为他们很脆弱。开发者必须决定他们是否维护,支持这些Hack,或者移除hack而牺牲用户体验。通常大多数人会牺牲用户体验,不然这些hack也会有可能阻碍用户的优化。
我们需要让产品开发者使用这个后路,并观察在他们实践中都是如何使用的。我们的目标是提供这类实现一个常用的解决方法(idiomatic solution),目的是达成更好的用户体验。有时候,一个解决方案,会花费我们数年的时间。我们更倾向于有弹性的hack来确立完整的习惯用法(a poor idiom)。
实现局部开发
你无法在代码编辑器做太多的事情。你可以增加几行,移除几行。或者复制粘贴。但许多抽象概念让这些基本操作变得困难。
比如,MVC框架让删除一些render的操作变得不可靠。这是因为及即使你删除了childern的方法,parent仍有可能执行它。相比之下,React的优势在于:你通常能安全的删除某些render tree内的代码。
在设计API时,我们会假设使用它的人只熟悉他们会用到的局部代码的相关知识。如果预期发生的影响只发生在这局部的代码中,我们将会避免意料之外的结果。例如,我们通常假设新增代码时安全的。在移除和修改代码时,应该清楚指出这些改动会连带影响、应该被考虑到的部分。我们不应该假设改动单一文件需要对整个代码都了解。
如果某一项改动不安全,我们希望开发者能够尽早发现这个改动所带来的的影响。虽然可以使用警告、类型检查和开发者工具来帮忙,但它们都受限于API的设计。如果API不够局部性,局部开发就不可能实现。例如,findDOMNode
就不是一个好的API,因为它需要全面的了解。
渐进的复杂度
有些框架会选择在开发的路上分出岔路,提供两种路线:简单的方法或强大、完整的方法。简单的方法容易学习,但你终究会走到他的极限。这个时候,你必须推倒重来,重新使用另外一套方法来实现。
我们认为实现一个复杂的东西,和实现一个简单的东西,在结构上没有太大的差别。我们并不会简单的状态提供简单的写法,因为这样会使开发中出现岔路。如果我们认为开发者在开发过程中想要完整的开发工具,我们愿意牺牲低门槛来达成这件事。
有时,【简单】和【强大】代表两种不同的框架,那么你扔需要换框架重写,最好能避免这种事。以React为例,增加服务端的render这类的优化会需要付出额外的努力,但你不需要完全的重写。
控制损害
从上到下的解决方式很重要,例如代码评估。然后长时间下来,我们的标准会下降,功能会在dead line前完成,也有可能不继续维护产品。我们无法期待所有人都遵守规则,身为协调者的React必须控制损害。
如果有些UI相关的代码很慢,我们需要想尽一切办法,避免它拖慢载入时间,避免它影响其他的UI表现。最理想的状况是,开发者只会为了他们使用到的功能付出开发成本,而产品使用者只需要载入他们会用到的UI。Concurrent Mode ,包括 Time Slicing 和 Selective Hydration ,可以以不同的方式达到理想状态。
由于代码库本身的性能相对稳定,而应用的代码没有底线。因此我们倾向于在应用代码中去控制损害,而不是去修正代码库内的代码。
相信理论
有时我们会知道某些做法是死路一条。也许它现在可以运作,但可以想象它的局限。本质上无法依靠它来实现想要的用户体验。一旦有机会,我们会立刻从这种情况中抽身。
我们不想卡在这里。如果某种做法在理论上更站得住脚,就算画上好几年,我们也愿意在上面投入精力。在达成目标的过程中,会遇到许多障碍和务实的妥协。但我们详细,若持续的客服这些困难,理论终究会获胜。
你们团队的准则是什么
以上是我观察到的React团队在工作时的基本原则,但我可能漏了很多。我也还没提到React如何推出API,团队如何沟通未来的改动方向等等。或许下次可以再来谈谈这些。
你们团队有什么准则呢?我洗耳恭听。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。