原文: https://medium.com/@fusetools/how-fuse-differs-from-react-native-and-nativescript-525344f02aaf
现在有很多不同的框架和工具可以用来构建移动应用,我们得到最普遍的一个问题就是:Fuse 和 XXX 有什么区别?
有的时候,这就是 Hybrid 应用和原生应用的区别,或者是创建一个原型和创建一个完整应用的区别(Fuse 实际上可以帮你无缝地从一个原型到完成一个完整应用),但通常我们需要更近一步说明。
我趋向于讨论 Fuse 背后的理念和视角。比起挖掘技术细节,我们更会去关注 Fuse 更高的目标以及它是如何帮助用户的。
这包括:
不过所谓 理念 ,仅在它有了明确的结果后才是有用的,对于开发来说更甚。
这也是为什么我希望更近地去看 Fuse 的一些功能,并解释它们和那两个框架的区别,一个是 Facebook 的 React Native,一个是 Telerik 的 NativeScript。
乍一看,Fuse、NativeScript(NS)和 React Native(RN)可能看上去很相似:
不过,如果你更进一步去看,Fuse 的目标以及它如果达到它的目标的方式都是很不一样的。
一个关键的区别在于,Fuse 仅在应用逻辑上使用 JS,其他地方全部生成原生代码,包括构建和操作 UI。
当你从 Fuse 导出一个应用的时候,它将你使用的整个框架和标记转化成 C++ 源代码,之后这个代码会被原生平台工具(Xcode 和安卓的 SDK / NDK)编译。你也可以把 Java 和 Objective-C 代码加入同一个项目一起编译,或者是简单的链接一个原生库。
与之不同的是,NativeScript 和 React Native 更依赖于 JavaScript 为它们做多数的事情。NS 通过给 JS 暴露原生 API,分发调用并即时转换数据。RN 也比较类似,不过它是通过调用原生代码实现的更高阶的函数。
你可以说 RN & NS 是自顶向下的:它们先用 JavaScript 完成需求,然后把其他东西填充进去。而 Fuse 是自底向上的,我们先从跨平台的原生代码和 UI 开始,然后再加入 JavaScript 代码,来轻松地完成一个应用。
让我们感觉到 “越是原生的越好” 的一个主要原因是:性能。
虽然 JavaScript VM 变得越来越快了,但它们绝对不会比编译后的原生代码快,这个速度的差异还是需要留意的。更高效的代码意味着你可以在你的应用里做更 cool 的东西,它可以在你的老设备里正常运行,并且也不是很耗电。
这引出了另一个相关点……
如果你想要 60FPS 的丝滑视觉效果,那么就不要让任何东西(比如较慢的 JavaScript 执行)阻碍你的 UI 更新。
在 Fuse 里,保函业务逻辑代码的 JavaScript VM 在单独一个线程运行,而其他 UI 的工作则是在另一个线程使用原生代码运行的。这两者的联系是通过响应式的数据绑定来完成的,这实现了职责的分离。
UI 自身知道(之所以知道,是因为在 UX 标记上定义了,之后会说到)在按钮点击的时候导航到另一个页面,或者新的数据添加的时候列表应该有一个动画效果,所以它不会因为 JS 的执行而影响动画的更新。
作为比较:NS 始终在单线程运行 JavaScript 代码,虽然它可以调用平台 API,但依然会因为 JS 的运行,导致 UI 更新出现卡顿。
RN 比 NS 利用了更多的线程,但 UI 层依然比 Fuse 更加依赖 JS 代码的运行:维护和差异化 RN 的虚拟 UI 树,以及线程之间通信时频繁的数据序列化和反序列化都会引入额外的 JS 任务,从而会减少多线程带来的好处。
这 3 种解决方案都提供了标记语言来处理 UI,但它们的区别是很大的。在这个方面,Fuse 显然是面向任何构建应用的人,而其他两者是面向 JS 开发者的。
UX 标记在 Fuse 的主要部分,是用来描述 UI 和用户体验是如何被创建的。
这是一个针对布局、动画和用户输入设计的标记语言,即便不是程序员,也很容易学习它。
UX 是用来定义任何的视觉效果和交互相关的效果,所以它提供了更多的对于视觉与感觉方面的控制。而 NS 和 RN 依赖于 CSS 的子集和传统的 XML 用于基本样式的声明,它让开发者更加纠结于代码。
换句话说:Fuse 使用为前端定制的标记语言,而让你不用碰任何代码。
这不仅对于设计师来说很有好处,而且对于开发者来说,它们可以创建更好看的应用,并且 UI 和业务逻辑完全分离。
并且之前也提到过,任何你通过 UX 标记创建的东西都会变成 C++ 代码,并独立于 JS 运行。这和另外两者是很不同的,在运行时通过 JS 解析 XML(或者将 JSX 转化为 JS)。
【译者注】自己没有写过 RN,不过在写 React 的时候,上线代码里,JSX 肯定是已经被转换好了的,所以作者这边的理解待考证。
除了传统的平台组件外,Fuse 也提供了完全可自定义的 OpenGL ES-accelerated UI。这是另外两种框架无法提供的。
【译者注】对 OpenGL 不了解,不过这里有一段对 OpenGL ES Standard 的描述:OpenGL® ES is a royalty-free, cross-platform API for full-function 2D and 3D graphics on embedded systems - including consoles, phones, appliances and vehicles.
这意味着你可以创建完全自定义你想要的 UI,并且运行时保持 60FPS 的流畅。你甚至可以添加实时可视化效果,比如动态投射阴影、模糊和玻璃蒙版,甚至其他更多的效果。
Fuse 允许你构建标准平台 UI 或 HTML 以外的东西。
这些 UI 在所有平台上看上去都是一致的,或者你也可以在你的项目里定义安卓和 IOS 平台的差异。这样你就可以得到最大化的代码共享,对于前端也是这样。
你甚至可以结合原生平台组件和自定义组件。比如在一个完全自定义的应用里使用原生地图组件。或者在一个标准的原生 UI 里使用一个特殊的地图组件。
这种 UI 的另一个好处是你可以在编辑的应用的时候,使用我们的桌面预览窗口查看效果。
Fuse 同样也是为设计师准备的,虽然一些人觉得使用标记语言是 OK 的,但更多的人更希望有可视化工具。另外,从其他工具里导入素材的功能对他们而言也很有用。
当然,对任何人而言,前端的工作是在不断迭代的。即便是使用文本编辑器加上终端的中坚程序员也应该可以发现一个选色器或是一个调整字体大小的游标是很有好处的。
这些功能的早期版本(原型)已经被加入到 Fuse 中一段时间了。需要指出的是:一个帮你实时调整 UX 属性的检查器和 Sketch 导入工具。不过这只是一个开始。我们现在正在在 Fuse 中构建一个更加大型的工具组,来组成一整套可视化工作流,从布局到动画,手势,还有导航。
从这一点而言,NativeScript 和 React Native 都无法提供这些。
还有,不过带有些偏见,我想说的是 Fuse 的架构让这一切变的可能。既然 “一切皆可视,一切皆可触”(everything visual and interactive)是通过 UX 来完成的,那么你就拥有的强大工具,就是一个基本的 WYSIWYG(所见即所得) 的 XML 编辑器。
这和我下一个观点有关……
这三种解决方案都提供了一些 hot reload 的功能,在我们对代码做出一些改动的时候,自动地将这些修改应用到所连接的设备上。这显然对我们是很有用处的,提供了更流畅的工作流,而不再是【改变-重新编译-部署-测试】的循环。
不过,Fuse 有一点不同,将这个概念更进一步。
首先,除了 JavaScript 的更新外,Fuse 对 UX 标记做了同样的事。这意味着即便这些都是原生代码,你依然可以在不需要重新编译的情况下调试动画、导航、动效或是其他 UX 提供的东西!
关于这一切是如何实现的,会再之后的技术文章中讨论,不过简单的说,在预览模式下,Fuse 插入了一些额外的模块代码。这个模块接收 UX 文件的更新,并自动初始化新的原生类,重现加载 UI。
接下来,这就意味着你再编辑代码的时候,都不再需要重启应用!两者的差异:
目前这些都在 Fuse 的检查器中操作,当然,一些新的可视化工具在上面也提到过了。
我觉得这说明了不同框架的理念上的不同。Fuse 专注于提供更加高效的构建应用的方式,而不仅停留于 “节省开发者的编译时间”。
希望你对于 Fuse 是什么以及它与其他开发解决方案的不同之处有所了解了。当然我并不是想说 “Fuse 是最帮的!”,我只是希望通过这篇文章,至少可以让你们了解为什么这个轮子值得造。
最好的总结可能是:
虽然 React Native 和 NativeScript 的存在,让 JavaScript 开发者可以使用原生 UI,不过 Fuse 更近一步的为开发者和设计师提供了更好的工作流,去专注于前端和用户体验。
这算是个有志向的目标,不过我们觉得我们做的是正确的。我们也绝对会听取你们的建议,所以只要你没有这篇文章吓到,你可以在 fusetools.com/downloads 下载,并用起来。
当然,这篇文章可能并没有完全覆盖到这些框架的技术差异,如果你们想了解 Fuse 的其他东西,就告诉我们。