# 10. React.js 研讨会专题

内核恐慌 · 2015-02-08

<https://lib.pan.icu/cae99ea1-517d-47a8-af71-3bc088063dc8>

本期节目邀请到参加React.js Conf 2015的柳成荫（Willow），与主持人Rio和吴涛深入探讨React.js及其生态系统。节目从React解决传统前端框架（如Backbone）的DOM操作和状态管理问题入手，详细解释了Virtual DOM、JSX语法、单向数据流Flux架构、Immutable Data等核心概念。柳成荫分享了其公司从Backbone迁移到React的实践经验，并介绍了React Native如何通过Virtual UI抽象实现跨平台原生组件渲染，以及Facebook对React的强力支持。此外，节目还前瞻性地讨论了GraphQL与Relay如何解决RESTful API的局限性，以及图数据库在数据查询中的潜力。整体上，节目认为React代表了前端开发的下一个阶段，值得开发者深入学习和采纳。

## Questions this episode answers

### React Native 提出的 “learn once, write everywhere” 是什么意思？它如何实现跨平台开发？

React Native 的口号是“learn once, write everywhere”，柳成荫解释这意味着开发者用相同的方式编写 iOS、Android 和 Web 应用，但各自使用平台原生 UI 组件，而非一次编写到处运行。JavaScript 逻辑在后台线程执行，通过异步通信将渲染结果传给主线程，避免界面卡顿。布局采用 Flexbox 模型，比原生约束式布局更直观，从而在保证原生性能的同时降低学习成本。

[55:45](https://lib.pan.icu/cae99ea1-517d-47a8-af71-3bc088063dc8?t=3345000)

### GraphQL 和 Relay 如何解决 REST API 在获取数据时的局限性？

Rio 指出 REST API 存在端点过多、数据字段固定、请求难以组合等问题，且 HTTP 请求-响应模式要求手动打包请求。GraphQL 允许组件声明所需字段，Relay 自动合并多个组件的数据需求为一个高效请求，并处理缓存。但柳成荫和 Rio 也提到，实现 GraphQL 需要后端支持图状数据查询，对中小团队有挑战，可能需要 REST 适配层过渡。

[35:08](https://lib.pan.icu/cae99ea1-517d-47a8-af71-3bc088063dc8?t=2108000)

### Flux 架构与传统的 MVC 有什么不同？为什么 Facebook 要发明它？

柳成荫指出，Flux 主要解决 MVC 中因事件链式触发（cascading）导致的不可预测行为。Flux 采用全局 action 和单向数据流，确保每次操作产生确定的状态变化，不会意外触发连锁反应。Rio 补充这保证了信息流向清晰。这对于 Facebook 这样有数百名工程师协同的大型应用尤为重要，能显著降低复杂度。

[35:00](https://lib.pan.icu/cae99ea1-517d-47a8-af71-3bc088063dc8?t=2100000)

## Key moments

- **[0:00] 开场**
  - [1:46] Q: 柳成荫为什么参加React.js Conf 2015？
  - [3:16] 从Backbone迁移到React的过程并不痛苦，柳成荫的公司非常享受这个过程
- **[8:15] Backbone迁移**
  - [8:25] Backbone在production上性能不佳，内存管理需手动操作易导致内存泄漏
  - [10:06] Backbone的view重用复杂，state分散在DOM中导致代码难以看清全貌
  - [11:34] Backbone不opinionated的设计导致团队协作时缺乏一致的mental model
- **[14:22] 虚拟DOM**
  - [14:22] Rio总结Backbone的核心问题是封装层级不够，数据分散在DOM和JavaScript中
  - [15:51] 柳成荫举例说明Backbone中手动操作DOM的繁琐，而React通过Virtual DOM抽象解决了性能与可维护性问题
  - [17:21] React通过Virtual DOM和diff算法实现自动DOM更新，使开发者能写声明式代码
  - [19:25] 吴涛解释React通过Virtual DOM与真实DOM脱节，通过diff最小化DOM操作开销
  - [20:29] David Nolan将Virtual DOM称作‘DOM virtual machine’
  - [21:06] Rio对比：传统前端开发手动管理DOM state，React只需声明最终状态
- **[32:06] Flux架构**
  - [32:06] Rio介绍Flux架构，提供了一种基于React的前端数据流管理模式
  - [33:29] 柳成荫回顾React最初发布时被批reinvent the view，但后来证明有效
  - [34:29] Flux通过全局dispatch和禁止cascading effects，实现单向数据流，使应用行为更可预测
  - [36:32] Rio体验Reflux后，前端应用逻辑变得有条理和清晰，边界明确
  - [37:45] 柳成荫指出Flux只是一个理念，可以用Backbone model实现，对大型应用才有意义
  - [39:23] React支持isomorphic渲染，可在服务端生成初始页面，提升SEO和加载速度
- **[45:41] JSX**
  - [47:01] 吴涛认为JSX是一种进步，通过类模板语法描述数据模型，而非历史倒退
  - [49:56] JSX使React中子组件重用变得极其简单，只需导入并像标签一样使用
  - [50:24] Facebook内部长期使用XHP在PHP中写HTML标签，为JSX的概念验证
  - [51:06] Rio看到Facebook用XHP实现任意自定义标签组件化，认为是划时代的进步
- **[53:01] React Native**
  - [53:14] 柳成荫对比React与Angular：React积极拥抱ES6等原生特性，Angular则在创造自己的封闭世界
  - [53:33] React在新版本中去掉mixin支持，遵循ES6标准的变化
  - [55:33] Rio介绍React Native：用JavaScript写应用，直接渲染为平台原生UI组件
  - [57:44] 柳成荫强调React Native的理念是‘learn once, write everywhere’，而非write once, run anywhere
  - [58:34] 柳成荫分享iOS的auto-layout布局痛苦，认为Web的box model简单直观
  - [1:01:13] React Native用JavaScript实现了CSS Flexbox布局模型，解决原生布局难题
- **[1:34:19] Relay与GraphQL**
  - [1:34:19] Rio吐槽REST API的诸多问题：端点过多、返回数据固定、组合性差、batch请求困难
  - [1:40:43] 柳成荫认为Relay更主要是帮助Facebook这样的大公司管理数据获取的复杂度
  - [1:41:32] 柳成荫预测会出现Relay adapter，让传统REST API支持GraphQL查询
  - [1:42:27] Q: 没有图数据库的后端如何支持Relay和GraphQL？
  - [1:43:59] 柳成荫指出GraphQL更是一种协议，真正的实现取决于后端的软件
  - [1:45:45] 柳成荫认为REST adapter对推广GraphQL技术有益
- **[1:53:21] 总结**
  - [1:53:21] 柳成荫评价React.js Conf 2015是他参加过最好的会议之一，内容hardcore CS，React前景乐观
  - [1:54:48] Q: 柳成荫的公司近期会采用React Native吗？

## Speakers

- **Rio** (host)
- **吴涛** (host)
- **柳成荫** (guest)

## Topics

Web 开发

## Mentioned

AppCelerator (company), Apple (company), Facebook (company), Google (company), AngularJS (product), Backbone.js (product), Ember.js (product), Flux (product), GraphQL (product), JQuery (product), JSX (product), PhantomJS (product), React (product), React Native (product), Reflux (product), Relay (product), TAO (product), Titanium (product), XHP (product), immutable.js (product)

## Transcript

### 开场

**Rio** [0:00]
大家好 ， 欢迎收听第 17 期的 《 内核恐慌 》， 我是 Rio。

**吴涛** [0:04]
我是吴涛 。

**Rio** [0:05]
呃 ， 今天我们请到了一位嘉宾 ， 哈 ，他叫 Willow。

**吴涛** [0:10]
对 。

**Rio** [0:10]
我来跟大家打个招呼吧 。

**吴涛** [0:11]
大家好 ， 我是 Willow， 嗯 ， 又可以跟 Rio 和吴涛插科打诨 ， 非常开心 。

**Rio** [0:19]
对 ， 啊 ， 为什么要说 " 又 " 呢 ， 就是如果大家听过我们 —— 呃 ， 我主持的另外一档节目 《IT 公论 》 的话 ， 就知道 Willow 已经在那边做过两三次的嘉宾了 。

**吴涛** [0:28]
可 、 可是我好像没有和 Willow 直接上过 ， 呃 ——

**Rio** [0:34]
对 。

**吴涛** [0:34]
对 ， 我们没有上过 。

**Rio** [0:37]
你们没有上过 ？

**吴涛** [0:38]
我以为一开始就这么 A 了 。

**Rio** [0:42]
不过其实这是我们 —— 就是 《 内核恐慌 》 这期节目第一次邀请嘉宾吧 ， 对 。

**吴涛** [0:46]
对 。

**Rio** [0:47]
之前曾经邀请过一位嘉宾 ， 后来被 《IT 公论 》 抢走了 。

**吴涛** [0:50]
没错 ， 就是王成荫 。

**Rio** [0:52]
所 、 所以 ， 呃 ，Willow 你还是来我们的 " 处女嘉宾 "。

**吴涛** [0:55]
哦 ， 非常荣幸 ， 非常 —— 不是 ，I don't know about the " 处女 " part，但是 ，但是 ——

**Rio** [1:00]
I guess。 啊 ， 今天请 Willow 来呢 ，是要聊一件跟前端开发有关的事情 ， 哈 ，因为刚好 Willow 最近 —— 应该是前天吧 ， 前天和上前天 ， 对吧 ？

**吴涛** [1:11]
啊 ， 上个星期 。

**柳成荫** [1:12]
28 号 、29 号吧 ， 应该是 。

**Rio** [1:14]
对对 ， 然后去参加了这个 Facebook 搞的 —— 哎 ， 现在已经不算 Facebook，他们已经独立出来了吗 ？ 还是怎么样 ？

**吴涛** [1:20]
还是 Facebook， 都是 Facebook。

**Rio** [1:22]
还是 Facebook，OK。

**吴涛** [1:23]
OK。

**Rio** [1:23]
啊 ， 就是 Facebook 他们有一个开发者的小型的一个会议吧 ，是讲一个叫做 React 这么一个前端开发的技术 。 然后刚好 Willow 去了现场 ， 参加了两天的会议呢 ， 然后我们就趁热打铁 ， 邀请他来跟我们分享一下他所的所见所闻吧 。

**吴涛** [1:38]
对 ，其实 Willow 你是为什么可以去参加 ， 或者说你是出于什么样的动机去参加 React.js 的 conference 呢 ？

**柳成荫** [1:46]
嗯 ， 呃 ， 如果你看前端开发的 ， 啊 ， 发展的话 ， 你会发现 ， 啊 ， 去年和前年是非常激动的两年 。

因为我们 ， 啊 ， 最开始大家写 Pure JavaScript， 然后后来又写 JQuery， 然后再到 Backbone 引进了 ， 啊 ， 比较 ， 嗯 ， 具体的 structure。

嗯 ， 前端的开发好像到那里就有一点停滞 。 啊 ，在这个时候呢 ， 又出现了 Angular， 然后去年又出现了 React。

实际上， 对于前端开发者来说 ， 整个前端世界是发生了巨变的 。 嗯 ，而 React 是促使这些巨变的一个代表之一 。

啊 ， 我们去年， 啊 ， 我们自己公司去年在 ， 啊 ， 考虑新的技术的时候呢 ， 把 React 纳入了 ， 啊 ， 我们想要使用的范围 。

嗯 ，在过去的六到八个月 ， 我们都有在积极地 ， 啊 ， 把以前的东西给 ， 啊 ， 转移到 React 上 。 我们之前是写了一个 Backbone app， 然后我们现在在 ， 啊 ，migrate 它去 ， 啊 ，React。

作为一个 React 开发者本身 ， 然后再作为一个 ， 啊 ， 这个技术的一个爱好者 ， 嗯 ， 我也觉得非常荣幸有机会去 React Conf， 去 ， 啊 ， 这个 community 看最新的东西 ， 啊 ， 然后从其他人身上学到一些东西 。

**吴涛** [3:16]
OK。

**柳成荫** [3:16]
对 。

**吴涛** [3:16]
那你刚才提到说整个 app 要从 Backbone 迁移到 React 上面 ， 那待会我们也可以讲一下整个迁移过程是不是的 、 的痛苦程度有多少 。

**柳成荫** [3:26]
没问题 。其实是一个非常有意思的一个过程 ， 相对于像 Angular 这样的庞大的 framework 来说 ，React 实际上非常的轻巧 。

然后正是因此 ， 这个 migration 没有很多人想象的会那么痛苦 。 我们 ， 我们非常非常享受这个过程 。

**Rio** [3:46]
啊 ， 我 、 我忘了介绍了 ， 就我们自己都很熟悉了 ，但是忘了给 —— 有些听众朋友可能还 ， 呃 ，不 、 不 ， 就第一次 ， 呃 ， 听到 Willow 的声音的话 ，Willow 你还要先介绍一下自己 ， 哈 。

你是在湾区的做前端开发 ， 对吧 ？

**柳成荫** [4:01]
OK， 嗯 ， 呼 。 哎 ， 我在 《IT 公论 》 的时候也没有介绍自己啊 。

**吴涛** [4:07]
对 ， 我觉得 ， 哎呀 ，不知道 Willow 的朋友 ，不知道 Willow 是谁的听众们可以回去听 《IT 公论 》。

**Rio** [4:13]
第一期是有介绍的 。

**柳成荫** [4:15]
哈哈哈 。 呃 ， 我是 ， 我在湾区生活了三年， 然后我们 ， 我一直在 ， 啊 ， 这家叫做 Backbone 的 ——sorry， 我在湾区生活了三年， 然后一直在一家叫做 Backbone 的公司 ， 啊 ， 做 software engineer。

啊 ， 我很 focus 在 ， 啊 ， 前端开发上 。

**Rio** [4:36]
嗯哼 。 然后我要 、 我要 、 要给你们公司做什么负面宣传了 ， 打印 ， 哈 。 就是 Backbone 这家 ， 可能在外界最知名的就是什么它的投资人， 对吧 ？

**柳成荫** [4:47]
Well, whatever, that's—that's save that for later.

**Rio** [4:50]
Uh, OK.

**柳成荫** [4:51]
What we're doing recently is very exciting, I'm just saying, OK?

**吴涛** [4:54]
投资人是谁 ？Lady Gaga？ 还是 ——

**柳成荫** [4:57]
对对对 。

**Rio** [4:57]
呃 ， 对 ， 没错 。

**吴涛** [5:00]
可以帮我要一个签名吗 ？

**柳成荫** [5:02]
她只是 ， 她只是小 —— 她只是小 、 小 、 小股东啊 。 啊 ， 签名 ， 哎哟 ， 她 、 她签我脸上了 ， 她亲了我 。

**Rio** [5:12]
好 ， 下次来亲我一下 。 不 ， 应该是你下次她来 ， 你亲她一下， 这样你就和 Lady Gaga 亲上了 。

**柳成荫** [5:18]
哦 ，OK。

**吴涛** [5:19]
OK。

**Rio** [5:20]
你看 ， 多机智的一个朋友 。

**柳成荫** [5:22]
耶 。

**Rio** [5:23]
啊 ， 对 ， 所以 ， 呃 ， 说回来 ， 哈 ， 球员 。 所以 Willow 是一个在湾区 ， 呃 ， 工作的这个软件开发者 。

**吴涛** [5:30]
对 。 然后 Willow 最有名的一个作品是 ， 呃 ， 或者说如果你跟 Willow 的曾经产生过什么交集的话 ，也许是你用过他写的一个插件 ， 呃 ， 叫做 WhatFont， 就是用来检测网页上某一部分被显示出来的文字所实际采用的字体的插件 。

**柳成荫** [5:52]
我们之前有一期 《IT 公论 》， 啊 ， 探讨完那个产品 。 如果大家有兴趣的话 ， 可以回头听那个 podcast。 嗯 ， 这个产品已经 、 已经 、 已经在上线很多年了 ， 所以说 ， 呃 ， 所以说我也 、 我也很期待能够有新的 ， 呃 ， 作品拿出来给大家用 。

然后我也在积极地 、 积极地 、 积极地做这方面的工作 。

**Rio** [6:13]
嗯 ， 很好 。 啊 ， 所以你看 Willow 在湾区就有比较方便的这种机会去参加到各种各样比较高大上的技术会 、 会议 ， 哈 。

这种的话 ，不在湾区其实真的蛮难的 ， 我觉得 。

**吴涛** [6:27]
是 ， 呃 ， 就像欧洲很多 conference 都是在各个城市晃来晃去 ， 它很少会有这种 ， 比如 ， 呃 ，因为 。

**Rio** [6:35]
扎堆的现象 。

**吴涛** [6:36]
扎堆的现象 ， 对 。 比如说 ， 呃 ，React.js Europe conference 将在 7 月份举行 ，在 ， 呃 ， 欧洲巴黎 。 然后 PyCon Europe 更是 、 更是每一年都要换一个城市 。

然后去年应该是在阿姆斯特丹吧 ， 我没记错的话 。

**Rio** [6:54]
嗯哼 。

**吴涛** [6:54]
然后 。

**Rio** [6:55]
还好啊 ， 欧洲交通方便嘛 。

**吴涛** [6:57]
我不觉得 。

**Rio** [6:59]
是吗 ？ 我觉得还可以 。

**吴涛** [7:00]
嗯 ，不管去哪都要 、 都要订机票 ， 然后可能要 、 要 、 要去上 、 去上那个国家的网站买火车票什么的 ， 就很麻烦 。

不像 。

**Rio** [7:12]
离欧洲大一统的理想还比较远 ，是吧 ？

**吴涛** [7:14]
嗯 ， 对 。

**柳成荫** [7:16]
之所以 React Conf， 呃 ，在欧洲会在巴黎 ，是因为 ， 啊 。

**Rio** [7:20]
那个主 、 那个什么 ， 主开发者之一 ， 那个人叫什么 ，Christopher？

**柳成荫** [7:24]
Yeah, Christopher，他是 。

**Rio** [7:26]
他是法国人吗 ？

**柳成荫** [7:27]
Right, exactly. Yeah.

**吴涛** [7:28]
对 ，他讲 、 他讲英语的时候有非常强的那个法国口音 。

**柳成荫** [7:32]
Right.

**Rio** [7:33]
我还专门去查了他是哪国人的 。

**吴涛** [7:35]
我也有 。

**Rio** [7:36]
我现在是太难受了 。

**柳成荫** [7:37]
哈哈哈 。Her last name is Chaton, 这个很明显了 。 嗯 ， 那挺好的 。 就 、 就是 ， 我自己反映一个很大家很开放的态度啊 ，其实我说英语也有口音啊 ，但是这个并不会成为 ， 呃 。

**Rio** [7:49]
不影响工作 。

**柳成荫** [7:50]
对 ，exactly。 所以我也很看到她能够 ， 呃 ， 呃 ，host 这个 conference，也是 validate 大家都能 ， 这个英语这个事情不是那么重要嘛 ， 所以是个很好的事情 。

**Rio** [8:02]
嗯哼 ， 很赞 。

**吴涛** [8:03]
其实 、 其实 Willow 在我们三个人里面已经是最没口音的一个了 ， 我觉得 。

**Rio** [8:08]
对啊 。

**吴涛** [8:09]
嗯 。

**Rio** [8:10]
摸爬滚打的最久的 。

**吴涛** [8:12]
Anyway, churr。 还是回到 、 回到 、 回到 。

**Rio** [8:15]
呃 ， 回到这个正题吧 。 就说 ， 呃 ，其实我们可以先回顾一下在 React 之前的那些框架 ， 会有一些什么样的 ， 就会有 、 有些什么样的选择 ， 会有什么样的问题吧 。

### Backbone迁移

**Rio** [8:25]
就 Willow 你们之前是用这个 Backbone， 对吧 ？

**柳成荫** [8:27]
对 ， 没错 。

**Rio** [8:28]
呃 ， 你们在实际使用中的话 ， 就说刚才你也提到你们在往这个 React 迁移嘛 。 那么 ， 那你们就说在 Backbone 的实际使用中遇到一些什么样的问题 ， 然后迁移到 React 会比较好的解决呢 ？

**柳成荫** [8:41]
嗯 ，有两方面的问题啊 。 一方面是在 。

**Rio** [8:46]
嗯 ？

**柳成荫** [8:47]
你真正在 engineering 方面会问到一些 、 遇到一些问题 ， 然后你在 production 上会遇到一些问题 。production 上的问题其实蛮简单的 ， 就是 performance。

啊 ， 这个一 、 一 、 一个 framework 它到底能有多快 ， 渲染得多快 ， 啊 ， 交互能力这些东西是非常好客观评价的 。

然后， 啊 ， 你如果上网搜的话会看到很多关负面的关于 Backbone 的 ， 呃 ， 一些评测显示 。 然后我们自己在 production 上也遇到了这些问题 ， 我们网站并不算快 。

啊 。

**Rio** [9:18]
嗯哼 。

**柳成荫** [9:18]
然后在 memory 上也非常难 ， 啊 ， 管理 。 这个 memory 呢 ， 实际上是跨了这个 production and engineering。 因为 ， 啊 ，Backbone 的 ， 呃 ，memory management 就好像你在原来做 iOS 开发是那个你要 manually return things, you know, like 你要 manually manage them。

**Rio** [9:37]
手工管理那一层 。

**柳成荫** [9:38]
对 ， 所以 、 所以 ， 啊 ， 非常容易出现 memory leak。 那整个程序记忆在 render 上会慢 ， 然后在 memory 上会 leak 的话 ， 那你的 performance 就 、 就非常不乐观是不是 ？

这是 production 上的问题 。engineering 上的问题呢在于 ， 啊 ， 关键对于我们来说是代码的可重用性和可管理性 。 啊 ，在重用性上的问题 ， 主 、 主要来说就是 view 的 ， 呃 ， 重用性 。

实际上要重用一个 view 在 Backbone 中还其实蛮 、 蛮 、 蛮复杂的 。 因为 ， 啊 ， 你要在那个 ， 啊 ，view 里面 ，在 、 在你的 template 里面给这个 subview 腾出一个空间 ， 选一个 container， 然后在你的 render function 中要 initialize 那个 ， 呃 ，excuse me，subview， 然后把 subview 切进来 。

这 、 这 、 这一系列过程对于开发者来说还是一个蛮 、 蛮头痛的事情 。 所以正因为如此呢 ， 你会看到 ， 啊 ， 很多人不会去重用 。

啊 ，在代码的可管理性上关键呢是 ， 啊 ，其实 view 它本身并不 、 并不管理它所有的 state。 很大一部分程度上 state 是在 DOM 里头的 。

你知道我们有时候 utilize class，utilize data， 啊 ，props 这样的 ， 这样 DOM 的 element 去管理你 view 的 state。 啊 ， 就导致呢 ，在大家看这个 view 的时候并看不到全貌 ，不知道这个 view 到底能够做什么事情 ， 会做什么事情 。其实你在你看那个 view 的时候是很难看出来的 。

这就 ， 啊 ，在多人合作的项目上， 或者是说你返回到你多年之前写的 app 的时候 ， 就会是个很大的问题 。

啊 ， 这是我们 ， 啊 ， 用 Backbone， 啊 ， 两三年的时间里所遇到两个方面的问题 。

**吴涛** [11:34]
我觉得这可能跟那个 ， 呃 ，Backbone 的设计理念有关系 。Backbone 毕竟它强调的是它所提供的功能只是最 ， 呃 ， 基本最 、 最 backbone 的那一部分 。

所以你可能不得不在很多地方要显式地去 、 去 、 去 ， 呃 ， 宣告一些东西 。 然后你需要告诉 ， 呃 ， 你需要显式地把逻辑写出来 。

而如果你需要显式地写出来的话 ， 那每个人写的 ， 呃 ， 逻辑可能会不一样 。 嗯 ， 你说你 。

**柳成荫** [12:09]
这 、 这 、 这的确是一方面的问题 。 对 。

**吴涛** [12:11]
对 ， 你 、 你说你直接看 ， 无法直接看到 view 想要干什么 ， 那其实原因之一也就是它没有一个 default 的 、 的 、 的 、 的 、 的 、 的 behavior 可以让你去 ， 可以一眼让你猜到它要干什么 。

**柳成荫** [12:26]
嗯哼 。Backbone 既好又导致这个问题的一方面就是 ， 啊 ， 它不是很 opinionated。 啊 ， 我们确实在总结我们的 Backbone 的 ， 啊 ， 经验的时候有提到这点 。在一个团队协作的范围 ， 呃 ， 中， 不 opinionated 实际上是一个很麻烦的事情 。

因为大家可能写东西会用不同的方式 ，也不是说 ， 啊 ， 各种方式哪个好哪个坏 ， 关键是协作上来说 ， 啊 ，有相同的 mental model， 啊 ， 会更方便一点 。

嗯 。

**吴涛** [12:59]
不管好坏 ， 只要一样的话 ， 那维护起来的成本可能更不 ，也不是维护起来的成本 ， 就是沟通起来的成本会小一些 。

就如果你用 Ember.js 或者是 Angular 之类的比较 ， 呃 ，有自己的一套使用哲学的框架的话 ， 你会比较 ， 呃 ，有一个大致的概念 ， 就是这件事情怎样做才是符合这个框架的理念的 。

但是 Backbone 则比较平淡 ， 或者说比较 ， 呃 ， 给了你太多自由权 ， 然后就会导致会有沟通上面的问题 ， 我是觉得 。

**柳成荫** [13:31]
嗯哼 ， 确实有这样的因素在 。 啊 ， 可是当我们在看就是像 Ember 这样的 framework 的时候 ， 它相对于 Backbone 是一个比较小的地景 ， 对我们来说 。

啊 ， 确实它在 Backbone 的每一个方面 ，Backbone 所设计的每一个方面 ，不管是 router 还是 view templating， 它都有相当大的进步 。However， 它所 fundamentally 它们的 、 它们的框架的理念 ，MVC 的理念是完全一致 。

这也是为什么我们在考虑 ， 啊 ， 更新我们的 ， 呃 ，framework 的时候 ，并没有做太 ， 对 ， 对 Ember 并没有做太多的考虑 。

因为 ， 啊 ， 如果你计算时间的 。

**吴涛** [14:13]
所以你不是从一种 MVC 换到了另一种 MVC， 只不过另外一个 MVC 更重量级一点 ， 更 、 更 opinionated 一点 。

**柳成荫** [14:20]
没错 。

**Rio** [14:22]
OK。 所以刚才 Willow 你讲到提到像 Backbone 你们做的时候 ， 就是我 、 我 、 我感 ， 我根据你的描述 ， 哈 ， 我感觉出来有几个比较核心的问题 。

### 虚拟DOM

**Rio** [14:31]
就一个是说这个叫什么封装的层级不够 ， 就说它封得太散了 。 比如说你很多有些那个 ， 呃 ， 数据是在 DOM 里面的 ，有些数据可能是在这个 JavaScript 的那个数据结构里面的 ， 对吧 ？

就可能是一个 ， 还有你说那个 view 不能在同一个地方一眼看出来它的相关的那一部分是怎么样 。 这个其实是在 ， 啊 ， 你们在工程上的话 ， 就是没有把这些相关的部分很好地就是 encapsulate 起来嘛 。

**柳成荫** [14:56]
嗯哼 ， 没错 。 因为这个 、 这个主要是因为 DOM 这个事情就太 、 太 、 太他妈操蛋了 ， 你知道就是这样 。

啊 ， 大家 、 大家都明白我为什么这么说 。 因为 ， 呃 ， 呃 ，DOM 的问题首先 ， 呃 ，API 很烂嘛 ， 这个 JQuery kind of, you know, sort resolve that problem kind of。

啊 ， 然后， 啊 ， 关键的因素在于说 performance 太烂 。 啊 ，因为 ， 呃 ， 这是历史 、 历史因素 。

**Rio** [15:25]
因为 DOM 的 ， 对 ， 你跟 DOM 交互的话肯定就是有这个所谓 overhead 比较 、 比较高嘛 。

**柳成荫** [15:31]
对 。 嗯 ， 实际上你如果你真正去 compare Backbone 跟 React 的话 ， 最关键就是它们怎么去处理这个 DOM， 你怎么去处理 DOM 这个事情上不一样 。在 Backbone 里头 ， 啊 ， 如果你要追求 performance 的话 ， 就如果 、 如果说你 、 你不 care performance 的话 ， 那是 totally different story。

但是如果你就是在意真正可用的东西 ， 它不是 、 不是好用 ，是可用的话 ， 你一定要在意 performance。 然后， 啊 ， 就导致说你的 DOM 的 ， 啊 ， 操作都要很小 ， 非常小 。

比方说 ， 啊 ， 如果我要写一个 ， 啊 ， 呃 ， 选项的那个列表 ， 一个用户 。

**Rio** [16:13]
嗯哼 。

**柳成荫** [16:13]
去点一个选项 ， 然后那个选项要变成红色 。 这么一个小小的功能 ，在你的 Backbone view 中， 你一定是会 manually 把这个 class 给 ， 啊 ， 从其他的 element 上移除出去 ， 然后加在这个 target 的 ， 啊 ， 这个 、 这个 ， 啊 ，element 上的 。

就这么小小的一点操作 。

**Rio** [16:35]
你要遍历一遍 。

**柳成荫** [16:37]
就 、 就导致你的那个这个 state 就从 view 上 loose 掉了 。 因为你那个 state， 你 、 你整个 state 是在那个 DOM 里的那个 active class 这个 、 这个 、 这个因素上的 。

然后但是你又不可能说每次都把这个列表重新给 render 一下 。 我 ，you know， 这就回到我们说的 performance 上面 。 对于用 、 对于那个开发者来说 ， 如果你不需要去担心这么小小的这种细节操作 ，而是描述清楚你到底这个 view end result 是怎么样 ， 那 、 那 、 那你的 code 就会清楚很多 。

可是因为 performance 的因素 ， 你必须得到这么到那个细节的小的程度去操作它 ， 就导致你不能够 ， 啊 ， 每次都 rerender。Backbone 的时代就是这样子的 。

但是 ， 啊 ， 然后这就是 React 的 magic happens。Where it happens, magic happens。 啊 ，在 React 的 conf 里头 ，Tom， 啊 ，who is the product manager， 啊 ，有提到 ， 啊 ，Facebook 内部 ， 啊 ， 去做这个 ， 去 、 去 ， 啊 ，initialize 这个 project 的动机 ， 就有提到说他们很想要 ， 啊 ， 啊 ， 把这个 DOM 这种细小的 DOM， 啊 ， 操作隔离出来 ，abstract out， 就像刚刚 Rio 说的 encapsulate。

啊 。

**Rio** [17:57]
嗯 。

**柳成荫** [17:57]
但是他们担心 performance， 所以他们做了 performance 的测试 。 实际上 performance 的测试结果比我们所要预想的都 ， 啊 ， 乐观很多 。

实际上 DOM 没有那么烂 。他们的原话是 ， 啊 ， 我不记得是 IE9 还是 IE10 才会非常烂 。Well, we all know that, like, that's not supposed to。

**Rio** [18:16]
对 。

**柳成荫** [18:16]
But, uh, um。

**Rio** [18:19]
对 ， 这是一个流 ， 对 ， 这是浏览器相关的毫无疑问 。

**柳成荫** [18:23]
对 。 啊 ， 所以但这是在 、 在比方说 ， 啊 ，modern Chrome 中如果你就是不停地 rerender 的话 ， 实际上也没有那么烂 。

可是 。

**Rio** [18:32]
嗯哼 。

**柳成荫** [18:33]
Of course we want better performance,right? 所以他们 。

**Rio** [18:37]
对 。

**柳成荫** [18:37]
又 ， 啊 ， 知道 ， 脑洞大开的 ， 啊 ， 想把这个 DOM 这个事情整个给 encapsulate， 整个给 virtualize。 啊 。

**Rio** [18:47]
嗯 。

**柳成荫** [18:47]
所以开发者就完全就不去操作这个 DOM， 然后通过 ， 啊 ，React 本身的一套算法 ，React 会 ， 啊

， 试图发现两个 state 之间的区别 ， 帮你自动地去 update， 啊 ， 真正的浏览器的 DOM。 啊 ， 这就移除了这个 performance 的 、 的问题 ， 从而回过头来 ， 啊 ，enable 了开发者去写更 ， 啊 ，descriptive、 更 declarative 的 code，而不是 ， 啊 ， 直接告诉浏览器去做什么 。

**Rio** [19:25]
对 。

**吴涛** [19:25]
对 ， 这里就提到有一个就是 React 它这个 、 这个 、 这个新的这种前端的 ， 它也比较有框架吧 ， 这个工具 。

它最核心的一点就是说 ， 它本身是和浏览器的 DOM 是脱节的 ， 就是它没有一个很就所谓的 type coupling 在里面嘛 。

就是它 render 出来的结果并不是得到的一个真正的浏览器的 DOM，而是一个所以他们讲的一个虚拟的 DOM 嘛 。

**Rio** [19:47]
对 ，virtual DOM。

**吴涛** [19:48]
然后它 ， 对 ， 然后他们再有做了这么一个这个 、 这个 diff 这一层 ， 然后再去说怎么用最小的代价使得浏览器里面现在有的那个真实的 DOM 能够变 、 变成你这个 virtual DOM 需要的形状 。

这样的话就可以尽量减少 ， 啊 ， 这个 DOM 那边的交互的开销嘛 。

**Rio** [20:08]
对 。

**吴涛** [20:08]
当然这个的前提假设就是说 ， 这个浏 、 你跟真实的浏览器 、 真实的 DOM 的交互是一个比较高成本的 。

啊 ，但是在一个现代浏览器 、 现代的 JavaScript 解析器的情况下， 它的那个 JavaScript 内部的执行和解析的速度是非常快的 。

所以要解决这两个之间的差异的话 ， 它就通过这种做 、 做 diff 的方法来实现了 。

**Rio** [20:29]
嗯 。

**柳成荫** [20:29]
对 ， 没错 。 啊 ， 很有意思的是呢 ， 呃 ，David Nolan 是那个写叫做 David Nolan 是 Closure Script 的作者 ， 然后他们有把 React 给 ， 啊 ， 写了一个 Closure Script 的 React 叫做 Ohm。他给了一个 presentation， 然后他不把 virtual DOM 叫做 virtual DOM，他把 virtual DOM 叫做 DOM virtual machine。

这是个非常小的差异 。 啊 ，但是我想他 、 他想要说的是说 。

**Rio** [21:00]
OK。

**柳成荫** [21:00]
这个 virtual DOM 实际上是非常 ， 啊 ，powerful 的 ， 这样 。

**Rio** [21:06]
嗯 ， 然后这个 React 它的可能在思维哲学上我觉得有一点很大的不同 ， 就是说传统上我们像用这个 Backbone 之类的 ，其实是你是在你是把 DOM 当成一个巨大的 state， 然后你是在手工地去管理那些 state， 对吧 ？

**吴涛** [21:21]
嗯哼 。

**Rio** [21:23]
然后就可能就很多的操作就是你要可能要手动去添加什么 ， 呃 ， 这个 、 这个 event handler 啊 ， 然后它发生什么事情你要又记得把它取掉 ， 然后要做一些 、 呃 ， 相应的修改 。

就是整个来看这个交互的流程和这个 、 这个你的这个 view 其实是混杂在比较 、 比较 ， 嗯 ， 叫做什么 ， 怎么那个叫什么 ， 犬 、 犬牙交错 ， 对吧 ？

哎呀 ， 终于想起这个词了 。

**吴涛** [21:48]
难为你用这么复杂的成语 。

**Rio** [21:50]
对 。 但是像 React 这种思路的话 ， 它用那个 virtual DOM 的思路其实刚才 Willow、Willow 已经 ， 啊 ， 解释过一下， 就说它其实是放弃了这一条 ， 就说我们不要去手工去 、 去改那个一个浏览器里面 DOM 的每一个小细节 ，而是说我们你只要告诉我你需要让它达到什么样的状态 。

当然这个需要你说你是一次性的描述性的状态嘛 。

**柳成荫** [22:14]
对 。

**Rio** [22:15]
然后这样的话 ， 我就只需要说 ， 诶 ， 那我不需要考虑怎么去变到那个状态 ， 我只需要声明我最后要达到什么样的状态就可以了 。

**吴涛** [22:24]
嗯 。其实这个让我想起 Backbone 的一个 、 一句宣传口号就是 "Get the truth out from your DOM." 嗯 ，但实际上， 呃 ， 它的这个口号所指的是要把 ， 呃 ，其实就是很简单的要把 DOM 所要呈现的那层那些数据 ， 呃 ， 作为你的 model 从 DOM 里面抽吸出来 。

但 ， 呃 ， 如果沿着这一句宣传口号更进一步研发的话 ， 会我觉得可能最终结果就是像 React 这样 ， 就是将 DOM 作为某种 ， 呃 ， 就像 screen buffer 一样 ， 呃 ， 就是计算出最终需要的 DOM， 然后去更新 ， 呃 ， 它与实际的 DOM 所差异的这一部分 。

这样可能更就是更多的 truth， 呃 ， 被从 DOM 里面 ， 呃 ， 抽吸出来了 。

**Rio** [23:22]
其实它这个思想也不是说 ， 呃 ， 原创性的哈 ， 就是在很多年前做游戏的大家都已经发现有这么一个 ， 就做那种就是电脑游戏的人都已经有这么一个概念了 。

啊 ， 过去游戏有个叫做就是绘 、 绘制图形的话 ，有个所谓的叫做 immediate mode， 就是立即模式嘛 ， 就是你 、 你画什么就在图像就在那个屏幕上出现什么嘛 。

然后后来发现其实这样的话对那个叫什么 ， 对性能其实是不好的 。

**吴涛** [23:51]
嗯哼 。

**Rio** [23:51]
然后后来他们又发现用那个什么 retain mode 的话 ， 你其实可以再让这个游戏引擎去做一些优化 ， 就说把 。

**吴涛** [23:59]
对 ， 你先告诉它下一帧会显应该显示什么 ， 让它 、 它计算出两者的差异 。

**柳成荫** [24:06]
其实在 React 的 conf 上， 啊 ， 没有人提到 ， 啊 ， 跟游戏上的差异 。 所以我有 、 我有点就是自己在想 ，在好奇说到底这个是一个殊途同归呢 ， 还是他们有真正的在那个 ， 啊 ， 游戏开发者身上提取灵感 。

啊 ，但我更倾向于是相信是一个殊途同归的结果 。

**Rio** [24:30]
对 ， 对 ， 我也觉得那个 Peter Hunt，Pete Hunt 他在那个去年的那个介绍 React 的那个会上面他就讲了嘛 ， 就说他们做完发现 ， 诶 ，他们那个做什么 3D 游戏的人好像也是用的同样一套思路啊 。

**吴涛** [24:43]
没错 。

**Rio** [24:44]
就是其实确实是一个殊途同归的一个结果吧 ， 我觉得 。

**吴涛** [24:47]
对 。其实我相信现在的 web app 领域的很多技术可能在 ， 呃 ， 就是古早的 ， 呃 ，3D 技术发展道路上都已经讨论过了 。

**Rio** [24:59]
嗯哼 。

**吴涛** [24:59]
然后有些经验可能也是会需要被 ， 呃 ，backport 过来的 。

**Rio** [25:05]
啊 ， 或者说其实我们把这个 ， 呃 ， 这个 ， 呃 ， 领域放得更宽广一点 ， 就说前端如果不仅限于这个网页或者是一个客户端的 app 的话 ，其实游戏从你从某种意义上来讲也是在 、 在做一个前端的东西嘛 。

**吴涛** [25:21]
呃 ， 我觉得游戏可能最大的差别是它和 ， 呃 ， 它的前端和后端之间的差异 。 啊 ， 它的前端和后端之间没有中间隔着这么巨大的一个互联网的鸿沟 ， 就是它 、 它中间的通讯没有这么大的一个 、 一个 、 一个 、 一个延迟 ， 或者说有这么大的一个协议站摆在那边 。

**Rio** [25:45]
但现在你很多游戏也是这种 ， 哦 ， 叫做网络 ， 就是 network game 嘛 ， 所以其实还是有很大相似点的 。

**吴涛** [25:51]
但那一部分仅仅是用来交互游戏数据的 。 你 、 你的 、 你的 ，yeah， 你的 、 你的 ， 呃 ， 表现层的数据 ， 呃 ， 仍旧是在本地 ， 呃 ， 生成 ， 除非你是在做 streaming，但是 streaming 又是另外一个话题了 。

**Rio** [26:08]
嗯 ， 对 ， 这也是一个问题吧 。React 其实还有一点就是说它是更倾向于你使用所谓的这个 immutable data structure， 就是不可修改的数据结构 。

**柳成荫** [26:20]
这点上我们在 ， 啊 ，conf 上有提到 ， 然后， 呃 ， 顺带说我非常喜欢我在这个 React conf 上我真 、 我真的非常高兴 、 非常激动 。

因为 ， 啊 ， 传统意义上来说前端不是一个很 hardcore CS 的东西 ， 对吧 ？ 你说大家 、 大家一般看前端开发者都有一点小鄙视的意思 。

啊 。

**Rio** [26:41]
对 ， 对 ， 对 ， 对 ， 更加工程导向而不是理论导向嘛 。

**吴涛** [26:45]
对 ， 更加 25 岁以下导向 。

**Rio** [26:49]
哈哈哈哈 。

**吴涛** [26:49]
不要这么黑 。 不不 ， 我又想起来那个 。

**Rio** [26:53]
所以 、 所以但是在这个 conf 上我们有听到很多很有意思的东西 ，其中有一个是 immutable data， 对吧 ？ 啊 ， 我们有一个 、 有一个演讲是 ， 啊 ，Lee Byron 给的演讲在专门说 immutable.js 是 Facebook 的 ， 啊 ，immutable data JavaScript 实现 。

啊 ，他有讲到很多 ， 啊 ， 这个 immutable data 到底是个什么东西 ， 啊 ， 怎么在 JavaScript 上实现的 ， 非常好 。 啊 ，但是 back 到这个 React 上来说的话 ， 之所以 immutable data 是 preferred, not required, but preferred，是因为正因为 React 它的设计方式 ， 整个的 render 的过程 ， 整个的 component 实际上就是 props plus state equal to something。

**吴涛** [27:43]
嗯哼 。

**Rio** [27:43]
这个 equal 是 render function 所做的事情 。 所以如果你的 props 跟你的 state 不变化的话 ， 你的 render result 总是一致的 ， 总 、 总会是一样的 。

**吴涛** [27:55]
对 。

**Rio** [27:56]
虽然说 virtual DOM 会帮助你不去 update 你的 DOM，但是如果你在你 、 你连 render 都 、 连 、 连 render function 都不用去 ， 呃 ，不用去 run 的话 ， 那你就实 、 实 、 呃 ， 就实现了更好的 performance， 然后省下了更多的时间 ， 特别是在大型的 ， 啊 ，application 上 。

但是怎么去判断这个 props 跟 state 有没有改变就变成了一个很大的问题 。 传统的 mutable data 的话呢 ， 就至少是个 ON 的操作 ， 对不对 ？

你 、 你必须得 。

**吴涛** [28:28]
对 ， 你得逐个去比较嘛 。

**Rio** [28:29]
你必须得把整个 object 给变例了 ， 然后如果你要做 deep、 呃 ，deep comparison 的话就更大了 ， 是一个树状结构嘛 。 啊 ，immutable data 实现了 constant time 的 、 的 、 的 comparison， 就是 O1， 对 。

**吴涛** [28:45]
对 ， 你只用判断一个指针吗 ？ 等于说最终 。

**Rio** [28:48]
是一个空间 ， 时 、 时 、 时间跟空间是花在 、 花在其他的部分了 ，但是在这个 render 上就 ， 啊 ， 就 、 就更有帮助 ， 就非常快 。

啊 ， 我们在跟其他的与会者讨论的时候也 、 也 、 也提到很多人就是一开始也没有用 immutable data，但越用 React 你就越觉得啊 ， 这个 totally makes sense， 你知道为什么不用了 ， 对吧 ？

**吴涛** [29:15]
哈哈哈哈 。

**Rio** [29:16]
对 ， 所以 、 所以但 immutable data 这个事情非常有意思 ， 就不是一个传统意义上 JavaScript 人 care 的东西 。 啊 ， 正因为这个对于 immutable data 的 ， 呃 ， 这个 ， 呃 ， 喜好才导致了 Closure Script 也叫 React 的 ， 啊 ， 行列 。

因为 Closure 它所有的 data 本来就是 immutable 的 ， 它是 function language， 然后它所有的 data 都是 immutable 的 。 所以 ， 啊 ， 就很 naturally 它的那个 framework 就很好地利用了这样一个特性 。

啊 。

**吴涛** [29:48]
对 ， 上次我看了一个那个 Ohm， 就是那个 Closure Script 写的的 React 实现嘛 ，他们的性能确实非常了不得的 。 因为刚才讲了嘛 ， 你只要因为在 、 在 Ohm 里面整个就大部分的那些 data structure 都是这个所谓的 immutable 的话 ，他们在渲染的时候就真的只用一逐 、 就逐个走那个 、 那个树状结构 ， 然后判断那个直根节点的那个指针的就好了 。

真是非常 、 非常快速的一个过程 。

**柳成荫** [30:13]
对 。 啊 ， 顺带说在整个这个 conference 中， 啊 ， 我们有提到非常多的 ， 啊 ，performance 的 trick， 怎么样实现更好的 performance。immutable 是其中之一 ， 我们有提到很多其他的东西 。

啊 ， 如果观众听众朋友们有兴趣的话 ， 可以 ， 啊 ， 找到这些 keynote，也可以写信问我 ， 或者我有 ， 或者告诉 Rio， 我们说不定下期可以做更多关于 React 的 ， 啊 ， 更细节更优化的东西 。

**Rio** [30:41]
对 ，不过他们看那个现场那个视频 ， 呃 ， 现在跟大家说一下这个这次的这个 React conf 2015 的所有的视频都在 YouTube 上面有的 ，但是因为现在国内 VPN 也打击得比较严重 ， 能不能看到就不好说了 。

**吴涛** [30:59]
个人 、 个人方法 。

**柳成荫** [30:59]
它不是所有都在吧 ？

**吴涛** [31:00]
好像可以吧 ， 就是我在看 ，因为 YouTube 上有个频道叫做 Facebook， 呃 。

**Rio** [31:06]
Developer。

**吴涛** [31:07]
Developer 的频道 ， 然后这个 channel 上基本上应该你需要的都可以看到 。

**Rio** [31:13]
不 ， 我就说国内的 ， 就是我们听众很多人都在国内嘛 ，他们没有办法去上这个 YouTube。

**柳成荫** [31:19]
这个 、 这个问题我觉得我们要 fact check 一下， 我好像只有它只有三个吧 ， 只有那个 Relay， 它有那 immutable.js 的那 keynote 吗 ？

**Rio** [31:28]
它现在它在逐渐放 ， 它已经放了九个 。

**吴涛** [31:31]
我觉得它应该可能还是在做一些剪辑之类的工作吧 。

**Rio** [31:34]
大家最终是要它要把它全部放上去 。

**吴涛** [31:36]
它没有理由不放出来 ，因为 。

**Rio** [31:40]
对 ， 对 ， 反正一共是有多少个 ， 一共是有多少个 talk 来着 ？ 有两天是 12 个还是 9 个 ？

**柳成荫** [31:46]
Anyways， 啊 ， 就是就是想想 fact check 一下而已 ， 没有 、 没有 、 没有其他意思 。

**Rio** [31:52]
嗯 ，有的有的 ， 这个没不用担心 。 啊 ， 嗯 ， 然后其实说到 React 的这个它 ， 我们传统上一般认为它是在 MVC 里面做的那个 V 的那个角色 ， 对吧 ？

**吴涛** [32:06]
对 。

### Flux架构

**Rio** [32:07]
嗯 ，但是我们传统一个 MVC 的话 ， 那个像 M 和 C 那部分怎么解决 ，其实 ， 啊 ，在相当长段时间内还是没有很好的一个方案吧 。

但是去年年末的时候 ，他们公开了一个叫做这个 Flux 的这么一个一个架构吧 ，也不算是一个 ， 就是一个指导方针 ， 只能说是 ， 就是你怎么去用 React 方式去构建一个传统的 MVC 的这个实现的时候 ， 你要注意些什么问题 。

这个 Flux 我觉得也是一个非常 ， 啊 ， 具有 ， 啊 ， 什么 ， 呃 ， 划时代意义的一个方式啊 。 就刚才你讲那个 。

**吴涛** [32:41]
我真的我怎么记得就是 Flux 出来的时候 ，Hacker News 上有人黑说他们 rediscover 了一个非常古老的 idea， 然后把它 ， 呃 ， 重新包装了一遍 ， 然后改名叫 Flux。

**Rio** [32:53]
但其实在起码在这个前端开发里 ， 它确实是一个挺好的事情 ， 我觉得 。

**柳成荫** [32:57]
啊 ，其实这一点上我跟吴涛所说的 ， 呃 ，有一点类似 。 我至今呢也觉得 Flux 的 idea 实际怎么说 ， 啊 ， 我如果看历史的话 ， 你如果有看 ， 我有看所有的 Flux 的 video 这些东西 ， 你看的话 ，他们最初 Flux 要解决的问题并不是真正的 MVC。

我 、 我觉得他们在最初 ， 啊 ，在 invent 这个 Flux 的时候 ，他们所使用的那个 ， 啊 ， 做事情的方式呢并不是真正的 MVC。

啊 ，但是这 、 这 、 这并不是说就 Flux 就不好 ， 就不是因此 Flux 就这个框架就不对 。 这我 ， 啊 。

**吴涛** [33:37]
嗯哼 。

**柳成荫** [33:39]
还有意思的是在这个 React conf 上， 啊 ， 那些 speaker 反复地提到 ， 啊 ，他们最初发布 React 的时候大家的反应 ， 最初发布 React 是在 JS conf 的 2013 年的 JS conf 上 ，他们的反应都非常 negative， 你知道 ， 就是说 reinvent the view。

**Rio** [33:59]
对 。

**柳成荫** [33:59]
Yeah, we are reinventing the view, we are reinventing the best practices. 嗯 ， 后来 Pete Hunt 甚至给了一个 Rethinking best practice 的 ， 啊 ， 一个 、 一个 speech。 啊 ， 所以 。

**吴涛** [34:14]
嗯哼 。

**柳成荫** [34:16]
上完这个会呢 ， 我也是觉得 ， 诶 ， 大家还是保持一个开放的心态 ，也不需要去黑他或者怎么样 ， 毕竟说我们也不能够就是怎么说 ， 就是墨守成规 ， 一定说之前的东西就是好的 。

如果 Flux 能够解决你所要解决的问题 ， 如果 Flux 能够解决 Facebook 所要解决的问题 ， 你清楚你的问题是什么 ， 我觉得这才是最重要的 ， 对不对 ？

啊 ， 所以 back 到 Flux 上面来说 ， 它实际上跟传统意义上 MVC 有非常多的相似的地方 。 啊 ， 它整个的 dispatch mode， 整个的这个 ， 啊 ，event 的 ， 啊 ， 流程 ， 这个单向的信息的流动 ， 实际上跟 ， 啊 ， 传统意义上 MVC 是非常非常类似的 ，但它有细节上的差异 。

比方说 action 是 global 的 ，dispatch 是 global 的 。 啊 ， 比方说在一个信息没有流完的情况下， 你不能够 initialize 另外一个信息 ， 像这样的细节的差异实际上是 ， 实 、 实际上就 、 就 、 就意味着 Flux 跟传统的 MVC 不一样 ， 特别是在 ， 啊 。

**Rio** [35:21]
对 。

**柳成荫** [35:21]
你知道 ， 比方说如果我们用 Backbone， 啊 ， 如果 model， 啊 ， 触发一个 change event， 这个 change event 的 event handler 是可以再去改变这个 model， 然后从而就产生另外一个 change event， 它有它 、 它有这个 cascading 的这个效果在 。

**Rio** [35:38]
对 。

**柳成荫** [35:39]
Flux 的 ， 啊 ， 它的发明跟这个 cascading 非常有关系 ， 一个重点的原因要他们去 ， 啊 ， 发明这个 Flux 就是不想要这个 cascading， 你看这样细小的一些 。

**Rio** [35:52]
因为太难管理了 。

**柳成荫** [35:53]
You don't know what will happen, like you don't know exactly what will happen,right?

**Rio** [35:56]
对 。

**柳成荫** [35:56]
就好像 ， 就好像 。

**Rio** [35:58]
对 。

**柳成荫** [35:58]
啊 ，React 它本身就 ， 啊 ， 把 ， 呃 ， 想要把那个 code 更 declarative 化 ， 啊 ，Flux 也有这样的目的 ， 就是让 flow 更清晰 ， 每次每次的你的 action 都是导致同一个结果 ， 同一个方向流动 ， 然后你的那个 ， 啊 ， 你不会触发另外一个你所没有预料到的结果 。

这点上， 啊 ， 如果你真的去用 Flux 的话 ， 会发现实际上是非常非常非常有帮助的 ， 对你管理你的 ， 啊 ， 你的程序的复杂度 。

**Rio** [36:32]
对 ， 对 ， 就我 、 我个人感觉就是我之前是在做一些小的这种小的 project 去 、 去尝试用这个 Flux 这种架构嘛 ，但是我具体用的是一个叫做 Reflux 的一个具体的实现啊 ，但是它在那个逻辑上是大同小异的 ， 只是有些细微的 ， 呃 ， 组件上有点不一样 。

我感觉就是有很明显的这个区别 ， 就是说一 、 呃 ， 采用了这个 Flux 这个架构之后， 整个这个前端应用的这个逻辑变得非常有条理和清晰 ， 就知道边界在哪里 ， 然后哪些 ， 呃 ， 数据在哪里管理 。

就最开始的时候你提到像那个用 Backbone 的时候 ，有些数据是混在这个 DOM 里面的 ， 对吧 ？ 这样其实这 、 这如果你用 Flux 这种方式的话 ， 就其实是完全分离开了 。

它有这个所谓的这个 store 的概念 ， 就大约略等同于以前 MVC 里面那个 model 嘛 ，但是说它的 store 里面它有一些具体的限制 ， 刚才比如说你不能说 store 触发 ， 呃 ， 呃 ， 就是 cascading 的东西出来 ， 这样其实然后就可以保证你这个 ， 呃 ， 信息的流向是单向的 。

**柳成荫** [37:32]
对 。

**Rio** [37:32]
这样的话 ， 啊 ， 就可以让你很方便地去把这个所谓的叫做 ， 啊 ，separation of concern 嘛 ， 就是把那些需要关注的点全部分隔开来 、 来做 。

**吴涛** [37:41]
嗯哼 。

**Rio** [37:41]
对这个整个架构是很有帮助的一个 、 一个工具 ， 我觉得 。

**柳成荫** [37:45]
啊 ， 然后 Flux 其实从 Facebook 的角度来说的话 ， 实际上只是一个 idea， 它对你到底说你的 dispatch 是什么 ， 你的 action 是什么 ， 你的 storage 是怎么实现的 ，并没有很严格意义上的 ， 啊 ， 就是管理 。

啊 ， 正因为如此呢 ， 像我们在做这个从 ， 啊 ，React 从 Backbone 到 React 的一个 、 一个迁移嘛 ， 从一定程度上来说 ， 我可以用传统的 Backbone model、Backbone collection 来实现 Flux， 这是可能的 ， 这是完全可能的 。

**Rio** [38:17]
对 ， 对 。

**吴涛** [38:17]
嗯哼 。

**柳成荫** [38:18]
啊 。

**Rio** [38:19]
对 。

**柳成荫** [38:20]
所以就是 again，不要拘泥于书本上的概念 ， 啊 ， 去想一想你所要解决的问题 ， 然后去看一看这个 architecture 到底能不能解决这个问题 ， 啊 ， 才是最重要的 。

啊 ，而且 Flux 可能在一定程度上来说 ， 只有对 ， 啊 ， 大型的 application 才有意义 。 你要想 Facebook 所要解决的问题是 massive scale， 对不对 ？

他们有 hundreds of engineers。

**Rio** [38:44]
对 ， 对 。

**柳成荫** [38:45]
啊 ， 如果你只有一两个人在一个 、 一个程序上工作的话 ， 那或许有更轻巧 、 啊 ， 更便宜的 ， 啊 ， 架构你能够选择 。

**吴涛** [38:55]
对 ， 可能用不上用使用这种就所谓大规模杀伤性武器 。

**Rio** [38:59]
没错 。 哈哈哈 ， 对 。 呃 ， 呃 ，React 还有一个好处哈 ， 就是说这个所谓构建这个 isomorphic 的 JavaScript 应用的情况是比较好的 ，因为它可以 ， 呃 ， 同样的一个 React 组件 ， 只要你构建的正方式稍微注意一点点 ， 它是可以在客户端渲染或者是在客户端 ， 呃 ， 服务端渲染 。

然后在服务端渲染它有一个什么好处呢 ？ 它可以在服务端渲染从最初的那个页面那个结构之后， 你把这个送给浏览器 ， 然后再浏览器再接着 ， 呃 ， 服务端渲染那个部分开始 ， 再完成后面的后续的工作 。

**柳成荫** [39:37]
对 。

**Rio** [39:37]
这个我 、 我不太清楚 ， 就之前有其他类型的框架实现过这种功能没 ，但是就我第一次看到这个的时候觉得还是蛮惊奇的 。

**柳成荫** [39:47]
As far as I know， 啊 ， 如果你小心翼翼地写你的 app 的话 ，是有可能用其他的 ， 啊 ， 框架加上 Phantom JS 这种 headless web kit 来实现相同的功能的 ，是我觉得理论上是有可能的 。

啊 ，但是 。

**Rio** [40:02]
嗯哼 。

**柳成荫** [40:02]
啊 ，在 。

**吴涛** [40:03]
这个太 hardcore 了 。

**柳成荫** [40:04]
Exactly， 就性能上的话会损失很多 ，因为你毕竟要 run 一个 web kit 在你的 、 你的 server 上 。 不过 Phantom JS 发展到现在实际上 。

**Rio** [40:13]
对 。

**柳成荫** [40:13]
啊 ，也解决了非常多的问题吧 。 它 、 它变成了一个 server，而不是你每次都要 ， 啊 ， 付那个 overhead 去 run 这个 ， 呃 ，run 这个 web kit 在里头 。

啊 ， 当然 React 有更大的可能性 ，因为 、 因为毕竟那个 DOM 是 virtualized 的 ， 所以 。

**Rio** [40:28]
对 ， 它不需要去 load 一个真正的 web kit 的引擎 ， 它只需要在 JavaScript 内部去虚构一个这么一个 、 一个 DOM 结构就好了 。

**柳成荫** [40:37]
这次我们在 conference 上有听到很多公司谈到这个他们的应用 ， 大部分的原因呢也不是因为性能 ，而是因为 ， 啊 ，SEO， 很多公司很 concerning SEO 嘛 ， 然后现在 JavaScript SEO。

**Rio** [40:51]
嗯 ， 对 。

**柳成荫** [40:51]
啊 ， 还是一个没能解决的问题 。Surprisingly it's like。

**吴涛** [40:56]
过去中国年了 ， 仍旧是一个老问题 。

**柳成荫** [40:59]
Crazy, it's crazy.

**吴涛** [41:00]
Somehow sorry。

**柳成荫** [41:01]
啊 ，有 、 有 、 有公司 ， 啊 ， 提到说 ， 啊 ， 你知道 Google 有就是有 、 有一个 ， 呃 ，有一个 ， 啊 ，convention 嘛 ， 就是 ， 啊 ， 你如果你的 URL 是一个特别的什么结构的话 ， 它会 。

**Rio** [41:14]
去 bang。

**柳成荫** [41:15]
它会尝试去 fetch 另外一个 URL，which is supposed to be a static page，但是 ， 啊 。

**Rio** [41:21]
嗯哼 。

**柳成荫** [41:21]
According to you know some other companies， 这个功能非常 ， 啊 ， 就是 Google 不怎么在意这个功能 ， 然后经常就坏掉了 ， 所以他们经常 、 经常就是每就是那个 fetch rate 到 drop 到零 ， 你知道吗 ？

这是对于公司来说就是个就是 disaster。他们 、 他们很多公司都是很靠 Google 的流量嘛 ， 如果说有这样一个问题的话 ， 那这个 。

**Rio** [41:43]
对 ， 对 。

**柳成荫** [41:44]
对他们的 business 是 critical 的 ，他们所 、 所以他们就很 。

**Rio** [41:48]
电打西葫芦 。

**柳成荫** [41:49]
非常非常在意这个 isomorphic 的 ， 啊 ， 可能性 。

**Rio** [41:53]
对 ，而且之前 、 之前说那个 Google 说它说 ， 呃 ， 一干一壮是一种方式 ， 通过一种特殊的 URL 结构去说告知 Google 的爬虫 ， 啊 ， 我这个动态网页你可以在另外一个地址找到它的静态版本 ， 这是一个解 、 一个比较传统的解决方案 。

然后 Google 是最应该是去年年末的时候 ， 它是说他们也会渲染 JavaScript 的这个页面的 ， 就是它会当把自己模拟成一个 。

**柳成荫** [42:18]
浏览器 。

**Rio** [42:19]
叫什么 ， 啊 ， 一个浏览器的引擎去解析那个页面的 JavaScript 引擎 ，但是现在问题就是说它没有办法去判断哪些东西是可以点的 ，因为你知道浏览器就是 JavaScript 里面的很多可以点击 、 可以 、 可以 navigate 的项目 ， 它并不像说网页上你是一个 A 的那种这个 anchor 的 tag 可以去很明显地发现嘛 ， 对吧 ？

**柳成荫** [42:39]
对 。

**Rio** [42:39]
所以其实对他们来讲 ， 搜索引擎去 、 去发现这些动态的内容始终是有问题的嘛 。

**吴涛** [42:45]
嗯 。

**Rio** [42:45]
所以在这种情况下， 那种 isomorphic 的还是 ， 啊 ，不可避免 。 然后我的感觉就是说用 React 这种方式来实现 isomorphic 的话 ， 它的难度是相就极大地被降低了吧 ， 就相对于你之前手工地去要么用 Phantom JS 去做一个这个什么 render farm， 手工地去渲染一下 ，因为这个比较高成本嘛 。

然后另外就是说它可以实现这个所谓的无缝迁移 ， 就是你可以随意决定哪一部分是在服务端渲染 ， 然后哪一部分是在 ， 啊 ， 这个客户端渲染嘛 ， 这个是非常不 、 不错的一个 、 一个工具 。

**柳成荫** [43:18]
刚刚 Rio 做了一个非常好的总结 。

**Rio** [43:20]
嗯 。

**柳成荫** [43:20]
啊 ，在实际的应用中，React 可能是 ， 啊 ， 最好的 balance， 就是性能跟可管理性最好的 balance。 如果你的应用场景是你非要需上要需要非常好的 performance 的话 ， 那或许你应该 ， 啊 ， 去看其他的一些选项 ， 比方说用 ， 啊 ， 共用 template，而不是共用 JavaScript logic， 然后在服务器端用服务器的 native language， 啊 ，whatever，you know, PHP or Java， 啊 ， 来写这个 template 的 render， 啊 ，function。

这样 、 这样的话 ， 你要写两个 rendering 的 ， 啊 ，application， 可在 、 在你的工程上是 ， 啊 ， 更麻烦 ，但是如果你要追求性能的话 ， 那是个更好的选项 。React 现在的问题是在于说 ， 啊 ， 即使你在服务器端渲染 ，React 还是会给你做很多不必要的 DOM 的操作 ， 啊 ， 或者是模拟 。

**Rio** [44:20]
啊 ，有 、 有 、 有什么具体的那个情况 。

**柳成荫** [44:24]
啊 ，As a result， 啊 ，有公司 ， 啊 ， 做了测试 ， 然后 As a result， 相对于说就是我刚刚说的那个用 、 用 ， 啊 ，PHP 来 render 这个 template 的话 ， 它的 ， 啊 ， 输出率只有 、 只有那个 template 的大概二 、 呃 ， 啊 ，25%。

**吴涛** [44:43]
哦 ，有差这么多吗 ？

**柳成荫** [44:44]
但是这个是非常可以优化的 ，因为有很多 DOM 的 ， 啊 ， 就是 ， 呃 ， 比方说 event handling 啊 ， 这些东西你都不需在服务器端都没有必要去关联了嘛 ， 对吧 ？

啊 ，因为你最终只需要一个静态的页面 ， 你只需要这个静态的结果 。 啊 ，但是这就是一个 ， 啊 ，open source project 很有趣的地方了嘛 。

哈哈 ， 啊 ，Facebook 本身对这个没有太大兴趣 ，因为他们没有太大这个需求 。 啊 ，但是如果其他公司或者是你 、 你我们听众对此有需求的话 ， 可以去看他们的 source code， 然后， 啊 ， 做对 、 对这个 virtual DOM 做出一些修改来 ， 啊 ， 实现更好的在 server 上 render 的功能 。

我想这个潜力是非常非常大的 ，因为它现在是基本上是没有任何优化的 。

**Rio** [45:27]
对 ， 对 ， 就在这种情况下都还是挺好 ， 我觉得 。 嗯 ， 哎 ， 说到这个 React 在实际使用的时候就会牵涉到一个很有意思的它的写法或者一个语言吧 ， 叫做 JSX 哈 ， 就是什么概念呢 ？

### JSX

**Rio** [45:41]
就是说因为我们是在传统上我们写一个 ， 呃 ， 前端应用的时候 ， 我们是把这个模板和这个数据或者是逻辑完全分离开来的嘛 ， 就模板可能会是用什么 、 什么 moustache 啊之类的一些东西来 、 来用 HTML 来写一个模板 ， 然后留些空 ， 然后让那个 JavaScript 去把模板这个 ， 呃 ，load 进来 ， 然后把那个空填上， 最后 render 出一个静态的页面再发给出去填到页面里面去 。

但是在 React 里面去 ，他们推荐的方式是说不要区分这个模板和这个数据和逻辑 ， 你是做一个前端应用 ， 你的这个模板就是你的这个要核心要考虑的一部分 。

**柳成荫** [46:18]
我觉得这是 React 的 ， 啊 ，Rethink Best Practice 的一部分吧 。 啊 ， 理论上来说我们之前所 follow 的那个 best practice 是说把模板分离开来 ， 这样的话你 ， 啊 ，有更好的重用性 ，因为你那个模板是可以被重用的 ， 对吧 ？

**Rio** [46:33]
对 。

**柳成荫** [46:33]
啊 ， 可是如果你看这个 JSX 的话 ， 它实际上不是一个模板 ， 它完全不是一个模板 ， 你其实就是写 JavaScript code 嘛 ， 你 、 你 、 你所写的 。

**吴涛** [46:42]
你只不过是用一种类似于写模板的语法去描述数据吧 。

**柳成荫** [46:46]
对 ，exactly。

**吴涛** [46:47]
就是这样的 ， 就是它你对你在你 、 你在你用一种写模板的方式去写你的 data model， 这其实是一种进步 ，而不是 ， 呃 ， 就是某种抨击的某种某些人抨击的那样 ， 是一种历史的倒退 ， 我觉得可能 。

**Rio** [47:01]
对 ， 这个事情就其实挺好玩的 ，因为刚那个就是 React 去年刚发布 ， 呃 ， 正式对外发布的时候 ， 很多人就是吐槽这一点嘛 ，因为大家都可能被这个教条教条灌了哈 ， 就说这个模板和数据要分离 。

但其实我觉得当时那个 Pete Han 他有一个话说得很好 ， 就是说这个模板它 、 它分的那个就 separation concept 是分错了 。

**柳成荫** [47:23]
嗯 。

**Rio** [47:24]
它把两个不应该分开的东西强行分开了 ，但其实没有太多的好处嘛 。 啊 ， 所以通过就像那个 React 这种 JSX 的方式 ，其实把这两个本来就应该紧密联系在一起的 ， 呃 ，不两个部分放在一个地方 ， 然后大家可以一眼看到 ， 就好像那个 Willow 之前抱怨的说那个 Backbone 里面写很多这种 subview 的时候不方便说在一个文件里面就看出它在干什么 ， 然后用这种 JSX 的方式你可以一眼

看出 ， 啊 ， 我这个是在做一个模板 ， 我在这个模板里面填充了这么一个数据 ， 然后这个数据是从这个对象哪个地方来的 ， 然后这个我要添加哪些这个 event handler 都在同一个地方完成这个东西 ， 这个才是一个好的所谓的这个这个 encapsulation 嘛 。

**柳成荫** [48:07]
我要再次提醒大家就是你需要考虑自己的实际问题 ， 然后选择正确的 ， 啊 ，framework 或者 convention adopt。 啊 。

**Rio** [48:16]
嗯哼 。

**柳成荫** [48:16]
我们刚刚说那个 isomorphic 对不对 ，在那种情况下实际上你如果你分离出模板来的话是有好处的 ，因为如果你要在 ， 啊 ，在你的 、 你的后端用另外一种语言来写你的 render logic 的话 ， 那那个共用模板是可以共用的 ，但你得看在你的实际上使用过程中 。

**Rio** [48:35]
对 。

**柳成荫** [48:35]
我们是没有这么做的 ， 然后我们所有的模板是没有任何重用性的 ， 就是也不是没有任何重用性 ，而是没有 ， 呃 ， 它是有很强的重用性 ，因为 、 因为它 、 它 、 它在另外一个就是单独的自己的那个文件中的话 ，但是我们从来没有重用过它 ， 从来没有重用过它 ，在三年的写这个程序的过程中， 那 、 那到底做这个事情是为了什么 ， 我们其实也不是很清楚 。

**Rio** [49:00]
对 ， 没想明白 。

**柳成荫** [49:01]
所以在 、 在特定的应用场景下， 特定的 best practice 是有道理的 ， 比方说我们刚刚说那个你如果一个同一个模板要在不同的语言中被 render 的话 ， 那实际上是非常好的一个设计 ，但如果你仅仅是在 JavaScript 中， 那可能真的你得重新考虑这个事情到底是不是有意义的 。

何况你用 React 的时候 ， 这就真的不是模板了 ， 这个模板这个东西不存在的 ， 它所有的东西都是 ， 啊 ，JavaScript object，there is no string template， 这个 、 这个念头你得转过弯来 。

**Rio** [49:29]
对 。

**柳成荫** [49:30]
啊 ， 你写这 。

**Rio** [49:31]
它只是看起来像而已 ，但完全不是 。

**柳成荫** [49:34]
啊 ， 好处在于说 ， 啊 。

**Rio** [49:35]
对 。

**柳成荫** [49:36]
啊 ， 刚刚我们说 ， 啊 ， 把 subview 的问题在 、 在 Backbone 里头你 、 你 、 你得 ， 啊 ，在模板里头给它留空间 ， 然后再 manually insert 进去 ，在 ， 啊 ，React 中这就不是问题了 ， 你直接 import 一下， 然后 import 那个 sub、sub、subcomponent， 然后直接把这个 tag 写上去就好了 。

这 、 这 、 这是个非常非常非常好的 ， 啊 ， 重 、 重就是重用性的进步吧 。

**吴涛** [50:03]
对 ，而且实际上也在也大量减轻了开发者的 ， 呃 ，mental model， 就是在 、 在维护一个 mental model 的 、 的 、 的 、 的负担 ， 就是你不用总是在 ， 哦 ， 我现在在写一个 template， 哦 ， 我现在在写 model， 你不用再维护这个不停的 context switch 的成本上头 。

**柳成荫** [50:24]
还有必须得提到的是 ，JSX 并不是一个全新的东西 ，在 Facebook 内部 ，Willow 这是一个开源的项目了 ， 已经是 ， 啊 ，他们一直在用类似的产品叫做 XHP，是 PHP 的 ， 啊 ， 版本 ， 所以他们很长时间已经在 PHP 里写所谓 HTML tag 了 ， 所以在这点上也是对这个 concept 的一个 validation 吧 ，因为毕竟 Facebook 有用相同的概念用了很久了 ， 所以我觉得他们先人一步 ， 啊 ， 已经 accept 了这个概念了 ， 所以

、 所以对他们来说 ， 啊 ， 就 、 就不是一个事儿 ， 你知道吗 ？ 哈哈哈 。

**Rio** [51:06]
对 ， 我 、 我大概也是就是前年去湾区的时候 ， 然后看到他们就是在 Facebook 内部是怎么用这个叫做 XHP 的这么个语言嘛 ， 去写这个 ， 啊 ， 这个他们的这个服务端的软件 。

当时我就震撼到了 ， 我说哇 ， 这个就因为他们那个等于是可以任意构建一种 ， 就传统上我们写这个模板的时候 ， 你是只能用一个抽象程度很低的方式 ，因为你模板的话 ， 你要么就在模板层别上你可以构建一些东西出来 ， 或者是说 ， 呃 ， 你 ， 呃 ， 就你在写那些 HTML 标签的时候 ， 你还是要用那些标准的标签嘛 。

**吴涛** [51:39]
嗯哼 。

**Rio** [51:39]
但是他们在用那个 XHP 的时候 ，其实是可以定义自己的一个标签的 ， 然后这个标签可以包含很多很复杂的这种行为和数据 ， 包括内部的结构在里面 ，而这个对这个标签的调用方来讲 ， 完全可以不用关心里面到底是如何实现的 。

**吴涛** [51:55]
对 ，其实就有点像一个 AngularJS 所做出来的新的 HTML tag， 只不过这一切都在 PHP 里面 。

**Rio** [52:03]
对 ，他们这个他们应该也是叫做叫做 compliance 吧 ， 那个时候 。 就 、 就它所谓这个组件化的时候 ， 就组件化的时候 ， 就一个什么一个要达到一个什么样的 、 呃 ， 场景呢 ， 就是说我只要构建好我这个组件 ， 我这个组件对外部来说是一个完全封闭的 ， 你只需要外部提供给我需要的这个数据和我需要的包括一些 ， 呃 ， 这个回调函数的话 ， 我这个组件就能完成你

需要的工作 。 啊 ， 就不再需要去每个人都去看到这个组件 ， 啊 ， 内部是有多少个什么多少个 a tag， 多少个 div 这种层层包起来这么一个东西 。

这一点我觉得是一个在抽象层级上是一个划时代的进步 ， 我觉得 。

**柳成荫** [52:38]
嗯 ，是 。

**Rio** [52:41]
啊 ， 然后当时那个就是我看到 Facebook 他们内部在用这个之后就觉得哇 ， 这个真是 ，因为我没有在其他地方看到有类似的产品或者是语言吧 ，在做类似的事情 ， 真的是感觉走 、 走在什么时代的前列的那种 ， 跟我们不跟其他的人确实差的 ， 呃 ， 就领先的蛮远的 。

### React Native

**Rio** [53:01]
那我们下面讲那个 React Native 吧 。

**吴涛** [53:06]
呃 ，ES6 要讲吗 ？

**Rio** [53:09]
那个那其实不是很重要 ， 我觉得 。

**吴涛** [53:11]
OK， 这个是 。

**Rio** [53:13]
Willow，Willow 你觉得呢 ？

**柳成荫** [53:14]
说到 ES6 呢 ， 啊 ， 我觉得 Angular 跟最主要是 Angular 跟 React 的区别之一吧 ，因为 ， 啊 ， 就是 React 似乎在 ， 啊 ， 它的发展过程中考虑了更多的 JavaScript Native 的东西 ， while Angular 好像在创造一个自己的小世界 。

啊 ， 我们有一个 panel 上， 啊 ，有那个 Sebastian， 啊 ，是 React 的主要的 ， 啊 ， 维护者之一 ， 然后他实际上他本身是在那个 ES6 的 ， 啊 ， 那个委员会上的 ， 所以他有提到说 ， 啊 ，React 其实非常非常 aggressively 在推 ES6 的支持 ，他甚至把那个 mixing 的支持给去掉了 ，在最新的版本 。

**吴涛** [53:59]
你拿掉了吗 ？

**柳成荫** [54:00]
他解释呢 ，是因为 ES6 的 ， 啊 ，mixing 支持在那个不是比较糟糕 ，而是而是在那个 standard 中被去掉了 ， 就是 ES6 现在的那个标准 ， 就是在这一版中的话是不没有 mixing 的 ， 没有提到 mixing 的 ，他们在 ES7 中才会去支持 mixing， 或者说才会把这个事情再提上议程 。

所以正因为如此呢 ，在那个 Native 的 ， 啊 ，class uphold 中 React 把那个 mixing 给 、 给 、 给去掉了 。 啊 ， 当然这些事情都是 ongoing events， 所以 、 所以 ， 啊 ， 还有可能有其他的变化 。

啊 ，不过我觉得 ， 啊 ， 至少在我看来的话 ， 啊 ，React 是非常 ， 啊 ，在积极的推动和 ， 啊 ，comp 就是 ， 啊 ， 实现这个 ES6 的这个标准的 。

**Rio** [54:49]
哎 ，其实你 Willow 你对这个 ES6 就是 JavaScript 下一个版本的这个语言你 、 你什么样你是什么样态度 ？

**柳成荫** [54:57]
呃 ， 老实说我不是很熟悉 ， 所以我们把这段剪 、 剪掉吧 。

**Rio** [55:02]
哈哈哈 ，OK， 好 ， 那行 。

**柳成荫** [55:04]
我没有用 。

**吴涛** [55:05]
我们再做一次 。 我们再做一次 。 谁比较熟悉嘛 ，有人有人紧跟着 ECMA2。

**Rio** [55:09]
我 、 我有我有在跟这个 。

**吴涛** [55:11]
你在跟啊 ， 哦对 ， 你现在在搞这个对吧 ？

**Rio** [55:14]
没有没有 ， 我 、 我有在也有在用它嘛 ， 就是在就尝试去使用它 。 现在我把我昨天还在转就是那个那个 IPN 背后不是有个我自己写的 CMS 嘛 。

**吴涛** [55:24]
嗯哼 。

**Rio** [55:25]
然后还有一个管理后台 ， 那个其实是用 React 写的 。

**吴涛** [55:28]
嗯 。

**Rio** [55:28]
那哎 ， 那我想想 ， 那我们是先讲 Relay 呢 ， 还是先讲这个 React Native？

**柳成荫** [55:33]
因为 Native 实际上是个非常非常非常 ， 啊 ， 自然的过渡 ，因为 ， 啊 ，在 React 中你的最最初的版本中你的那个 render target 是 Virtual DOM 对不对 ？

啊 ，但是为什么一定要 render 到 DOM 上来 ， 已经反正已经 virtualize 了 ， 你 、 你就就好像你 、 你用那个虚拟机一样 ， 你到底那个虚拟机是在 Windows 上 run，是在 Mac 上 run，是在 you know like OS2 上 run，并并不重要嘛 ， 对吧 ？

啊 ， 所以 。

**Rio** [56:04]
对 。

**吴涛** [56:05]
对对 。

**Rio** [56:05]
它就等于它提供一层新的抽象 ， 然后借由这层新的抽象你就有了新的自由 ， 你可以把它你可以把 ， 呃 ， 它的底层迁移到其他的 platform 上面 。

对 ， 我 、 我忘了是那个是 Tom 还是那个 Christopher 说的哈 ， 就说他说我们他们之前做那个 Virtual DOM 的时候的最终目的并不是说要把这个 DOM virtualize 这件事情本身 ，而是说要完全去掉这个 DOM， 就是要把 React 跟这个 DOM 的依赖直接切掉 ， 就完全没有关系 ， 我可以不依赖一个 DOM。

然后最终的结果就是我们现在看到的它这次发布了一个重量级的产品叫做 React， 呃 ， 一个一个工具吧 ， 叫做 React Native。

呃 ， 什么意思呢 ？ 简单描述一下就是说我还是用 JavaScript 写我的应用 ，但是 ， 呃 ， 相比在网页上我是是是把它渲染成一个网页的那些 ， 呃 ，HTML 的这种 tag 标签的话 ， 我是直接用 ， 呃 ， 这个某一个平台原生的 UI 组件 ， 比如说在 iOS 里面就是一个原生的 ， 比如说这个列表那种可以滚动的那种有带重力不叫带什么加速度的惯性的那种 ， 呃 ， 滚动窗口 ，

或者说是我用一个原生的这个地图这个组件来实现我的这个功能 。 啊 ，但是我的这个这个程序的实际的后台的所有的这个 model 啊 ， 还有所有的数据啊 ， 还有包括那些逻辑啊 ， 都其实是在 JavaScript 里面运行的 。

**柳成荫** [57:22]
对 。

**Rio** [57:24]
啊 ， 这个我觉得是非常了不了不得的一个事情啊 ， 就是说 ， 啊 ， 我知道很多这个 iOS 或者是 Android 开发者在吐槽这个开就在其实哪怕是现在应该开发一个 iOS 应用或者 Android 应用都还不是那么爽的一件事情啊 ， 它有点像那个在 Backbone 时代的 ，有一点像在 Backbone 时代的开发 WebApp 的感觉 。

**柳成荫** [57:44]
对 ， 啊 ， 我觉得对我来讲最重要的概念在 React Native 中最重要的概念是 ， 啊 ， 我 Tom 说的 ， 啊 ，learn once, write everywhere。React Native 它并不是要你 write once, write everywhere， 它没有它没有它 React Native 本身它没有 ， 啊 ，merge the gap between Android and iOS，Android 还是要写 Android app，iOS 还是要写 iOS 的 app，但是你写程序的方式发生了根本的变化 ，不管是写 WebApp 好 ， 还是写 Android app 好 ， 还是写 iOS app 好 ， 你会用 exactly the same way 来写这三个不同的 ， 啊 ， 环境下的

application， 只是你 、 你 、 你会用这个这个环境的对 。

**Rio** [58:32]
不同的组件嘛 。

**柳成荫** [58:34]
这这一点上是非常非常有意义的 。 啊 ， 我本人对此也是深有感触 ，因为 ， 啊 ， 我之前有写一个 iOS app， 啊 ， 我不是 WhatFont， 我 、 我现在还在写另外一个 ， 啊 ， 小小的小小的说一下， 啊 ， 我有在写另外一个 iOS app， 然后其中有很多的 layouting，其实上是一个逻辑上来讲是一个比较简单的 app，但是有很多 layouting， 啊 ， 我有一个 UI label， 这个 UI label 是可变的长度 ， 然后这个 UI label 呢又在那

个 ， 啊 ， 一个可变长度的 UI table cell 中 。 啊 ， 就实际上如果你想用 auto-layouting 的话 ， 这是个非常非常麻烦的事情 ，因为在 UI label 第一次 render 的时候 ， 它并不知道它的宽度 ， 它如果它不知道它的宽度呢 ， 它就不知道它的高度 ， 它不知道它的高度呢 ， 它就乱 render。

啊 ， 你就得 ， 啊 ，auto-layout 呢是你知道 all about constraints， 所以你需要设计一系列的 constraint， 然后这个 ， 啊 ，layout 引擎会来猜测怎么样的结果能够满足你所有的 constraint 或者尽量满足你的 constraint， 这是个非常 non-tunitive 的 way。

然后从 Web 的角度来说的话 ，box model 多多简单啊 ， 虽然说 box model 有时候不工作 ，但是多简单啊 ， 你知道就是所有东西都是 box top box，box 在 box 之上， 你知道 ， 然后你有 margin， 你有 ， 啊 ，padding， 你有 border，其实非常非常容易理解 ， 非常直观的 ， 啊 ， 直观的 ， 呃 ， 一一种模式 。

反观你知道 iOS 如果你不用 auto-layout， 就是 constraint 非常难以理解 ， 然后你那个结果也不 intuitive， 你如果只给我一系列的 constraint， 如果你不 ， 啊 ，不告诉我结果的话 ， 我 、 我很难说我很有信心说这些 constraint 会得到我想要的结果 。

啊 。

**吴涛** [1:00:25]
我觉得可能最重大的一个差别就是 constraint-based layout 要求你能够在头脑中维护一个 ， 呃 ， 最终 ， 呃 ， 视觉效果的模型 ，而 box model 对此的要求就低一点 ， 或者说低很多吧 ， 应该说 。

**柳成荫** [1:00:42]
如果你不用 auto-layout 的话呢 ， 你又得就是 manually 去做很多的 math， 如果你看那个 Christopher 的 ， 啊 ，slide，他有他有一张全都是 math math math math。exactlyrightright，但但倒倒也不是说有多难多容易 ， 很多那个 iOS 开发者跟我说 ， 啊 ， 那不难啊 ，但是那 ugly 啊 ， 多丑陋啊 ， 我靠 ， 然后你要想要改一点什么东西的话 ， 又回头得去算 ， 然后哦妈呀 ， 真的是真可怕 ， 对吧 ？

啊 ，React Native。

**Rio** [1:01:13]
所以我觉得其实他们这次做的那个就是他们发布的 React Native，他们也解决了这个问题啊 ，他们用 JavaScript 实现了一套那个 CSS 最新的那个叫做 Flexbox 的那个 box model 嘛 。

**柳成荫** [1:01:25]
对 。

**Rio** [1:01:26]
然后他们用那个模型就解去解决了这个在去怎么去布局那些原生的 UI 组件的问题 ， 这个我觉得就刚才那个 Willow 也已经大家相信已经听出来哈 ，Willow 吐槽对这个什么 constraint layout auto-layout 这东西已经吐槽很久了 ，其实就从从某一个意义上讲 ， 那个什么 constraint-based layout 的话 ，其实它是要你在你头脑中构建一个这个就是叫做叫做什么动态规划机 ， 对吧 ？

你得自己在头脑中随时解那个解那个方程 ， 解完之后才说啊 ， 这个这个会出现在那里 ， 这个会出现在那里 ， 就不像那个 box model， 它是更加反映出是一个比较直观的哇 ， 这个应该是多大 ， 它应该有多宽 ， 然后它多到一个一个一个边框是就那个什么 margin 东西叫什么来着 ， 留白对吧 ？

留白要多少 ， 或者是跟其他的东西间距要多少 ， 我这个确实是 CSS， 呃 ， 就是这个比较好的解决的一个地方哈 。

就我我很好奇为什么像 iOS 啊 ，Android 之前他们没有用到这种同样的模型去做这个事情 。

**吴涛** [1:02:25]
呃 ， 这是一个很好问题 ，其实这个可以将来专门找一期谈这个 ， 就是为什么 box model 这种看起来如此简单易行 ， 又呃 ， 又呃 ， 大量解放生产力的布局仅仅在 Web 领域独树一帜 ， 就甚至很多比如说排版软件都完全不去考虑这种这种 。

**Rio** [1:02:49]
嗯 。

**吴涛** [1:02:50]
但我觉得可能还是惯性在里面吧 。

**Rio** [1:02:54]
对 ， 这个是挺挺奇怪的一件事 。

**吴涛** [1:02:56]
对 ， 比如说你说 iOS 为什么不用它 ，iOS 不用它是因为 OSTen 不用它 。

**Rio** [1:03:01]
哈哈哈 。

**吴涛** [1:03:01]
iOS 毕毕竟一开始只是 OSTen 的一个改版嘛 ， 就就 Mac 上的 app 不可能不从来没有用过 box layout， 所以 iOS 上面也就不用了 。

**Rio** [1:03:15]
这这次这个 React Native 它发布了我觉得还有一点我觉得特别令特别特别就是说就令人觉得比较呃 ， 惊奇的一点哈 ， 就是它因为那个整个这个呃 ， 程序的逻辑和这些啊 ， 包括这个呃 ，model 啊 ， 都是在 JavaScript 里面实现的嘛 ， 然后这个 JavaScript 它是依赖于一个就所谓解析器或者是 JavaScript 引擎的嘛 。

**柳成荫** [1:03:39]
对 。

**Rio** [1:03:39]
然后这个引擎可以不用跑在那个手机上面 ， 它可以跑在他们在现场 demo 的时候 ， 它那个解解析器是跑在浏览器里面的 ， 然后它可以在就是在 Chrome 里面去改那个浏览器 ， 然后即时重刷新一下， 然后这个在那个 iOS 的这个 iPhone 模拟器里面 ， 那个对应的一个原生的 UI 的主那个那个界面就随之发生改变了 ， 我觉得这个非常非常了不得 。

**柳成荫** [1:04:06]
这个在实际的 production 中是不不可能就是很很难实现的 。 啊 ，however，但是这反映了就是说 ， 啊 ，React 它 Native 到底是怎么样实现从 JavaScript 到 Native 的这个转换 。

啊 ，React Native 不想要成为一个性能瓶颈 ，of course notright， 啊 ， 所以它的实现方式就是在啊 ， 把 JavaScript 这个引擎放到单独的呃 ，background thread 中， 一个一个单独它自己一个单独的线程中， 啊 ， 然后在这个线程中有一个啊 ，JavaScript 的引擎在啊 ，不断的啊 ， 渲染 ， 然后得到结果 ， 再通过 channel 的方式把这个呃 ， 渲染结果发回到那个你的主线程中， 所以你的主线程是没有被 block， 你随时这个结果就是说你的主线

程总是很 smooth 的 。 反观如果你用一个 webview 的啊 ， 一个一个解决方式 ， 到先不说就是你你不能够用 Native component 这种这种极大的问题 ， 啊 ， 关键是说你的 JavaScript 是会 block 你的主线程的 ， 所以说如果你 JavaScript 在做一些啊 ， 大量的运算的时候 ， 那个啊 ， 用户如果在比方说在在在在向下滑那个页面 ， 那页面就会不动嘛 ， 就所以那个页面就不 smooth 嘛 ， 你整个的那个体

验就就很不易 ， 就就很不乐观咯 。 所以 React 既让你 React Native， 既让你使用 Native component，有 Native 的 experience，也从性能上帮助你啊 ， 呃 ，不要啊 ， 就是提供不好的体验 。

**Rio** [1:05:50]
就它把这个啊 ，UI 的渲染和这个逻辑的就是就业务逻辑的执行是完全割裂开 ， 然后通过异步的方式进行通讯同步的嘛 。

啊 ， 这个是我觉得非常非常好的一件事情哈 ，但是这就牵涉到另外一个问题了 ， 就它这样的话对这个后台的那个执行 JavaScript 解析器的那个进程的性能会有要求吗 ？

比如说据我所知在呃 ，iOS 上面这个你单独自己跑一个 JavaScript 的这个解析器的话 ，是没有那个他们那个叫什么来着 ， 那个啊 ，JIT 的优化 。

**柳成荫** [1:06:24]
啊 ， 这一点上我并不是特别清楚他们主要实现方式 ，但是有一点很重要是你刚说的那个问题只只有在你直接使用啊 ，webview 的情况下才会出现 。

**Rio** [1:06:40]
嗯 ， 为什么 ？

**柳成荫** [1:06:41]
因为那个引擎是在那个 webview 里头啊 ，但是他们的那个 React 的实现方式是并不代表说它一定要用那个啊 ，JavaScript 引擎 ， 它可以自己包装一个其他的啊 ，JS 引擎在里头 。

**Rio** [1:06:54]
就是它可以说我不用苹果那个 iOS 自带的那个 JavaScript 引擎 ， 然后这是然后我自己包一个带 JIT 的这个 JavaScript 解析器进去 ， 这样执行吗 ？

**柳成荫** [1:07:05]
没错 。

**Rio** [1:07:06]
OK， 那这样不会就会撞到那个 App saw 的审核条例的那某一条说不能自带解析器吗 ？

**吴涛** [1:07:13]
真的吗 ？

**Rio** [1:07:14]
有这么一条的曾经 。

**吴涛** [1:07:16]
我记得后来就因为那一条苹果条约 ， 我记得我还写过 blog， 就是说它只能用规定的几种语言来写 ，但好像没有说不能自带虚拟机吧 ，不然那些什么带 Lua 的东西是怎么被审核通过的 。

**Rio** [1:07:31]
对 ， 这就是一个挺模糊的一点 ， 就是后来因为很多游戏它需要用那个 Lua 解析器作为一些辅助的事情嘛 ， 所以它就后来又又通过 ， 现在我也不太清楚苹果在对这件事情的这个啊 ， 的立场是什么 ，但是嗯 ， 这个只能再再议了吧 。

**柳成荫** [1:07:48]
我可以 fact check 一下 ，因为我有那个啊 ，他们把那个啊 ，Native 就是它的那个演示的代码给所有的与会者都分享了一份 ， 所以我是可以 fact check 去看他们到底用什么引擎的 。

**Rio** [1:08:03]
OK， 你可以看一下它用的是苹果原生的还是 。

**吴涛** [1:08:06]
就是那个叫什么 JavaScript core 的 。

**Rio** [1:08:08]
对对对 ，JavaScript core， 我理解应该是吧 ， 今天这个是个成成本比较低的方案嘛 ， 你不用自己做任何事情 ，而且如果每个应用都要自己带一个 JavaScript 解析器的话 ， 那个应用的尺寸也会比较大 。

这是一个问题 ， 我觉得 。

**吴涛** [1:08:25]
好 。

**Rio** [1:08:26]
啊 ， 就是其实现在用那个 React Native 其实有已经有一个 app 的一个典范了哈 ， 就在 iOS iOS 的这个 App Store 里面 ， 啊 ，Facebook 一个叫做新的应用叫做 Groups， 就是 Facebook 群组的这个这个单独的一个应用 ， 它其实是在很大程度上用的这个 React Native 写的 。

然后我之前我我在知道它是用 React Native 之前 ， 我就已经用下载过用过它 ， 当时我完全没有感觉到它不是一个 Native 的软件 ， 就是非常就整个体验是非常好的 。

**柳成荫** [1:08:57]
呃 ， 问题是我们并不是很清楚说它到底哪一部分是 UI 的那个 。

**Rio** [1:09:02]
就是多少比例是用的那个 。

**柳成荫** [1:09:05]
对 ， 或或许这正是这个好处所在 ， 你知道用户如果说他他他都他都不知道哪部分的 ，他都感受不出来 ， 那就证明这个东西说不定就成功了 。

**Rio** [1:09:14]
对 。

**柳成荫** [1:09:14]
啊 ， 对 ， 我们所啊 ， 拿就是与会者所拿到的这个版本跟啊 ，Facebook 它所用的版本实际上是不同步的 ， 啊 ，Facebook 它还在做很多的工作来啊 ， 把这个东西给完善 ， 然后才会正式的向大众发布 。

目前来说的话 ， 我们所看到的版本都是一个啊 ， 只是一个啊 ，tech preview kind of thing。

**Rio** [1:09:42]
对啊 ，OK， 明白 。 啊 ， 就是说 React Native 刚才 Willow 你也提到他们的口号是叫做 learn once, write everywhere 嘛 ， 然后我其实我也在想 ， 如果你按这种方式去构建你的 app 之后 ，其实还是可以有蛮多部件是可以在各个平台之间重用的哈 ， 比如说之前啊 ， 我好像是在前期还是上前期的时候 ， 我们在讨论过啊 ， 那个 Google 不是做了一个叫 Inbox 那个 app 嘛 ， 就新的 ， 它是有安卓版 ，有 iOS

版 ， 然后还有一个这个 Chrome， 只有 Chrome 浏览器可以用的 web 版嘛 ， 然后他们后来发了一篇博客文章去讲他们怎么去做这么一件事 ， 就是说他们把这个假设你把这个整个应用分成两部分 ， 一对是前端 ， 就跟那个用户交互的那部分 ， 那么这部分就是说在 iOS 上面就是 Object C 写的 ， 然后在安卓上就是用那个 Java 写的 ， 然后在这个啊 ，Web 上就是 JavaScript 写的 ，但是

他们其实是都是用 Java 写的 ， 然后通过 GWT 转化成 JavaScript， 然后通过一个叫做 J2 Object C 的一个工具转换成 Object C 代码来做啊 ，不做那个逻辑的那一部分 ， 就是就跟原生界面无关 ，但是是跟这个后台的事物逻辑相关的 ， 就是通过同一套语言 ， 然后再转化成不同的同同样用 JavaJava 写 ， 然后通过这两种工具转换成对应的 JavaScript 或者 Object C。

但如果我们用这个 React Native 来写的话 ，其实就这一步都可以省去了 ， 我直接把所有的事物和逻辑都写成 JavaScript 就好了 。

**吴涛** [1:11:12]
对 ，其实这让我想起那个嗯 ，AppCelerator 出的 Titanium， 呃 ， 它也是用 JavaScript 来写整个所有的事物逻辑 ，但是其使用的那个 UI widget 全都是原生的 。

**Rio** [1:11:28]
嗯哼嗯哼 。 它那个体验怎么样呢 ？

**吴涛** [1:11:31]
不是特别好 ， 就因为呃 ， 前公司在做 web 呃 ，不是在做 mobile app 的时候考虑过用 Titanium， 呃 ， 可能当时最大的一个问题就是首先那个时候正好是 iOS 6 升到 7 的过程中， 然后他们大概是比落后了吗 ？

落后了可能 3 到 5 个月的时间 ， 就是我觉得这个是不可忍受的 ， 就呃 ， 新的 iOS 版本已经在那边了 ， 然后你如果你用 Titanium 的话 ， 你用不到新的一些 widget。

**Rio** [1:12:02]
对 。

**吴涛** [1:12:03]
嗯 ， 然后他们的他们的那一个那一套东西据说其实是非常优秀的 ，但是呃 ， 没有什么文档 ， 主要是哈哈哈哈 。

**Rio** [1:12:16]
这个可能可能是用任何第三方平台或者这种框架都会遇到的问题吧 。

**吴涛** [1:12:21]
对 ， 呃 ， 据说 AppCelerator 还在搞 ， 现在在搞一些新的什么东西 ，但我一时也想不起来名字了 ， 呃 ，其大概的走向可能和 React 有点异曲同工的地方 ， 我还要看一下 。

**Rio** [1:12:37]
OK， 所以说呃 ， 那说回这个 React Native 这种方式 ，其实我还不是特别赞同他们说完全不在乎这个 write once, run anywhere 这么一个口号的哈 ， 就是说起码你假设你看到像这些后台的逻辑啊 ， 还有这些数据 ， 这些模型啊 ， 都可以用 JavaScript 构建 ， 这一块是完全可以在各平台之间重用的 。

**柳成荫** [1:12:55]
没错 。 嗯啊 ，而且我可以预见到肯定会有人做一个中间层 ， 然后说用这些组件的话 ， 这些组件可以就就变成那个 environmental sensitive， 然后他们会根据 environment 来 。

**Rio** [1:13:10]
就原对原生的组件 。

**柳成荫** [1:13:11]
比如说你个 Tab view， 你可以用这个组件的 Tab view， 然后这个 Tab view 背后的实现会根据啊 ， 你的 target 是 Android 或 target 到 iOS 来自动选择啊 ， 相应平台的 Tab view。

啊 ， 这并不是 React Native 自己本身的一个设计理念啊 ，React Native 非常鼓励你去啊 ， 根据各种平台本身的特性来设计不一样的 UI 啊 ， 来用不一样的 component，而不是像这样的简单的替换的逻辑 。

但是我想我们肯定会看到第三方的一些啊 ，solution 出来的 。

**Rio** [1:13:51]
对 ， 我觉得这个就是很多就像什么什么企业级软件可能会采取这种方式啊 ，因为它没有那么多的资源 ， 或者说就是人手去优化每一个平台的细节的体验 ， 那么更加呃 ， 就是节省成本的节省开发时间的一个方式 ， 就是通过这种什么中间层去转换一下嘛 ， 我觉得 。

嗯 ， 就虽然体验不是太好 ，但是起码成本下去了嘛 ， 我觉得这个对很多企业软件来讲就是这样的一个一个诉求 。

**吴涛** [1:14:16]
没错 。

**Rio** [1:14:17]
嗯 。

**吴涛** [1:14:18]
就我们现在等于说如果呃 ，Native 呃 ，sorry，React Native 这一套啊 ， 能够吸引到一部分人去把它炒起来的话 ， 那呃 ， 可以说企业级跨平台应用开发又多了一个新的选择在 。

**Rio** [1:14:37]
对啊 ， 从 Java 变成 JavaScript。

**柳成荫** [1:14:39]
啊 ， 我有跟我们的 developer 说讨论这个问题 ， 它并并不单是在 solution 上， 就是 tech solution 上有改变你的你的组织架构 ，而关键是说如果你想这个 ， 如果你真的实现 learn once, write everywhere 的话 ， 那啊 ， 所谓 web developer 跟啊 ，mobile developer 之间的界限就变得更模糊了 。

我觉得对于 。

**Rio** [1:15:06]
可能是二二合一了 。

**柳成荫** [1:15:07]
对于这个资源的呃 ， 对于这个企业资源的一个运用 ，其实上是一个非常有意思的事情 。 你知道就所以你知道我们的比方说如果现在啊 ，web application 不需要太多维护的话 ， 那这些人就可以去写那个呃 ，Android app 去写 iOS app， 对不对 ？

所以这一点上对于企业来说可能是一个非常重要的事情啊 。 所以我也有跟我们啊 ， 我们的 web developer 开玩笑说 ， 那你现在得赶紧去学啊 ，HTML，CSS， 对 ， 赶紧去赶紧开始学哦 。

**Rio** [1:15:40]
哈哈哈哈 。 哎 ，他现在那个 React Native 这个是还是在什么 alpha 阶段 ， 可能是 pre-alpha 阶段 ，他们现在是说有一个私有的 GitHub 的 repository， 你们可以访问 ， 就参与会者可以访问嘛 ， 外界还没有公开哈 。

啊 ， 我我不知道你看了多少 ，但是我的就比较好奇他怎么去实现他这个就是 JavaScript 那部分的业务代码 ， 业务逻辑怎么去和原生的那些进行交互那块 。

**柳成荫** [1:16:07]
啊 ， 我没有还来还没有来得及啊 ， 对这个代码本身做很多的研究 ，但是对 developer 来说的话 ， 你所做的事情真的跟以前写那个 web application 没有太大的区别 。

我可以把流程说一下， 就是说从那个纯粹的开发者的啊 ， 这个角度来说的话 ， 你 clone 这个 repository， 然后啊 ， 你做 npm install，OK，在你就是就是传统的 JavaScript， 你知道都大家都这样 ， 然后你写说 npm start，OK，npm start 的啊 ， 理由原因呢 ，是你现在是在一个 dev environment 里头 ， 你这些 JavaScript 的文件需要 serve 到那个啊 ，simulator 里头去 ， 对不对 ， 那个 iOS simulator 里头去 ， 所以这个这个 npm star 就会啊 ， 启动一样一个这样

的啊 ，server， 然后 watch 你的那些文件 ， 然后你如果去看那些文件的话呢 ， 实际上跟你写 React 的呃 ， 的那个啊 ，web 方 web 的那个 application 并没有太大的区别啊 。

如果真的要说最大的区别 ， 可能就是说你没有 CSS file 了 ， 你所有的 file 都是 inline， 所有的 style 都是 inline， 这是最大的区别了 ，其他的东西都看起来非常的相似 。

**Rio** [1:17:25]
对对 。

**柳成荫** [1:17:25]
啊 ， 然后你写的是真的是纯就是 common JS 那种组件 。 啊 ， 最神奇的地方在于 ， 如果你看到那个 video 的话 ，有这一点 ， 就是你把这在那个比方说如果你啊 ， 改变一下 CSS， 那个 iOS 的 simulator 是直接可以得到这个结果的 ， 你是不需要去 recompile 的 ， 这点非常的神奇啊 。

**Rio** [1:17:48]
对对对 。OK。他们有一个说法就是说要实现你在这边就编辑器里面改一行代码 ， 然后在 iOS 那个那个模拟器里面实现呃 ， 就是出现改动只需要不到一秒 。

**柳成荫** [1:18:01]
对 ， 就跟 OK， 就是这个我觉得对开发效率非常大的大的提升 。

**吴涛** [1:18:06]
呃 ，library load 的时间级别嘛 。

**柳成荫** [1:18:09]
对对对对 。

**吴涛** [1:18:10]
Java 类似 Java 世界里面有个叫做 Jrebo 也做类似的事情 。

**Rio** [1:18:14]
哈哈哈哈 ， 这个我觉得看那个 demo 真的是挺酷炫的 。 嗯 ， 哎 ，不过你们觉得这样的话 ， 那不变成 JavaScript 变成一个什么通用的 。

**柳成荫** [1:18:26]
这已经是现实了啊 。

**吴涛** [1:18:28]
对啊 ， 哈哈哈哈 。

**Rio** [1:18:30]
那你们觉得这是好事吗 ？

**吴涛** [1:18:32]
是呃 ， 这个电脑上面的另一层电脑 。

**Rio** [1:18:35]
对对 ， 这个这个浏览器那边我们毫无疑问 JavaScript 已经是一个 ， 就如果它不是通用语言 ， 它至少是一个构建的基石 ，因为很多语言可以所谓 compile to JavaScript 嘛 。

**吴涛** [1:18:45]
对 ， 我觉得 JavaScript 其实就是现在的 C 嘛 ， 就现在的 。

**Rio** [1:18:48]
不会编 。

**吴涛** [1:18:49]
现在浏览器就是当初的 PDP11 之类的 ， 然后就是 C 语言本来是多那个多设计的多么粗糙的一个语言啊 ，但就是因为时事造英雄把它推的推到了现在的霸主地位 ， 我觉得 JavaScript 基本上就是另外一个 C 嘛 。

**Rio** [1:19:07]
对啊 ，但是现在 React Native 它要做的事情就是说把这件事情再往这个就是 mobile 就移动端再推嘛 ，因为之前移动端大家还是在就至少我们是鼓励或者消费者也愿意使用所谓的原生的应用嘛 ，但这个原生打引号 ， 就可能说说你要用这个平台自己的那种工具 ， 然后自己的语言来写 ，但现在你再看 React Native 它能够把这个啊 ， 整个效果做得这么跟原生就是说以假

乱真吧 ， 至少是 ， 那就完全没有必要再用平台原生的语言来写了 ， 就好像说哎 ， 我是现在是一个 web developer， 那我也可以做 iOS 应用 ，不需要学什么 Object C 或者 Swift 了嘛 。

**吴涛** [1:19:44]
对 ， 这就好像把呃 ，C 语言移植到不同的架构的处理器上嘛 。

**柳成荫** [1:19:51]
啊 ， 我觉得吴涛刚刚说的很好 ， 就是这这这怎么说 ， 就是就是既定事实 ，JavaScript 的应用就是既定事实 ， 所以我很期待 ES6 和 ES7，因为这个啊 ， 语言本身还是有非常非常多的问题的 ， 特别是它的 prototype 这样一个啊 ， 架构 ，而不是 class based 啊 ，ES6、ES7， 我很期待他们把这些问题解决好 ， 这样的话对于我们这些语言的使用者来说是一个非常好的事情嘛 ，因为啊 。

**Rio** [1:20:22]
啊 ， 作为一个 web dev， 你竟然不喜欢 prototype。

**柳成荫** [1:20:26]
而不是不喜欢 ，而是说啊 ，在真正的应用上面 ， 我很我们很多时候都是在啊 ， 用 prototype 去 simulate class，因为没有 native class support 嘛 ， 这这是我所不喜欢的一点 。

我说 prototype 本身啊 ，在 ES6 中加入真正的 class support， 这是我所期待的啊 ，prototype 当然有 prototype 的好处和应用啊 ，但是实际的应用中的话 ， 如果我们要用 class 的话 ， 那我还是希望能有真正的 class。

**Rio** [1:20:54]
对 。

**吴涛** [1:20:54]
OK。 我觉得 class 出现其实是比较呃 ， 如果有比较合理的 class 的支持的话 ， 那对于构建大型程序实际上是更加有利的 ，因为 prototype based object orientation 它的优点我觉得就在于你你做原型开发非常的快 ，因为你不需你不需要去考虑那个模板和实际的 instance 之间的呃 ， 抽象的问题 ，但当你要做大一些的东西的时候 ， 这个这个抽象其实还是相当必要的 。

**Rio** [1:21:28]
OK。 对 ， 我我不知道哈 ，因为我对这种所谓就传统的经典的基于 class 的这种呃 ，OO 的话 ， 我其实并没有太特别的偏好 ， 所以我觉得就两种都还好啦 ， 没有没有那么就是就 class based 没有那么好 ， 就 prototype based 没有那么差 ， 我觉得是这样 。

**吴涛** [1:21:47]
哎 ，Go 也是没有 class 的对吧 ？

**Rio** [1:21:49]
Go 根本就没有 ， 连 prototype 都没有 ， 它是基于 interface 的 ， 更完全更不一样 ， 我觉得其实用实际用起来我觉得是那种是更灵活的 。

**吴涛** [1:21:57]
对 ， 所以我觉得你其实就是一个你你比较不喜欢这种哈哈哈哈 。

**Rio** [1:22:02]
经典的 class。 对对 ， 没错 ，Java 你看太多了 。

**吴涛** [1:22:07]
我觉得你可以去看看 IO， 就是 EO 这个语言 ， 我不知道怎么念的 ， 它其实也是呃 ，prototype based 的 ， 然后 。

**Rio** [1:22:14]
不 ， 这个这这个说来其实还蛮蛮奇怪的哈 ， 那个 Object C 算是一个经典的基于 class 的继承 ， 那个 OO 语言也不算吧 ， 它是类似于 small talk 那种方式 。

**吴涛** [1:22:25]
它是在 C 上面加了一层 small talk， 然后啊 ， 用一个他用一个最近看到一句话来说 ， 呃 ，Object C 就是过去 25 年计算机语言发展史的缩影 ， 你在看里面不同语言特性的时候 ， 你会如果你从一个计算机历史学家加引号的角度来看的话 ， 就你会看到哦 ， 这个特征来自于那个时代的一个思潮 。

**Rio** [1:22:48]
考考古考古语言啊 ， 对 ， 就所以其实我觉得就很好奇嘛 ， 就是说就是啊啊 ， 起码 Object C 也已经证明了 ， 就说你没有一个大规模的呃 ， 就没有 class 的支持的一个呃 ，OO 的语言也可以做得很好嘛 ， 就是是不是不能证明这一点 。

**吴涛** [1:23:08]
我觉得不能不太能证明吧 ，不过这啊算了 。

**Rio** [1:23:13]
我们可以留待以后再讨论吧 。

**吴涛** [1:23:15]
专门讲这个编程语言的一期 。

**柳成荫** [1:23:17]
我们刚刚说到就是啊 ，JavaScript 应用这么广泛啊 ， 实际上在这个 talk 中啊 ， 我们有一个呃 ，Netflix 的啊 ， 那个 speaker， 然后他有说到说就是啊 ， 我们现在有很多智能那个电视嘛 ， 智能电视上有很多可以看 Netflix， 然后他们都是用啊 ，JavaScript 来写这个东西的 ，他们都是啊 ，ship 一个那个 web kit 的啊 ，help 啊的的啊 ， 封装给那个电视厂商 ， 然后这其中有他们的 Netflix 的 application。

**Rio** [1:23:52]
对 ， 你知道那个 Apple TV 也是这种方式实现的吗 ？

**柳成荫** [1:23:55]
哦 ，interesting 啊 ，Netflix 的啊 ，Netflix 他们实际上现在是用 React 来写那个 TV app 的 ， 就好像 React Native 一样 ，他们是 React TV，you know。

**Rio** [1:24:09]
啊 。

**柳成荫** [1:24:10]
Yeah， 那个不是开源的程序 ，但是但是他有介绍说这个是怎么样实现的 。

**Rio** [1:24:14]
嗯哼嗯哼 ， 哦 ， 之前我也在玩那个 ， 哎 ， 你有那个叫什么 Chromecast 那个那个小棒子吗 ？

**柳成荫** [1:24:22]
啊 ， 我在公司有 ，但是我没有我没有很经常 。

**Rio** [1:24:25]
我我我我自己有一个 ， 然后我之前玩过一段时间 ， 就它也是那种方式 ， 就它整个就是其实就是一个浏览器窗口啦 ， 它你可以电视上的啊 ， 然后里面也可以做类似的事情 ， 就是你你可以把这个整个 React 组件丢过去 ， 然后做一些很好玩的事 。

**吴涛** [1:24:40]
哎 ， 我插问一句 ， 呃 ，Chromecast 的那个小小棒子 ， 它要求有外界的 WiFi 在是吧 ？

**Rio** [1:24:48]
对 ， 它只能通过 WiFi 和外界 。

**吴涛** [1:24:50]
它自己不能提供一个热点 。

**Rio** [1:24:52]
它自己不 ， 它只是一个 WiFi 接收器而已 ，但是你你把它 hack 掉 ， 应该也可能做一个热点出来 ，但你为什么你会想得它会是一个 WiFi 的接收器 。

**吴涛** [1:25:00]
如果它能够自己成为一个 WiFi 接点的话 ， 我出去在酒店里面用酒店的电视呃 ， 看在 iPad 上面预先 load 好的视频其实 。

**Rio** [1:25:14]
你想发送过去是吧 ？ 不 ， 首先你要有两点是有问题的 ， 第一个它不它不能 ， 它只能是一个 WiFi 的这个 client， 它不是一个 AP，但是估计你 hack 一下应该也行 ，但第二个问题就是说 Chromecast 的那整个的一个那个 API， 包括认证机制是不允许你随意播放你本机的视频文件的 。

**吴涛** [1:25:36]
OK。

**Rio** [1:25:36]
就比比较麻烦 ， 你可以做 ，但是比较麻烦 ， 只能私人做 ， 没有那种比较现成的 app 来搞这种 。

**吴涛** [1:25:42]
嗯 ， 好吧 。

**Rio** [1:25:44]
不过不影响啊 ， 现在很多手机都可以建一个热点嘛 ， 然后你可以用那个那个手机的呃 ，有有很多 Android app 就可以让你做到这件事情 。

**吴涛** [1:25:52]
OK。

**Rio** [1:25:53]
啊 ，iOS 就暂时没有解决方案 ， 哈哈哈 ，Apple TV 都没有 ， 没有办法 。

**吴涛** [1:25:58]
打个叉 。

**Rio** [1:25:59]
嗯 ， 那我们接下来讲 ， 哎 ，React Native 还有什么要补充的吗 ？ 我应该差不多 ， 我想想 。

**吴涛** [1:26:05]
我觉得差不多了吧 。

**Rio** [1:26:07]
那讲 。

**吴涛** [1:26:08]
就其实有一个问题就是呃 ，React React Native 可以用来写游戏吗 ？

**Rio** [1:26:14]
呃 ， 那种所谓 light game 应该是可以的吧 ， 我觉得 。

**吴涛** [1:26:19]
对 ， 就是嗯 。

**Rio** [1:26:21]
哎 ，不过也不一定 ，有人用那个什么 WebGL 来写那种很复杂的射击游戏 。

**吴涛** [1:26:27]
可是在呃 ，React Native 就 React Native 所能操纵的原生组件到底到一个什么级层级呢 ？ 比如说那个 iOS 上面的 spread kit 它可以它可以它可以用吗 ？

**Rio** [1:26:41]
这个就只有 Willow 才能回答 ， 哈哈 。

**柳成荫** [1:26:44]
啊 ，有人问过类似的问题 ，但不是直接问游戏 ，而是说到底它可以 。

**Rio** [1:26:49]
就哪些组件是可以用的是吧 ？

**柳成荫** [1:26:51]
对 ， 然后所得到的答案呢 ，是说啊 ， 我的理解啊 ，不是 quote unquote 啊 ，是说所有的组件都是可以用的 ，但是可能有些组件你得自己手工把它包装一下 。

**Rio** [1:27:04]
OK。

**柳成荫** [1:27:05]
啊 ， 对 。

**吴涛** [1:27:05]
就是以什么方式包装呢 ？ 是说我必须再用 Swift。

**柳成荫** [1:27:09]
再写个什么 Object C。

**吴涛** [1:27:10]
Object C 写一个 wrapper， 然后它可以调用吗 ？

**柳成荫** [1:27:13]
啊 ，不是 ，是在 JavaScript 端写一个 wrapper 啊 ， 你这样想哦 ， 你这样想啊 ，不考虑 React Native， 就考虑那个啊 ，React 的 JS 的 part 啊 ， 你可以用 div 对吧 ？

你可以用 div， 你可以用 like almost any HTML component，但是 div 本身它有一个中间层是啊 ，React 已经提供给你的 ，React 已经写了这个 div 这个 component 对不对 ？

**Rio** [1:27:40]
就 virtual DOM 里面会有一个 div 的对应的一个一个对象吧 。

**柳成荫** [1:27:45]
然后这个这这这个东西是 JavaScript 啊 ，是在 JavaScript 里头有一个组件来告诉 virtual DOM 说我自己要做什么 ， 我能够做什么 ， 如果我的 state change 我应该怎么变化 ， 这个是在那个 JavaScript 的 definition 里头的 。

同样的 ， 如果说你现在 HTML 出现了一个新的东西 ， 出现了一个新的 tag， 然后你想要用这个 tag 啊 ，by the way， 那个 React 还有一些啊 ，SVG 所相关的那个 tag 它没有实现 ， 如果大家有兴趣的话可以去 contribute 啊 ， 就现在要加入这个呃 ， 对这些新的原生 tag 的实现的话呢 ， 那你也写一个啊 ，React 的 component 来实现它对不对 ？

所以转换成 React Native 的逻辑呢 ， 如果你有一个原生的 Native 的那个啊 ，component 你要使用的话 ， 你只需要在 JavaScript 端写一写一个 adapter 来说这个东西是是个什么东西啊 ， 怎么样 initialize 它 ， 它啊 ， 能够提供什么样的操作 ， 然后啊 ，React 的那个引擎肯定有一个就是 protocol 来说你你要怎么写这个文件在 JavaScript 了 ， 然后你按照它啊 ， 一壶花瓢把它写出来之后呢 ， 那你就可以用这个原生组

件了 。

**Rio** [1:29:01]
但我觉得可能吴涛的问题就是说 ， 那是就是说呃 ，是 React Native 这个 library 提供啊 ，JavaScript 到这个 iOS 的那些原生组件这一个桥吗 ？

还是怎么样 ？

**柳成荫** [1:29:14]
是 React Native 自己本身实现那个那一个 。

**Rio** [1:29:17]
那那这会不会有这样类似于这个叫什么 Titanium 那种同样的问题 ， 就是说你要等这个 React Native 这个 library 提供了对应的这个呃 ， 比如说 iOS 的一些原生的组件的这个桥了之后， 你才可以用它 ，而不是说我自己可以 ， 比如假设苹果 iOS 9+ 又出了一些新的原生组件 ， 那我作为一个开发者 ， 我可以自己包一下就可以用 ，而不是说要等到这个 React Native 发布一个新版支持说就所谓 expose 那些原

生的组件出来才可以用呢 ？

**柳成荫** [1:29:48]
根据在那个啊 ， 会上的 Q&A 的答案的话 ， 我相信是你可以自己来做这个事情的 。

**Rio** [1:29:56]
就他们做了一个通用的桥 。

**吴涛** [1:29:58]
这个非常好 。

**Rio** [1:29:59]
啊 ， 这个就很厉害了 ， 就不用考虑 ， 就不会遇到那个之前那个 Titanium 那种问题了 。

**吴涛** [1:30:03]
对 。

**Rio** [1:30:04]
啊 ， 这个真的不 ， 这个了不得 。 我靠 ， 那这样那么 Swift 不就挂了 ？ 哈哈哈 ，JavaScript 多简单 。

**柳成荫** [1:30:12]
你知道这个技术的发展总是有很多不确定性的 ， 所以大家不要把鸡蛋放在同一个篮子里头 。

**吴涛** [1:30:19]
哈哈哈 ， 这是没错 ， 还好我已经不做前端了耶 。

**Rio** [1:30:23]
哈哈哈 ，不过这也是一个问题啊 ， 前端真是变化好快 。

**吴涛** [1:30:27]
对 ，其实这也是我在那个提纲里面写的 ， 就是我觉得现在前端真的是没有人知道风会往里面吹啊 。

**Rio** [1:30:34]
就是说三三天一小变 ， 七天一大变 。

**吴涛** [1:30:37]
对 ， 就是 front end technology， 可能你你这个网站你所用的东西跟另外一个网站所用的东西 completely different， 没有任何一点点交集 ， 然后两个人都觉得呃 ， 自己做的才是前途 ， 或者反过来两个人都觉得对方做的才是正确的 ， 这个是非常令人让人疑惑的一件事情 。其实 。

**Rio** [1:30:58]
你这个都是高端了 ， 你像遇到那种比较低端的 ， 然后就说吼 ， 我们不是都是用 JQuery 吗 ？

**吴涛** [1:31:04]
哈哈哈 。

**柳成荫** [1:31:05]
你知道就是所谓啊 ， 就是最好的时代也是最坏的时代 。

**吴涛** [1:31:09]
对 。

**柳成荫** [1:31:10]
看你自己所处的位置是怎么样啊 。

**吴涛** [1:31:13]
对 ， 我觉得这也可能就是前端技术比较让人呃 ，有有有兴趣的一部分吧 ， 就你你总是可以看到一些新的 ， 然后看到一些有趣的东西 ， 看到年轻人的活力 。

**Rio** [1:31:26]
哈哈哈 ， 对 。

**柳成荫** [1:31:28]
这从从一定程度上来讲的话 ， 它也是啊 ，有就是技术也有很固定的时候 ， 比方说算是阶段性发展吧 ， 你知道就 JQuery 有 JQuery 的一段时间大家都用 JQuery， 然后 Backbone 有一段时间大家都用 Backbone， 然后我觉得我们可能之所以这么就是现在这么精彩 ，是因为我们在进入一个新的阶段啊 ， 从我的角度来说的话 ， 我觉得 React 是最 promising 的一个 solution，因为 Angular can shoot itself in the foot， 对不对 ？

你要 。

**Rio** [1:31:57]
哈哈哈 。

**柳成荫** [1:31:58]
没办法 ， 这个对啊 ， 所以 。

**Rio** [1:32:01]
太复杂了他们那个 。

**柳成荫** [1:32:02]
所以啊 ， 我而且它那个 2.0 跟 1.0 又不匹配 ， 然后 2.0 又再又又需要那么长时间来开发 ， 所以所以 Angular 有点就是啊 ， 就是自身的那个可能 。

**Rio** [1:32:13]
即将作死 。

**柳成荫** [1:32:14]
哈哈哈 ， 真的真的有点这个意思啊 。

**Rio** [1:32:16]
哈哈哈 。

**柳成荫** [1:32:17]
所以 React 啊 ， 很可能就是下一个阶段的一个一个一个主力了啊 。

**Rio** [1:32:22]
嗯 。

**柳成荫** [1:32:22]
所以我不管你对啊 ，React 自己本身什么怎么想 ， 我觉得作为一个前端的开发者的话 ， 真的应该去了解它啊 。

**Rio** [1:32:30]
OK。

**柳成荫** [1:32:31]
至少知道它为什么好啊 ， 或者它哪里好啊 。

而且从公司的支持来说的话 ，Facebook 对啊 ，React 的支持是非常非常强烈的啊 ， 你可以看到它它从啊 ， 它最初是最初最初的模型是那个 Facebook ads group 啊 ， 就是 ads group 来来做出来的 ， 然后现在后来到 chat 到大部分的前端 ，他们所现在写的都是 adopt 这个 React， 到你知道 group 现在又用那个 React Native 写 ， 所以 React 背后有非常多 Facebook 的支持 ， 反观 Angular 反倒是在 Google 里头啊 。

**Rio** [1:33:08]
它自己都不怎么用吗 ？

**柳成荫** [1:33:09]
对 ， 我们并不知道特别多的 Angular 所写的应用 ， 那个 inbox 倒是倒是一个倒是一个啊 ，Angular 的案例 ， 对不对 ？

**Rio** [1:33:17]
Inbox 不是啊 。

**吴涛** [1:33:19]
上次 Rio 上次 Rio 说是 GWC 写的 ， 然后我成功的破碎了这个谣言 。

**Rio** [1:33:25]
对 ， 它它是这样 ， 它就它是两部分嘛 ， 它的前端那部分不知道没有说 ，但是后就是那个业务逻辑那边它是 Java 转过去的 。

**吴涛** [1:33:33]
对 。

**柳成荫** [1:33:33]
OK。

**Rio** [1:33:34]
OK。

**柳成荫** [1:33:34]
就是说 。

**吴涛** [1:33:35]
I have no other business here like you don't code me on that. OK。

**Rio** [1:33:38]
对 ， 就有很有可能就是它它的这个 inbox 的这个网页版的前端可能是用这个 AngularJS 写的 。

**吴涛** [1:33:44]
对 。

**柳成荫** [1:33:44]
对 ， 还有它或许有很多 internal tool 用用 Angular 写 ，但是我们并没有看到很直很多直接的支持 。 我觉得这一点上对于那个技术本身的发展是啊 ，不是很不是特别好 ，因为你 。

**Rio** [1:33:56]
没有干爹支持 。

**柳成荫** [1:33:58]
对 。

**Rio** [1:33:59]
哈哈哈 ， 天 ， 这个是个很大的问题 。 嗯 ， 我们看看看选技术 ， 技术选型的时候要先先看爹嘛 ， 对吧 ？

你看我选了 go。

**柳成荫** [1:34:08]
真的是这样子 。

**Rio** [1:34:10]
啊 ， 那我们接下来说一下那个 Relay 吧 ， 这个还是要留到下期还是怎么样 ， 还是一次过把它讲完好了 。

### Relay与GraphQL

**Rio** [1:34:19]
啊 ，他们这次这个 React 大会上面除除了发布这个激令人激动人心 ， 什么令这个 WebApp 可以秒杀这个 iOS 或者安卓 。

**吴涛** [1:34:30]
Ground breaking。

**Rio** [1:34:31]
就直接直接就秒秒试了的这么一个什么 ， 对 ，ground breaking 的技术之外， 还发布了一个其实作为一个前端开发 ， 半个前端开发者的我来讲 ， 这个还是非常令我激动的 ， 叫做一个 Relay 的这么一个技术啊 。

**吴涛** [1:34:46]
嗯 。

**Rio** [1:34:46]
这个事情跟之前讲的那个 Flux 是有或多或少的关系的啊 ，因为他们在去年发布那个 Flux 架构的时候并没有说 ，因为 Flux 它只是一个 idea 嘛 ， 刚才 Willow 也讲了 ， 它并没有说告诉你一些具具体的执行的措施是怎么样子的 ， 然后其中有一个很一个就是任何一个 WebApp 都都逃不掉的问题 ， 就是你怎么去从服务端获取数据嘛 。

**吴涛** [1:35:08]
对 。

**Rio** [1:35:09]
然后在这个传统的方式下， 那可能很就最简单的 ， 我就用 JQuery 写个 ， 或者用那个什么 HTTP XML HTTP request 发一个请求 ， 然后回来用什么一个 callback 就更新了一下这个 DOM， 这个可能是最最原始的一个从服务端取数据 ， 然后在一个 WebApp 里面展示的方法 。

但是到了一定层级之后， 这种方式就是完全是不可以管理的嘛 ，有很多很多奇奇怪怪的问题要解决 。

**吴涛** [1:35:33]
没错 。

**Rio** [1:35:33]
然后他们这次发布的这个 Relay 呢 ，其实就是要解决这么一个问题 。 啊 ， 哎 ， 我不知道 Willow 你们在之前的时候是怎么去做这个从服务端获取数据这么这么一个过程的 。

**柳成荫** [1:35:45]
嗯 ， 啊 ，因为我们都啊 ， 之前都是在用那个啊 ， 传统意义上的啊 ，MVC 的 model 嘛 ， 我们还没有到 ， 我们我们并没有使用 storage 的概念 ，但是我觉得 store 的概念可能跟啊 ， 那个 model 是可以 map 的啊 ， 所以然后我们的后台是一个 RESTful API。

**Rio** [1:36:04]
OK。

**柳成荫** [1:36:05]
在在前端我们有 model， 然后这个 model 啊 ， 它可以去跟那个后台去 sync，right？ 然后这个 sync 是一个啊 ，RESTful 的 HTTP request， 然后那个 server 会把你所获取需要获取的信息给发送回来 ， 然后这样 model 就有了 ， 就就就得到了这个所有需要的信息 。

**Rio** [1:36:24]
那么这里就有一个问题啊 ， 就是说刚才我们那个可能要介入这么一个新的这个一个一个概念 ，也比较新 ， 如果你做前端开发 ， 肯定会遇到就是 REST 的这么一个一个 API， 那什么意思呢 ？

就是说它起码它就说把我把这个我后台我能够提供的所有的资源嘛 ， 一个 resource 通过一个这个 URL 的这么一个节点暴露出来 ， 然后你通过像什么标准的什么什么 put delete 啊 ，post get 这些方法去获取这些这些这些呃资源嘛 。

但是这有一个问题就是说啊 ， 我不知道你们那边是不是怎么样子 ， 就是我我看到的大部分的这个 REST API 都有一个共同的问题 ， 就是它有太多的这个所谓 endpoint， 太多的节点了 ，因为每一个资源叫对应一个节点嘛 。

**吴涛** [1:37:03]
没错 。

**Rio** [1:37:04]
然后包括如果 Willow 你讲的这种情况 ， 如果我理解的没有错的话 ， 你们你们也是说每一个 model 应该是对应一个一个 resource， 一个资源 ， 然后这个每个 model 去负责去那个节点的那个那个那个资源对应的 REST 的节点去访问它 ， 对吧 ？

但是我觉得其实这样管理和编写起来都不是很方便 ，而且在使用起来我觉得有很多问题 ， 就我我先讲讲我的体验怎么样子啊 ， 感觉首先一个刚才讲那个节点太多 ， 你要为每一个资源增就增加一个节点 ， 然后你要考虑每个资源它能够支持的这些这个所有的这些动词嘛 ，verb 它对应的一些所谓的这个这个语义是什么 ， 比如说我有一个 user， 如果我 put 这个

user 是一个什么意思 ， 对吧 ？ 然后我 post 这个 user 又是一个什么意思 ， 然后 delete 当然可能更好理解一点 ，但是又会牵涉到资源的种类又不一样 ，有所谓的什么 collection， 然后有所谓的 individual 啊 ， 这种这种 resource 其实很多事情还是不是那么清晰的 。

**吴涛** [1:37:56]
对 。

**Rio** [1:37:56]
啊 ，而且这个 REST 本身的定义就是很多人有很不同的理解嘛 ， 虽然那个最开始那篇博士论文里面有把这个概念阐述得很详细 ，但是我我我可以确信绝大部分做 REST 的人都是没有看过那篇博士论文的 。

啊 ， 然后 REST 我觉得还有一个问题就是说它的那个这个就约束太多了 。 首先一个一个约束它就是说 ， 比如假设你要要要暴露出来一个 user 这么一个节点 ， 这么一个资源 ， 可能代表的是某一个啊 ， 一个账号体系的一个用户 ， 对吧 ？

它返回给你的数据肯定是固定结构的 ， 就是你取一个 user， 你就取到它所有的信息 ， 比如说你要取它的这个用户名 ， 这个 email， 它它会把那个所有的详细的信息都返给你 ， 哪怕你只是需要用它的这个所谓的一个用户名来显示这显示出一个或者一个头像来显示出一个一个所谓的那个头像框而已 ， 对吧 ？

**吴涛** [1:38:46]
对 ， 你没有它对于它的更为精细的控制 。

**Rio** [1:38:49]
对 ， 就每对每一个资源来讲 ， 你比较难去说你你再做一些更精细的要求 ，而且就是它所谓的这个可组合性也比较低 ， 比如说呃 ， 就是最举个最简单的例子啊 ， 我有一个 user 这么一个节点 ， 然后我有一个像一个 post， 就一个一个一个文章或者帖子这么一个节点 ， 我想在取到说这个用户发过的那个文章的时候 ， 你会牵涉到一个很麻烦的问题 ， 就是说你把这

个这这个对应的请求 ， 它显然不不是完全归属于用户那个节点了 ， 它也不是完全归属于这个 post 那个节点 ， 对吧 ？

**吴涛** [1:39:23]
嗯 。

**Rio** [1:39:24]
就有一些这种很不正交的东西出现在里面 ，而且你有办法很很方便的在同一个请求里面去同时取这两个不同的东西 ， 就它们的这个可组合性我觉得是比较比较低的 。

**吴涛** [1:39:35]
没错 。

**Rio** [1:39:35]
然后最后最后一个呢 ， 就是说我实际用的体验中就是因为这个大部分的 REST API 是通过 HTTP 的这种方法去访问的嘛 。

**吴涛** [1:39:43]
嗯哼 。

**Rio** [1:39:44]
然后我们现在用的 HTTP 所谓的 1.0、1.1 这个版本 ，有一个问题就是说它有一个很严酷的就是 request response， 就是请求返请求答复 ， 请求答复这么一个流程 ， 你不可能说我发五个请求出去 ， 然后等五个回复出来 ， 对吧 ？

这样而这样这种这种一个有个效率的问题 。 那么很多人就为了解决这个效率问题 ，他要去考虑说我把这个请求所谓打包 ， 就是 batching 嘛 ， 比如我把啊 ， 我要请求五个用户 ， 或者说请求五个用户三个文章 ， 我要把这几个请求包在一起 ， 然后发一个请求过去 ， 这个时候你用 REST API 的话就不是非常好做了 。

**吴涛** [1:40:17]
没错 。

**Rio** [1:40:18]
所以所以总体来讲 ， 我觉得 REST 在它的它的逻辑是很好的 ， 就是说整整个概念是非常方便 ， 它是 ，但是我觉得它始终是一个更适用于那种所谓面向文档的呃 ， 这种类型的应用是比较好的 。

但是在我们目前在做的很多这种面向一些什么社交网络也好 ， 还有其他一些更新形态的应用的时候 ， 用 REST 这种 API 其实我觉得并不是一个特别好的选择 。

**柳成荫** [1:40:43]
嗯 ， 我我我吃饱了就讲 ， 我觉得啊 ， 就是我们所看到 Relay 它的确在解决啊 ， 另外一 set 的 problem，但是啊 ，而而而且是非常有意非常有意义的一个一个一个解决方案 。However， 我总总总归是觉得啊 ，Relay 它的它它的意义更在于是帮助像 Facebook 这样大型的公司来来管理它的复杂度 ，因为只有在那个规模上你才会在意那么小级别 ， 就是说到底是哪个啊 ， 哪个 view 得到哪个 field

来有减少那个带宽的需求 ， 然后同时又更好更好的封装和保护不同的数据 ， 这是非常有意义的事情 ，但是我觉得还是跟那个规模是相关的 。

**Rio** [1:41:29]
就小公司其实是不需要这种复杂的需求的嘛 。

**柳成荫** [1:41:32]
啊 ， 我对啊 ， 从从很大程度来说我我觉得是这样子 ，但但是 again， 这这也是跟你一个那个你所要解决的问题所那个 available 的方案是有相关的啊 ，而且从一定程度上来讲 ， 如果你在 RESTful API 的基础上加上一些啊 ， 一些控制的变量 ， 比方说啊 ，Facebook 自己本身的那个 graph API 有一个叫 fields 的概念 ， 就是你你你 fields 会帮助你啊 ， 控制它所返回的那个 attributes 到底是哪一些 fields， 这跟

这跟 Relay 中的一些概念是非常相似的 ， 非常 map map 的啊 。 我也可以预见就是在 Relay 真正的发布的时候 ， 会有人给啊 ， 传统的 RESTful API 写一些 adapter， 然后从而啊 ， 让那个传统的 RESTful API 也支持这个 Relay 的啊 ， 实现方式 。

**Rio** [1:42:27]
就刚好昨天那个啊 ，因为 Relay 现在还没有 ， 它只是发布了这个概念 ， 它并没有公布它后面的一些产品啊 ， 然后昨天在那个 Hacker News 上面 ，Facebook 他们有个叫做呃 ，Vincent，不是 Vincent，是 Vincent 这么一个人 ，他他不是在 GitHub 上写了一个 Relay 的一个 FAQ 嘛 ， 常见问题解答 ， 然后他他上面我就问了他们他们这么一个问题 ， 就是说 Relay 它很依赖一个核心的组件 ， 就是那个什么 GraphQL 嘛 ， 就是这个图呃 ，

查询语言 ， 这个是跟 Facebook 他们后台有个叫做 TAO 的一个图数据库紧密相关的 ，但我不太清楚就是说对于一个第三方 ， 就是作为一个 Facebook 以外的人， 或者说中小开发者或中小网站 ， 你没有一个基于这么一个图的啊 ， 结构的后台的话 ， 你怎么去去呃 ， 适应这种 GraphQL 的要求去做到 Relay 这种效果 ， 我觉得还是很很大的一个疑惑 。

**吴涛** [1:43:21]
OK。

**柳成荫** [1:43:21]
嗯 ， 这这是一个机会啊 ， 这是一个这是空白 ， 市场现在是空白的 ， 对不对 ？

**Rio** [1:43:26]
对 。

**柳成荫** [1:43:26]
然后如果如果如果呃 ， 我们有听众啊 ，you know，like， 想要在呃 ， 借此机会来写一个什么 open source library， 或者是甚至于开一个东西的话 ， 我觉得这个机会是有可能存在的啊 。

你要知道这个啊 ，GraphQL 它最终啊

， 最终即使是 open source 啊 ，不是即使就是最终它会有 open source，但是我们需要等一段时间 ， 它的 open source 之后呢 ， 啊 ， 它也更多的是作为一个 protocol 的存在 ， 就像 Flux 一样 。

**Rio** [1:43:58]
对对 。

**柳成荫** [1:43:59]
真正实现呢 ，是需要是用根据它所用的那个软件来来来来实现的 。

**吴涛** [1:44:07]
对 ， 我觉得有点像像 SQL， 你可以你可以做一个 GraphQL database， 然后或者说呃 ， 类 database 的 GraphQL server， 然后这个 server 可能会会会说一种 GraphQL 的 dialect， 然后呃 ， 带某种扩展就就和 SQL 一模一样 。

**Rio** [1:44:27]
对 ， 没错 ，他们就算 Relay 以后发布的时候 ， 它也只会包含首先第一个是客户端的那个 GraphQL 那些组件嘛 ， 比如说它可以在每一个 React， 它可以在每个 React 组件里面声明你那个组件需要哪一个哪一种类型的数据 ， 然后它可以通过这个 Relay 的这个 library 去把这些这些需求都都一一次抽出来 ， 然后往服务端发一个请求就可以解决 ， 包括它会帮你去做好刚才讲的那个 batching 啊 ，

就是这个就是就是请求打包 ， 包括哪些是可以重用的请求就可以不用发送嘛 ， 包括那个本地的这个缓存它都给你解决了 。

但是我觉得始终是在反而就问题在客户端那边 ， 呃 ，在服务端那边你是没有办法 ，因为它最终它只会给你一个 GraphQL 的这个那个叫什么 parser， 然后它会给你一个语法树 ，但你怎么去满足它每一个这个 GraphQL 写的这么一个查询 ， 你还是要要挺费脑筋的 。

而且我觉得这不是一个呃 ， 小小企业或者是个人能够很轻易做得到的事情吧 。

**柳成荫** [1:45:26]
对 ， 我很期待看到有人做一个啊 ，RESTful API 的 adapter，因为虽然说虽然说他们两者的那个啊 ， 概念上有区别 ，但是实际上最终啊 ，GraphQL 和 RESTful 都是访问数据的一个方式嘛 ， 所以说他们他们两个之间是有可以 map 的地方的 。

所以如果说有人能做一个啊 ， 比方说 reels， 你知道 reels apps， 你肯定可以有人做一个 reels 啊 ，GraphQL， 然后一个一个一个一个 gym， 你把这个加上之后， 那个它的那个 RESTful API 就可以通过这个 adapter 来来啊 ， 实现 GraphQL。

我觉得对这个可能在性能上会有些损失 ， 然后也不是说直接你实现了 GraphQL，但是对于推广这个技术 ， 你应用这个技术是是是非常有好处的 ，因为 。

**Rio** [1:46:12]
就作为一个过渡方案 ， 对 ， 作为一个过渡方案应该是挺好的 ， 对吧 ？

**吴涛** [1:46:16]
嗯 。

**Rio** [1:46:16]
所以我就还是在想 ，因为之前在知乎的时候 ， 我的很大的一部分工作就是在琢磨这些乌七八糟的有的没的图的结构嘛 ， 然后其实我我后来的一个体验就是说其实真的是蛮难的 ， 就是作为一个普通的团队 ， 你像很多这种所谓的 Web 应用 ， 它都是一个什么啊 ，mysql 一个后台 ， 然后前面加封一个 REST 的一个一个 API 层 ， 然后再加几个 Redis 的这种啊 ， 叫什么 ， 就是缓冲层嘛 ，

然后就可以它就可以满足一个中型网站的应用了嘛 。 但是你要实现像那个 GraphQL 那么灵活多变的查询 ，而且要达到那种那种呃 ， 那种好用程度 ， 你真的是要后台要做很多工作才能够实现这个 Graph 的结构的 。

**吴涛** [1:47:01]
就这个 GraphQL 出现后， 我发现就是其实这一个抽象层级的需求是非常明显的 ，但是在它做出来在 GraphQL 出现之前 ， 好像没有人去讨论它 。

**Rio** [1:47:13]
有可有是有的 ， 就是但是就说因为 。

**吴涛** [1:47:16]
呼声不够大 ，因为它不是 Facebook， 没有吸引到足够的眼球是吧 ？

**Rio** [1:47:19]
我觉得主要是因为现在的主流就是呃 ， 就除了像 Facebook 这种巨头能够有精力或者有这个资源去把它的后端做成一个这种类这种结构的方式去查询的话 ，其他那些中小企业真的是还蛮难 ，因为没有一个现成的 ， 或者说被像 mysql 这种级别能被大众广泛接受又好用的就是图数据库嘛 。

呃 ，有几个例子像什么啊 ，Neo4j 啊 ， 那个什么 OrionDB 啊之类的 ，他们但是就是你可以看到就成功案例很少 ， 就是你首先一个熟悉程度也就它的成熟程度本身也不够 ， 然后就是大家也不太敢用 ， 然后这样的话就会反而导致这一块其实是在市场上是很弱的 。

我倒是希望说说这个 Relay 或者说 GraphQL 这个呃 ， 正式开源出来之后， 大家会真呃 ， 意识到这个的好处 ，以及对这个包括前端啊 ， 开发的这个啊 ， 这个难度的降低哈 ， 然后包括后端的开发的成本的降低 ， 然后能够使得大家更多去思考 ， 哎 ， 那我要不要用一下这种图呃 ， 就以图为呃 ， 主要结构的这种数据后台 。

**吴涛** [1:48:24]
对 ， 这也算是呃 ，Facebook 对于整个 Tech stack 做出的一个贡献吧 。

**柳成荫** [1:48:30]
哈哈哈 。Actually 啊 ， 那个 Rio，you mentioned 那个图图啊 ， 结构的呃 ，database， 我我其实我我就是就是 honest question 啊 ， 我我并不清楚这个东西 ， 它那个命名是一个出于一个一个 branding 的考虑 ， 还是它真的就是所谓图 。

我我我我没有听说过图 database， 就是 honest 没有听说过 。

**Rio** [1:48:55]
啊 ， 对 ， 这个这个是一个相对于没有那么大众的一个应用嘛 ，其实图数据库要解决的问题也是蛮简单的 ， 就你可以想象一个一个普通的是一个社交网络 ， 就能只有一种只有一种类型的节点 ， 我们就考虑最简单的一个情况 ， 就我们有有这个用户嘛 ， 就 user 你和我 ， 然后无他我们三个人， 然后图数据库存储什么 ， 就就就存储节点嘛 ， 我们这个本身节点

有些是有些什么样的属性 ， 比如说我作为一个人， 这个 user 这么一个一个节点有什么名字 、 性别 、 年龄 、 出生日期啊之类的一些什么 attributes 嘛 ， 对吧 ？

啊 ， 这个是这个是跟传统的包括这种我们像 mysql 这种就是 RDB， 我们就 relational database 其实是没有太大区别的 ， 就是就无非就是说每一个节点对应 relational database 里面的一个一行啊 ， 一个 role， 然后每一个 attribute 就对应对应它的传统的 relational relational database 的一个 column， 对吧 ？

**吴涛** [1:49:50]
对 。

**Rio** [1:49:50]
然后啊 ，但是一个图数据库更加重要的一点其实是存储这个节点与节点之间的关系 ， 比如好像说我可以说我可以 friend 你们两个 ， 你们可以两个之间互相 friend， 那我可以啊 ， 然后你我你可以和别的人也就是互相那个 friend， 这个时候的话 ， 这个时候它表现出来的呃 ， 结构 ， 如果我们在传统的一个 relational database 里面去实现会怎么样 ， 会通过一个 。

**吴涛** [1:50:14]
表 。

**Rio** [1:50:14]
另外一张表来做一个这个那个什么链接 ， 说你对另外比较假假设比较多叫做关注的就会写 。

**柳成荫** [1:50:21]
Sorry to cut you off， 我我只是做一个 check 而已 ， 所以啊 ， 谢谢你的解释 ，但是我们还是不要吧 ， 我觉得这这段就不用在那个 podcast。

**Rio** [1:50:31]
没事 ， 可以可以可以可以放进来接着解释完 ， 就很多人不理解嘛 ， 就听众里面可能不是很熟悉这个概念 ，因为这个确实在工业中我也用的不多了 。

**柳成荫** [1:50:39]
也对 ，因为对我来讲的话 ， 我觉得就是说那个 GraphQL 所谓 Graph 只是一个 branding 而已 ，并不是并不是真正在啊说 。

**Rio** [1:50:47]
啊 ，不 ， 它真的是就说 GraphQL 本身它真的是要有这么一种呃 ， 对对后端其实是有很大要求的 ， 你才可以做到它那么灵活的查询 ，不然的话你可以做 ， 你可以去用那种像 adapter 的方式去把 GraphQL 的查询转换成对应的这个 REST 的查询 ，但是这样的效率非常低 ，因为这个整个你的这个后台的数据库的组织的结构就不是按照一个那种图的查询的方式来来查询的 ，因为图

里面查询的最常见的什么啊 ， 就是便利嘛 ， 节点便利嘛 ， 对吧 ？ 这个在你的 RDB 这个什么 ，在如果在一个传统 relational database 里面做 ， 你这个性能是作死的 ， 你想一下你要假设你在一个社交网状那个图里面 ， 你要从某个节点为中心查询他的好友的话 ， 你在一个传统的这个 relational database 里面 ， 你要去要查好多张表 ， 你要不然你要查三个维度的好友 ， 就是三

就是什么三度分割的好友的话 ， 你要用那个传统的 relational database 查询的话 ， 这是非常困难的 。 所以所以我就是在想就是说呃 ，其实现在有这么多的社交场合的应用 ， 反而是没有一个呃 ， 基于能够很好满足社交查询的这么一种数据存储的引擎能够大规模的方便的使用 ，其实是蛮悲哀的一个现状 。

**吴涛** [1:52:04]
其实也是挺奇怪的 。

**Rio** [1:52:07]
哈哈哈 ， 难做嘛 。 这确实挺难的 。 哎 ， 就就比如说我们传统的作为 relational database， 你可以性能不够 ， 你可以做简单的说什么 sharding， 就分割嘛 ， 按照这个按照这个 key 的这个范围来分割嘛 ，但是你怎么去分割一个图呢 ？

这很难的一件事情 。

**吴涛** [1:52:25]
对 。

**Rio** [1:52:26]
所以就里面还是有很多这种非常 hardcore 的 computer science 的东西在里面要要解决 ，而市面上现有的解决方案都给人一种信心不足的感觉 。

真的啊 ， 就我就其实这段我就是蛮蛮蛮担忧的 ， 就是说如果这个解决不好 ， 那个 GraphQL 这种东西就真的是只能局限于像 Facebook 啊 ， 像 Google 啊这种庞大的企业 ， 它能够有这个资源或者这个能力去实现自己的或者维护自己的这么一套基于图的 ， 或者是以图结构为导向的这么一个呃 ， 后台系统 ， 否则其他人还是只能很呵呵的继续用着 REST。

**吴涛** [1:53:04]
啊 ， 对 。

**Rio** [1:53:05]
哈哈哈 。 呃 ， 对 ， 那个什么 ， 那 Willow 你说一下就整个就说刚才我们讲的这个 React 相关 ， 还包括你在会上看到一些东西啊 ，但是你说整个来讲 ， 你对这个会本身是什么样的一个感受 ？

### 总结

**柳成荫** [1:53:21]
这是我啊 ， 所去过的比较好的一个会议之一了 ，因为啊 ， 整个的所有的 speech 都非常的有意义 ， 非常能觉得从中能够学到东西 ， 都不是在也都都非常有意义 ， 非常 hardcore CS， 我觉得这一点是非常非常难得的 。

啊 ， 那个会的组织者肯定做了很好的工作来啊 ， 选取这些啊 ， 这些演讲者和演讲本身 。 嗯 ， 啊 ， 我们有非常多的那个 social 的机会 ，在其中也遇到了非常非常多人， 然后 React 现在真的是被应用到各种各方各面啊 ， 很多你想不到的啊 ， 一些啊 ，application 都在使用 React， 都在或者在考虑使用 React 啊 ， 非常的激动人心的 ， 就是可能看到这么多啊 ， 实际的应用 ， 这么多

啊 ， 积极主动来参与这个社区的人啊 ， 所以整整体来说 ， 我觉得是个非常非常非常好的啊 ， 一个气氛 ， 大家都非常啊 ， 对这个 React 的前景都非常乐观啊 ， 我也很高兴看到 Facebook 对整个会议的支持 ， 跟对整个这个啊 ，React 技术的支持 。After hours 啊 ， 我也觉得非常开心能够得到这个 React native 的一个 preview 啊 ， 我有给我的同事演示啊 ， 这对我们做接下来的一些啊 ，technology

选项都是非常有帮助的 。

**吴涛** [1:54:48]
所以贵公司贵公司也是要出一个 mobile 领域的客户端的吗 ？

**柳成荫** [1:54:52]
啊 ， 我们一直有啊 ， 那个 mobile 的客户端 ， 我们有 iOS 跟 Android 的客户端 ， 然后哦 ，well, foreseeable future 肯定不是 React native， 对不对 ？

但是啊 ， 对于那个技术的选型 ， 观察这个技术的发展来说的话 ， 我们肯定现在是啊 ， 把它是摆在一个比较重要的位置了 。

**Rio** [1:55:11]
OK， 对 ， 没错 。OK， 那行吧 ， 今天我们非常高兴邀请到 Willow 来跟我们讨论这个 React 啊 ， 包括一的一系列相关的东西哈 ， 然后那今天的节目就到此为止吧 ， 谢谢大家 。

**吴涛** [1:55:26]
谢谢大家的收听 。

**柳成荫** [1:55:27]
谢谢大家 。

**Rio** [1:55:29]
啊 ， 我们下期再见 。

**吴涛** [1:55:31]
呃 ， 我还要念那个吗 ？

**Rio** [1:55:33]
你念吧 。

**吴涛** [1:55:34]
OK， 啊 ， 感谢大家收听 《 内核恐慌 》， 呃 ，也欢迎大家收听 IPN 旗下的其他五档 podcast 啊 ， 包括技术主题节目 《IT 公论 》， 呃 ， 医疗主题节目 《 太医来了 》， 美食节目 《 未知道 》，以及呃 ， 艺术类节目 《 流行通信 》。

嗯 ， 最后还有不知道是在播什么的无主题节目 《 无次元 》。 感谢大家的收听 。

---

本节目库由 PodHood（https://podhood.com）提供支持——播客网站平台。
