React 的未来:Time Slicing和Suspense

JSConf Iceland 大会于 3.1 - 3.2 在冰岛举行,在会中,React 核心团队的 Dan Abramov 发表了名为 “Beyond React 16” 的演讲,描述了对 React 未来的展望,本文根据 Dan 的演讲整理。

React 作为一个通用的框架,需要考虑各种网络状况(网速有快有慢)以及各种设备类型(CPU 性能有好有坏),而框架开发者的一个重要使命就是帮助开发者们开发在各种情况下用户体验都很好的应用程序。

影响用户体验的因素主要可以归为两大类:计算能力(Computing Power)和网络速度(Network Speed),他们对应计算设备的 CPU 和 IO 能力。在 React 中,CPU 主要影响 DOM 元素创建和更新的效率,而 IO 则影响获取数据和懒加载的代码。下面 Dan 用了两个 Demo 来展示 React 在这两个方面的尝试。

Demo 1

第一个例子,由一个输入框和下面的三个图表组成,当输入的内容越复杂,下面的图表也越来越复杂。

为了更直观地看到页面刷新的效率,Dan 还写了一个时钟,绿色表示页面刷新时帧与帧之间间隔的时间很短,而颜色越深则表示间隔时间越长,页面卡顿感越强,用户体验自然也越差。

这种场景中,提升用户体验的一个经典的做法是 Debounce(Throttle 类似),即等用户暂停输入后再刷新页面,对应的 Demo 如下:

但这么做用户体验上也是有缺陷的,如果用户的 CPU 很强劲,那也不得不等暂停输入后才看到结果。那有没有更好的解决方案呢?有的,Dan 给了一种异步刷新的方案,先看图:

引用 Dan PPT 中的一句话,用来体现这种异步方案的精髓。

We've built a generic way to ensure that high-priority updates like user input don't get blocked by rendering low-priority updates.

Dan 称这种特性为 “Time Slicing”,主要包括以下几点:

Demo 2

第二个 Demo 是一个电影信息展示的应用,选择一个电影,点击进入可查看电影的详情和评论。在后面的演示中,Dan 通过一步步修改这个 Demo 的代码来让我们理解 React 在网络方面如何提升用户体验的。

首先,Dan 将数据从硬编码改成了从网络获取。代码如下:

在上面这段代码中,当 React 渲染 MovieDetails 组件时,会先看对应电影 ID 的详情有没有被缓存,因为是第一次,电影详情信息还没被缓存,所以需要去网络拉取,下面高能!React 会阻止渲染过程,直到数据被拉取回来!而我们需要做的,仅仅告诉 React,从电影列表页到电影详情页的过程是个异步过程即可。代码如下:

这样修改过后,下面的动图展示了这种异步过程:点击一个电影,React 去网络拉取对应电影的详情数据,等数据拉取回来后,React 再将页面渲染出来。

同时,页面还保持良好的可交互性,点击一个电影之后紧接着用户也可以点击其他的电影。

上面的修改仅仅模拟了 1s 的网络延迟,如果延迟更长咋办,用户点击了一个电影,发现页面像卡死了一般,用户体验肯定很差。Dan 紧接着又对代码做了修改:使用一个叫 “Placeholder” 的组件包裹即将要渲染的异步组件,当组件在加载的过程中,Placehodler 会显示一个“安慰剂”。

同样的,这个过程界面仍然保持着良好的交互性,当页面在转圈时,用户可以选择返回。

上面的修改中,只有一个电影详情数据需要从网络获取,如果有多个数据需要从网络获取,那么 React 可以选择等所有数据都返回后显示最终的页面,也可以选择优先展示先获取到的数据。

除了在详情页中展示安慰剂,也可以在电影列表处展示,这需要通过一个叫 Loading 的组件来实现,Loading 与 Placehodler 一样,是一个未来的特性。

除此以外,还可以使用 Code Splitting 来优化用户体验。但点击一个电影时,再去拉取跟电影详情页相关的代码。这里还是使用未来提供的 createFetcher 接口来实现 Code Splitting。

运行代码,点击一个电影,会发现 Network 中新拉下来一个叫 “1.chunk.js” 的文件。

最后,Dan 还做了一个用户体验方面的优化,目前为止的 Demo 中,打开页面时,电影海报可能没加载出来(从上面一张动图中也可以看出来),所以 Dan 做了优化,需要等图片加载完成后,页面才能显示。这里的细节不再详述,当然这也是用 createFetcher 实现的。

到这里,Demo 2 就结束了。Dan 用一句话概括了这个新特性:

We've built a generic way to suspend rendering while they load asynchronous data.

Dan 称这个新特性为 “Suspense”,主要包括以下几点:

这两项新的特性据说将在今年发布,是不是很期待呢?你对 Timing Slicing 和 Suspense 又有什么看法呢?欢迎留言。

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180305G03RPL00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券