【译】2016React 大会之 React 展望
In 未分类 on 2016年04月20日 by view: 7,662
4

译者按:2016 年 React.js 大会在今年 1 月份举行,2 月底放出了视频,本文翻译的是其中一个演讲 What Lies Ahead(自备梯子), 介绍了 React 目前的进展,以及未来的研发方向。

Hi, 我是 Ben,在 React 团队工作,今天我要介绍的是我们对 React 未来的构想。

当我们在考虑 “React 还有哪些改进空间?”“还有什么问题可以用 React 解决?” 的时候,我们都在尝试回答一个问题——React 如何帮助(开发者)开发极致的应用?这个问题有两个部分要考量。首先,一个极致的应用明显应该有良好的用户体验。同时,我们认为开发体验的地位也是举足轻重。所以今天我们要讨论这两个话题。

在我继续阐述之前,我需要声明一下,我今天要讲的东西基本上都是一个 idea,我们还没有为之写过代码,我们也可能不会实现。然而这些都是我们特别想改进的地方,而我们团队太小,实现起来要花一定时间,所以如果你们能直接实现它就更好啦。(嘿嘿嘿)记住这一点,希望接下来的分享能给你们带来启发。

UX(User Experience 用户体验)

动画

首先是动画。动画对一个优秀的应用来说是至关重要的,开发者也往往会先在这方面发力来提高应用质量。动画有很多种,像<blink>,<marquee> 这种标签式的——对用户没什么卵用,但有些动画还是很重要的,它有助于用户感知当前的应用位置,特别是对于移动应用,天然的小屏幕,缺乏丰富的上下文。

我们刚推出 React 的时候,人们问得最多的问题之一就是,动画在 React 中的最佳实践是怎样的?这个问题确实很自然。我们看看 React 的开发模式——给出一个 State A 与 State B,告诉 React 对应的 State 如何 render,然后 React 就接管了从 State A 到 State B 之间的变换,开发者不需要关心 React 是如何做 Dom Diff 以及修改 Dom 的。然而动画关心的恰恰就是这个变换的过程。 目前动画在 React 上已经有很多优秀的组件与库,React transition Group React Motion,还有 React Native 里的 Animated 库。
1_1
(译者注:此处略去 Ben 安利 Animated 的过程,感兴趣的读者可以查阅 ReactNative Animated 动画详解

所以,我们打算在 web 版的 React 里实现 Animated 库。

手势

动画与手势是紧密相连的,而手势正是我们当前不好把控的地方。人们在构造应用的时候经常忽视手势的重要性,特别是移动应用上。事实上,手势的流畅度正是原生或者优秀应用与恶心应用之间最大的差距之一。

2_1

我们看个例子。这是苹果手机上的地图应用,看起来很简单,与它交互起来也很轻松。仔细分析下这个应用,我们会发现有大量的手势操作在里面。你可以

  • 用一个手指拖动地图
  • 用两个手指缩放地图
  • 可以点击大头针查看相关信息
  • 双击放大地图
  • 长按放置一个新的大头针

这些操作加起来,体验确实很优秀。但没有合适的代码抽象时,这个应用很难开发出来,事实上在 web 基本不可能用 touchstart,touchmove,touchend 开发出来,因为这不是我们想要的接口。我们需要的是一个基于它们的手势系统,可以推断用户的手势操作,预测用户的行为。所以我们的目标是做一个手势系统,有简单的组件 API,而且是纯 JS 实现。React Native 可以在 iOS 和 Android 上借用系统的能力,但我们不想考虑跨平台的问题,这样 Web 上也可以有良好的手势体验。

性能

关于用户体验的话题,我想讲的第三点是性能问题,这里指的是列表优化。有一些 Web 开发者可能疑惑了,为毛是列表?我想移动 Web 开发者应该有一些体会。在移动应用上,我们用到了大量的列表,通讯录、日历、通话记录,信息,照片展示,全都是一列东西。所以列表性能优化对于 React 也是很有意义的。这里我想讲三个技术点
3_1

窗口渲染(Windowing)

窗口渲染指的是只渲染在屏幕上的部分。这听起来很明显,为什么要浪费时间渲染不在屏幕上的东西呢?然而这活现在在 React 的模型下没那么简单。我们对此有做过一些抽象,然而性能效果都不尽人意。

分块渲染(Render In Thunks)

我们的第二个想法是,将列表内容分块渲染。当你在滚动一个列表的时候,一个新的列表项出现在屏幕上了,看看这个新项的复杂度,如果是个非常复杂的东西,比如一条 Facebook 的状态,有作者,内容,图片,视频,评论,点赞等等,几十个视图需要在屏幕上渲染,这可能 50 到 100ms,此时滚动就开始变得不流畅,反应迟钝了。如果 React 可以只渲染这条状态的一部分,保持滚动流畅,然后再慢慢分帧渲染这条状态,这样就可以使应用持续保持响应了。

布局(Layout)

关于性能的第三点是布局。当我们用 Chrome 的 Timeline 剖析任何 Web 应用的时候,看到很多红色的小三角,鼠标移上去,显示着强制回流(Force Reflow)。当重复地改变元素样式,然后再去获取元素样式的时候,浏览器不得不及时地重新执行渲染算法,然后给出最新的元素渲染信息。React 在这方面已经做得不错,你很难意外地创建一个这样的循环来消耗浏览器的性能,但还是有这种场景存在。

假设有一个组件,你希望根据组件的占用空间来做不同的展示,这时最好的选择,是渲染一个占位器,在 componentDidMount 的时候可以测量内容的宽高来决定最后的渲染结果,然后再次触发 render 来实现。当你希望根据渲染结果,比如文字宽度,来决定最终渲染的时候,总是不得不渲染两次。

我们的想法是,由 React 来管理布局如何?你们肯定觉得这想法很疯狂,我一开始也是这么觉得的。但仔细想想,这样做会带来什么改变:
4_1

  1. render()里获取布局信息。

    比如当文字宽度大于 300px 时,渲染 A,否则渲染 B。

  2. 避免不必要的回流问题

  3. 使得窗口渲染的实现简单得多

  4. 避免创建仅布局相关的元素

    当我们在 Facebook Google 的页面上审查元素时,能看到大量的 div。有一些 div 有边框背景色,然后更多的 div 往往只是因为布局需要而创建的。它们不渲染任何东西,存在的意义就是把其它元素捆在一起。如果没有这个 div,而子元素能保持在原来的位置上,那么渲染出来的结果是一样的。我在 Facebook.com 上做了统计,发现有 60% 的元素就是干这活的。它们不渲染任何东西,而浏览器还要对它们进行管理,处理它们的事件等等。如果我们能把这些元素去掉,显然可以使页面加速。

  5. 创建新的布局

    用 css 来布局页面有多痛苦,我相信大家都懂的。特别是使用浮动,绝对定位等,总是很难兼容各个浏览器地把元素放到我们期望的位置上。FLexbox 布局就相对好多了,不过我们很多时候还在等各个浏览器支持某些特性, 而且它也不是万能的,比如不支持 Aspect Ratio 布局等等。但是,如果我们掌握了布局信息,我们可以创建自己喜欢的布局组件,比如堆栈布局(stack layout)/栅格布局 (grid layout)/瀑布流布局(Pinterest layout)

DX(Developer Experience 开发者体验)

下一部分我想讲一讲开发者体验。之所以讲这个话题,是因为提高开发者体验,就可以减少开发者无谓的时间浪费,提高开发速度,有助于开发者专注开发出高质量的应用。

新项目体验

如果你足够幸运,你也许从来不需要从头开始构建一个 React 项目,因为公司里的 React 项目已经创建好了,正在正常运转。提到这点,是因为现在创建新项目是一个痛苦的体验。如果你想尝试最新的工具,你需要花时间搞定 node npm gulp webpack babel 等等一堆东西,此时你还没写出一行代码。你也许不需要这些玩意,比如 React 的玩具项目就没用到这些(除了一行用了 babel 即时转译的代码)但这些工具并不是无用的,相反,它们解决的都是很现实的问题,构建大型项目的时候往往离不开它们,然而同时我们失去了 web 的朴素性——创建一个 HTML,用浏览器打开就可以用了,不用安装任何东西。

我们理想的开发模式是,只需要创建一个指向根页面的 app.js,然后用 react 运行它,就可以直接打开浏览器看效果了。如果指定平台是 ios 或者 android,可以打开对应的模拟器。而随着项目的逐渐发展,我们为了性能优化,提高扩展性等原因,可以慢慢地把上面列到的工具加进项目中,但它们不应该是启动新项目时的必须项。
目标:用一个文件快速构建原型,然后随时间慢慢增强应用
5_1

开发者工具

第二,是老生常谈的开发者工具。有许多工具我忍不住想安利一下:

  1. 官方出品的 chrome/firefox 的 react-devtools 插件
  2. 热加载(react-transform-hmr)
    修改文件,保存文件,浏览器或者模拟器就会自动更新页面,而不需要重新加载页面
  3. IDE(nuclide,deco)
    nuclide 是 facebook 出品的 IDE,而 deco 是最近在 Hacker News 上比较火的 React Native IDE。这些 IDE 可以让你清晰的看到组件状态,修改样式时可以看到实时的效果,同时完全不需要退出 IDE。

    以上这些工具都很棒,我们团队都很喜欢,请做出更多类似的东西,我们会尽我们所能提供帮助。

数据管理

7_1
第三个开发者体验的问题是数据管理。人们有很多种方法可以做数据管理,而大多数情况下都是从 React 内置的 setState 入手的,这是一个很好的起点。setState 超级简单,一两行代码就可以了。它将数据都封装在了组件内部,这在一开始使得组件内部通信变得异常简单,但当你想复用这个组件的时候,麻烦就来了,你需要做额外的工作来保持数据的一致性。

所以当应用规模逐渐增长的时候,人们往往会转向 FluxRedux 等。这些方案将数据从组件中抽离,放置在中心化的存储结构中,这是一种很棒的实践,你可以随时随地从组件中访问这些数据。FluxRedux 都没有提供服务端通信的解决方案,交给开发者自己实现。使用这些框架还有许多要预设的地方,比如 dispatcher action creator 等等。

第三种数据管理的方式,Relay,在 Facebook 内部就非常流行,目前开源社区对它的关注也在不断增加。Relay 允许组件自由地获取自己需要的数据,而不是 “通知 server 去获取数据,提供 API,然后在数据中心拉取 API,再填充到组件”。 基本上 10 行代码就可以搞定了,我们称之为 Colocated Query。我们认为这玩意意义非凡,已经在 Facebook 内部用上了,不过如果没有一个支持 GraphQL 的 server,relay 就玩不转了,不幸的是目前大多数人都没有 GraphQL Server。不过如果你有很多纯客户端数据需要管理的话,Relay 也不能帮上太多忙,因为在服务端没有对应的副本。

这些数据管理的方式都很棒,我们的目标是找到结合这三种方案的最佳实践,配置简便同时能复用代码。 理想情况下,我们可以切换到任意一种模式进行开发,而代码复用是开发体验中很重要的一环。我们鼓励你在设计应用的时候,尽可能使自己的代码容易复用。可能是复用数据逻辑,也可能是复用 UI,或者是把数据逻辑与 UI 放在同一个组件里复用。

代码复用

9_1

谈到代码复用,我想给大家看看 Facebook 第一个完全用 React Native 实现的 APP,这是一个用来创建和管理 Facebook 广告的 app,可以看出 iOS 与 Android 的界面很像,但是设计上都符合各自的系统规范,看起来像是原生的,而实际上它们有 90% 的代码是共用的。我们还有一个移动 web 版,它和 App 版共享一点点数据逻辑层的代码,完全不复用 UI 代码。但可以看到他们相似的基本特征与系统目标,同样的广告活动列表。

我们已经有 ReactNative 可以开发 iOS 和 Android,如果再支持一些 web 版呢?这对你来说,并不是什么天翻地覆的变化,你不需要改变原有的工作流——拉取数据,设置 img、span 标签,填充文本,虽然像 iOS 和 Android 一样,并不能共享全部的代码,但为什么不复用基本的界面呢?就像图中一样,有 iOS、Android、Web 三个版本,看起来很相似,并且共享着 90% 的代码。

这只是一个 idea,我知道你们都希望它真的存在,然而它目前仍然是镜花水月。这真的很有启发性,它能真正改变工程师的组织结构,与其将工程师分为 iOS 组、Android 组、Web 组,可以把他们合为一个团队,基本上看起来就像是 3 倍人力——我开始关心硅谷的人力问题了= =

今天的 React

谈了这么多,我们有太多想法,该如何实现呢?
10_1

我们现在是一个超大的开源社区了,目前 React 的版本是 0.14,在 2013 年时已经有用于生产环境的稳定版了,下周五(这里指 2016 年 1 月)我们即将发布下一个候选发布版本 15.0。之所以叫 15.0,是因为我们发现,之前发行的许多版本都已经可以用在生产环境上了,应该有个大于 1.0 的版本号了。大家已经习惯了 React13,React14,现在可以称之为 React15 了。即将发行的版本主要解决的问题有:完整支持 SVG 标签,文字节点不再有 span 标签包裹,废弃<noscript> 标签(组件返回 null 的时候出现),使用 HTML 注释代替。我们会更频繁地发布小版本,更快地增加新特性。同时,还有一次内部重构,废弃了 react-id,现在审查元素也不会看到它们了,使得性能提高了 10%(此处有掌声)

11_1
在 2015 年,我们有 300 个人给 react 贡献代码,600 个人给 react-native 贡献代码,这么多人,估计这个会场都坐不下了。我们在 Github 上获得了 36000 个 star,只是个虚荣的数字,我提到这个数字是因为我们想知道有多少开发者在使用 React 了,而 Google 可以告诉我们,已经有 225,000 个人安装了 Chrome 的 react-devtools,这意味着成千上万人已经在用 React 构建应用了,这太令人兴奋了。不仅仅是数字,我们还有很多关于 React 的优秀项目,比如 Redux、material-ui,react-routers,enzyme,解决了很多我们都没考虑过的问题。

正如我刚才所说,希望大家能从这次分享得到灵感,贡献更多鹅妹子樱 (amazing) 的项目,谢谢大家!

原创文章转载请注明:

转载自AlloyTeam:http://www.alloyteam.com/2016/04/reactjs2016-what-lies-ahead/

  1. 尼古拉斯·李·Skyfucker 2016 年 4 月 28 日

    66666

  2. 吴聊 2016 年 4 月 25 日

    地板

  3. 农夫山泉有点田 2016 年 4 月 23 日

    板凳

  4. 达克 2016 年 4 月 21 日

    沙发

发表评论