react native imageandroid 打bundle的时候会把image打进去吗

[React Native] 加载、维护 bundle 的正确姿势 - 简书
<div class="fixed-btn note-fixed-download" data-toggle="popover" data-placement="left" data-html="true" data-trigger="hover" data-content=''>
写了5637字,被15人关注,获得了24个喜欢
[React Native] 加载、维护 bundle 的正确姿势
前言:React Native 的其中一个卖点是程序可热更新,当前官方和非官方对这类实操的完整指导不多,所以在我们的项目实践中,我们做了一套自己的方案,iOS 侧已经上线运行,理论上和实践上没啥问题,这里梳理出来,一方面作为后续我们在 Android 的对齐基准,另一方面与大家共享思路方便探讨调优。
要做好 React Native 的热更新,主要需要处理好如下几个情况:
本地启动:为保证启动速度,不能全部依赖线上的 bundle,需保证还未下载到 bundle 的时候,能如常载入 bundle 并启动,所以初始化 RCTBridge 或 RCTRootView 时用的 bundleURL 得指向本地而非网络;
及时更新:为实现所用 bundle 能够及时更新,需要在合适时机拉取最新版的 bundle 存放到本地,细则如下:在 app 启动时,在 app 从后台切到前台后,以及在网络状态发生变化后,发起请求拉取最新的配置信息,根据配置信息确定是否需要下载 bundle 以及后续处理。
流量节约:为实现可控的流量节约,配置信息中包含了要使用的 bundle 信息如下:
url:bundle 文件的存放地址;
token:bundle 文件的标识字符串,每次将 bundle 文件成功保存到本地后,都同时在本地保存该值,以作下次拉取到配置时的比较依据,当配置中的 token 与本地的一致,那就无需做后续的下载和更多相关操作;
urging:更新该 bundle 的紧急程度,可选值如下:
1:有 WIFI 就下载,下好后重启 app 时启用 // 不紧急的时候用这个
2:有 WIFI 就下载,下载好后,从后台切回前台的时候启用 // 免流量,界面刷新柔和,推荐这个
3:不管有没有 WIFI 都下载,下载好后,从后台切回前台的时候启用 // 耗点流量,界面刷新柔和,次推荐这个
4:不管有没有 WIFI 都下载,下载好后,立马启用 // 杀很大,一般不用这个
当读取到上述信息后,基于配置中的 token 与本地值比较是否一致确认是否结束流程,如果不一致则以配置中的 url 发起一个请求,得到 bundle 后,保存到本地,同时把配置中的 token 也保存到本地。
版本并存:为实现多版本同时并存,提供 A/B Test、灰度发布等能力,需要做到:
约定每次发布 bundle,都以新文件形式发布,新老文件并存于服务器端,客户端根据配置情况按需拉取、使用;
实现因应不同情况输出不同配置信息的能力,有两种做法:a. 搭个动态 server,提供个接口,接受表达客户端情况的几个参数,根据这些参数的不同输出不同的配置信息,客户端读取配置信息时,都通过访问 server 上的这个接口来;b. 写个 JavaScript 文件,在其中写个函数,接受表达客户端情况的几个参数,根据这些参数的不同输出不同的配置信息,把这个 JavaScript 文件作为静态资源部署到 server,客户端读取配置信息时,都通过访问 server 拉取这个 JavaScript 文件,然后将其中的内容作为 JavaScriptCore 的 code 执行一下,然后调用其中的函数来获取配置信息;由于懒得搭动态 server,我们选择了 b 做法,关键代码如下;
// versionControl.js,
// 实际上这是个全局通用的资源版本控制配置文件,
// react-native bundle 作为其中一种资源存于其中。
// 注意:这里的代码是要放到 JavaScriptCore 中直接执行的,所以高级的 ES6 语法不能用。
var latestReactNativeBundleMetas = {
url: '/react-native/1.1.0/.ios.bundle',
token: 'a69cc86aef4bd8c0a8241'
android: {
url: '/react-native/1.0.3c.android.bundle',
var versionControlGetters = {
production: function(platform, appVer, innerId) {
// 每次在测试环境测试通过后,请将上边的 latestReactNativeBundleMetas.ios 的值复制到这里。
var meta = {
url: '/react-native/1.1.0/.ios.bundle',
token: 'a69cc86aef4bd8c0a8241'
"react-native": {
meta: meta,
test: function(platform, appVer, innerId) {
"react-native": {
// 这里的值一般维持不变,使用 latestReactNativeBundleUrls.ios 的值即可。
meta: latestReactNativeBundleMetas[platform],
function getVersionControl(envType, platform, appVer, innerId) {
return versionControlGetters[envType](platform, appVer, innerId);
- (void)getVersionControl:(void(^)(NSDictionary *data))callback
if (callback) {
NSString *url = @"/config/versionControl.js";
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
[manager GET:url
parameters:nil
success:^(AFHTTPRequestOperation * _Nonnull operation, id _Nonnull responseObject) {
NSString *code = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
JSContext *context = [JSContext new];
[context evaluateScript:code withSourceURL:[NSURL URLWithString:url]];
NSArray *args = @[[PlatFormUtil isNormalService] ? @"production" : @"test", @"ios", [PlatFormUtil AppVer], @(getCurrentInnerId())];
NSDictionary *data = [[context[@"getVersionControl"] callWithArguments:args] toDictionary];
callback([data objectForKey:@"react-native"]);
failure:^(AFHTTPRequestOperation * _Nonnull operation, NSError * _Nonnull error) {
callback(nil);
错误跟踪:为实现诸如错误上报版本跟踪、问题反馈版本跟踪等需求,需在代码中提供版本号和 Build 号信息,为此,提供一个 version 模块,考虑到 iOS、Android 并存,提供了一个公共的 version.base 模块,在 version.ios 和 version.android 中分别引用并扩展平台相关的信息;
// version.base.js
'use strict';
export default class Version {
= '1.1.0';
= '/react-native/';
platformCode = 'unknown';
// version.ios.js
'use strict';
import Version from './version.base';
export default new Version({
platformCode: 'ios'
// version.android.js // 预留,尚未启用
'use strict';
import Version from './version.base';
export default new Version({
platformCode: 'android'
鉴于 version.ios 和 version.android 的代码是固定的,所以版本升级时,主要维护的是 version.base,
发布流程自动化;
一般来说,一个发布过程应该包括如下过程:
修改 version.base 内的代码,为 version 设置新的 code 和 build 信息;
通过 react-native bundle 把 bundle 生成出来,过程中注意命名,确保不与既有文件重名,输出新文件,发布之;
将上述生成的 bundle 复制一份,覆盖到 iOS、Android 项目的内嵌 bundle 文件所在位置;
然后根据新文件的路径,调整 controlVersion.js,发布之
这么个流程,人工搞是可以,不过未免过于琐碎繁琐、易于出错,所以建议搞脚本,把这流程自动化起来。这个话题的细节比较多,后边会单独撰文详述。
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
被以下专题收入,发现更多相似内容:
如果你是程序员,或者有一颗喜欢写程序的心,喜欢分享技术干货、项目经验、程序员日常囧事等等,欢迎投稿《程序员》专题。
专题主编:小...
· 207199人关注
分享 iOS 开发的知识,解决大家遇到的问题,讨论iOS开发的前沿,欢迎大家投稿~
· 27811人关注
React Native开发
· 1324人關注
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
选择支付方式:如何评价 React Native?
write native apps with React.js?
本文首发于: ,最近我们也会持续分析他,并且也在Android上做类似的实现,观点会迭代,文章会更新。- - - - - - React native充分利用了Facebook的现有轮子,是一个很优秀的集成作品,并且我相信这个团队对前端的了解很深刻,否则不可能让Native code「退居二线」。对应到前端开发,整个系统结构是这样:JSX vs HTMLCSS-layout vs cssECMAScript 6 vs ECMAScript 5React native View vs DOM无需编译,我在第一次编译了ipa装好以后,就再也没更新过app,只要更新云端的js代码,reload一下,整个界面就全变了。多数布局代码都是,所有Native组件都是标签化的,这对于前端程序员来说,降低了不少学习成本,也大大减少了代码量。不信你可以看看JSX编译后的代码。复用React系统,也减少了一定学习和开发成本,更重要的是利用了React里面的分层和diff机制。js层传给Native层的是一个diff后的json,然后由Native将这个数据映射成真正的布局视图。css-layout也是点睛之笔,前端可以继续用熟悉的类css方式来编写布局,通过这个工具转换成constrain布局。系统只有js-objc的单向调用,就是把原生UI组件的方法通过javascritcore或者webview(低版本iOS)映射到js中来,整个调用过程是异步的,这样的设计令React native可以让js运行在桌面chrome中,通过websocket连接Native code和桌面chrome,极大地方便了调试。对其中的机制Bang的一篇文章写得很详细,我就不拾人牙慧了: 。但这样设计也会带来一些问题,后面说。点按操作也被抽象成了一组组件(TouchableXXX),这种抽象方式是我在之前做类似工作中没有想到的。facebook还列出Native为什么和web「手感」不同的原因:实时的点按反馈和取消能力。 这套相应机制设计得很完善,能像Native code那样控制整个点按操作的所有过程。Debug相当方便!修改了js以后,通过内建的nodejs watcher编译成bundle,在模拟器里面按cmd+r就可以看到效果。而且按cmd+d,可以打开一个chrome窗口,所有的js都移到了chrome里面运行,所以什么断点单步打调用栈,都不在话下。上面的既是特点也是优点,下面说说缺点,或者应该说:「仍然遗留的问题」,在我看来,这个方案已经超越了Hybird方案。系统仍然(不得不)依赖原生组件暴露出来的组件和方法。举两个例子,ScrollView这个组件,在Native层是有大量事件的,scrollViewWillBeginDragging, scrollViewWillEndDragging,scrollViewDidEndDragging等等,这些事件在现有的版本都没有暴露,基本上做不了组件联动效果。另外,这个版本中有大量组件是iOS only的:ActivityIndicatorIOS、DatePickerIOS、NavigatorIOS、PickerIOS、SliderIOS、SwitchIOS、TabBarIOS、AlertIOS、AppStateIOS、LinkingIOS、PushNotificationIOS、StatusBarIOS、VibrationIOS,反过来看,剩余的都是一些抽象程度极强的基本组件。这样,用户必须在不同的平台下写两套代码,而且所有能力仍然强烈依赖 React native 开发人员暴露的接口。由于最外层是React,初次学习成本高,不像往常的Hybird方案,只要多学几个JS API就可以开始干活了。当然,React的确让后续开发变得简单了一些,这么一套外来的(基于iOS)、残缺不全的(css-layout)在React的包装下,的确显得不那么面目可憎了。另外,React Native仍然很不完善。文档还不全,我基本上是看着他的示例代码完成的demo,集成到已有app的文档也是今天才出来。按照官方的说法,Android版本要到半年后才发布: ,届时整个系统设计可能还会有很大的变化。PS,在使用Tabbar的时候,我惊喜的发现他们居然用了iconfont方案,我现在手头的项目中也有同样的实现,不过API怎么设计一直很头疼。结果,我发现他是这么写的:&TabBarItemIOS
name="blueTab"
icon={_ix_DEPRECATED('favorites')}
在 _ix_DEPRECATED 的定义处,有一句注释: // TODO(nicklockwood): How can this fit our require system?以上。下面是一周前,在React native还没开源的时候,通过反解ipa的一些分析过程,有兴趣的可以看看。------------------------简单粗暴的分割线--------------------背景和调研手段React Native还没开源,最近和组里兄弟「反编译」了Facebook Group(这个应用是用React Native实现的)的ipa代码,出来几百个JS文件,格式化一下,花了几天时间读了一下源码,对React Native的内部核心机制算是有了一个基本了解。React Native的核心实现:先简单说几点,详细的等回头更新。1. React Native里面没有webview,这货不是Hybrid app,里面执行JS是用的
JavascriptCore。2. 再说React Native的核心,iOS Native code提供了十来个最基本核心的类(RCTDeviceEventEmitter、RCTRenderingPerf等)、或组件(RCTView、RCTTextField、RCTTextView、RCTModalFullscreenView等),然后由React Native的JS部分,组成二十来个基本组件(Popover、Listview等),交由上层的业务方来使用(THGroupView)。3. 就如他们在宣传时所说,他们实现了一套类似css的子集,用来解决样式问题,相当复杂和强大,靠这个才能将Native的核心组件组成JS层的基本组件再组成业务端的业务组件,应该是采用的C语言版本实现的(在ppt中我们看到了类似flex-direction: column一类的代码,这个正是css-layout支持的语法)。4. 在React Native中,写JS的工程师解决的是「将基本组件拼装成可用的React组件」的问题,写Native Code的工程师解决的是「提供核心组件,提供足够的扩展性、灵活性和性能」的问题。React Native的设计考虑:ReactJS对React Native有着直接的影响(我没在生产环境中用过React,只看过代码&用过Angular,如果有误请指出)ReactJS里面有这样的设计:1. ReactJS 的大工厂入口createElement返回的不是某个实体DOM对象,而只是一个数组2. 通过源码中 ui/browser/ 目录中的代码,将这个数组转换成DOM3. 底层的渲染核心是可以更换的另外,Facebook自己有JSX,css-layout等开源项目,基于这些,如果要做一个用 JS来开发Native app的东西,很自然就想到了一套最有效率的搞法:1. 将 ui/browser 里面的代码替换成一套 Native 的桥接JS(实际上,iOS版是通过injectGenericComponentClass方法,将核心组件的方法注入到JS里面 ),就直接复用React的MVVM,自动将数据映射到Native了2. Native code里面实现三组核心API,一组提供核心组件的API(create、update、delete),一组事件方法(ReactJS里面的EventEmitter ),一组对css进行解析(css-layout)以及返回Style的ComputedStyle(React Native里面叫meatureStyle)。这样,用上了ReactJS本身的所有核心功能和设计思路,Native的开发也足够简单。那,React Native是什么?其实这东西从Native开发来说,相当于重新发明了一个浏览器渲染引擎并且套一个React的壳,从Web开发角度来说,就是把原来React的后端换成了Native code来实现,就跟Flipboard最近搞的React Canvas 一样: react-canvasReact Native的优势和劣势::优势相对Hybird app或者Webapp:1. 不用Webview,彻底摆脱了Webview让人不爽的交互和性能问题2. 有较强的扩展性,这是因为Native端提供的是基本控件,JS可以自由组合使用3. 可以直接使用Native原生的「牛逼」动画(在FB Group这个app里面,面板滑出带一点果冻弹动,面板基于某个点展开这种动画随处可见,这种动画用Native code来做小菜一碟,但是用Web来做就难上加难)。优势相对于Native app:1. 可以通过更新远端JS,直接更新app,不过这快成为各家大型Native app的标配了…劣势:1. 扩展性仍然远远不如web,也远远不如直接写Native code(这个不用废话解释了吧)2. 从Native到Web,要做很多概念转换,势必造成双方都要妥协。比如web要用一套CSS的阉割版,Native通过css-layout拿到最终样式再转换成native原生的表达方式(比如iOS的Constraint\origin\Center等属性),再比如动画。另外,若Android和iOS都要做相同的封装,概念转换就更复杂了。更新1:添加了React对React Native的影响。更新2:基本确定其使用了 css-layout,添加了对React Native的总结更新3: React native已经开源了: ,只有iOS版。我写了几个demo,简单看了看objc代码并和开源前的我们的一些结论(见后文)交叉验证。简单地从前端工程师和系统整体角度说一下React native的特点和优劣吧。更新4: 补充了几条优势和与前端开发的对照
UPDATE list: React Native Android 9.15 提前发布,补充AppStore审核政策变化。 Slide:上海前端技术峰会, Slide:QCon北京2015,“” 天猫前端@横天同学发表的对的布局能力做了一些实验,给出了一些有价值的结论,如:react 宽度基于pt为单位;flex能实现网格系统需求,且网格能够各种嵌套无bug;padding 设置在Text元素上所有padding变成了marginBottom... 风险,iOS6 javascriptCore.framework 为私有,可以通过这个库代替。------本文首发于 Facebook在 F8大会上开源了React Native(),本文是对React Native的技术背景、规划和风险的概述。看得比较仓促,问题处请直接回复。组里的同学于完成了天猫iPad客户端“猜你喜欢”业务的React Native改造(4月中发版)。本周开始陆续放出性能/体验、稳定性、扩展性、开发效率等评估结果。图1 - 4.2已完成React Native改造的业务一、背景为什么需要 React Native?What we really want is the user experience of the native mobile platforms, combined with the developer experience we have when building with React on the web.摘自 React Native的发布稿(),加粗的关键字传达了React Native的设计理念:既拥有Native的用户体验、又保留React的开发效率。这个理念似乎迎合了业界普遍存在的痛点,开源不到1周github star破万,目前是11000+。图2 - React Native项目成员Tom Occhino发表的React Native: Bringing modern web techniques to mobile()详细描述了React Native的设计理念。Occhino认为尽管Native开发成本更高,但现阶段Native仍然是必须的,因为Web的用户体验仍无法超越Native:1. Native的原生控件有更好的体验;2. Native有更好的手势识别;3. Native有更合适的线程模型,尽管Web Worker可以解决一部分问题,但如图像解码、文本渲染仍无法多线程渲染,这影响了Web的流畅性。Occhino没提到的还有Native能实现更丰富细腻的动画效果,归根结底是现阶段Native具有更好的人机交互体验。笔者认为这些例子是有说服力的,也是React Native出现的直接原因。图3 - Occhino在ReactJS Conf分享了React Native(Keynote)Learn once, write anywhere“Learn once, write anywhere”同样出自Occhino的。因为不同Native平台上的用户体验是不同的,React Native不强求一份原生代码支持多个平台,所以不提“Write once, run anywhere”(Java),提出了“Learn once, write anywhere”。图4 - “Learn once, write anywhere”这张图是笔者根据理解画的一张示意图,自下而上依次是:1. React:不同平台上编写基于React的代码,“Learn once, write anywhere”。2. Virtual DOM:相对Browser环境下的DOM(文档对象模型)而言,Virtual DOM是DOM在内存中的一种轻量级表达方式(原话是lightweight representation of the document),可以通过不同的渲染引擎生成不同平台下的UI,JS和Native之间通过Bridge通信()。3. Web/iOS/Android:已实现了Web和iOS平台,Android平台预计将于2015年10月实现()。前文多处提到的React是Facebook 2013年开源的Web开发框架,笔者在翻阅其时,发现这么一段:图5 - 摘自React发布稿(2013)1. 加亮文字显示2013年已经在开发React Native的原型,现在也算是厚积薄发了。2. 最近另一个比较火的项目是(详见 @rank),渲染层使用了Web Canvas来提升交互流畅性,这和上图第一个尝试类似。React本身也是个庞大的话题不再展开,详见。笔者认为“Write once, run anywhere”对提升效率仍然是必要的,并且和“Learn once, write anywhere”也没有冲突,我们内部正在改造已有的组件库和HybridAPI,让其适配(补齐)React Native的组件,从而写一份代码可以运行在iOS和Web上,待成熟后开源出来。二、规划下图展示了业务和技术为React Native所做的改造:图6 - 业务和技术改造图6 - 业务和技术改造自下而上:1. React Node:React支持服务端渲染,通常用于首屏服务端渲染;典型场景是多页列表,首屏服务端渲染翻页客户端渲染,避免首次请求页面时发起2次http请求。2. React Native基础环境:
2.1. Framework集成:尽管React Native放出了文档,集成到现有复杂App中仍然会遇到很多细节问题,比如集成到天猫iPad客户端就花了组里iOS同学2天的时间。
2.2. Networking改造:主要是重新建立session,而session通常存放于http header cookie中,React Native提供的网络IO 和XMLHttpRequest不支持改写cookie。所以要不在保证安全的条件下实现fetch的扩展,要么由native负责网络IO(已有session机制)再通过HybridAPI由JS调用,暂时选择了后者。
2.3. 缓存/打包方案:只要有资源从服务器端加载就避免不了这个话题,React Native也是如此,缓存用于解决资源二次访问时的加载性能,打包解决的是资源首次访问时的加载性能。3. MUI是一套组件库,目前会采用向React Native组件补齐的思路进行改造。4. HybridAPI是阿里一组Hybrid API,此前也在多个公开场合(如)分享过不再累述,React Native建立了自己的通信机制,看起来更高效(未验证),改造成本不大。5. 最快的一个业务将于4月中上线,通过最初几个业务改造推动整体系统的改造,如果效果如预期则会启动更大规模的业务改造。 更多详细规划和进展,以及性能、稳定性、扩展性的数据随后放出。 三、风险1. 尽管Facebook有3款App(Groups、Ads Manager、F8)使用了React Native,随着React Native大规模应用,Appstore的政策是否有变不得而知,我们只能往前走一步。
* 更新::允许运行于JavascriptCore的动态加载代码,下图是此前的审核政策,对比加亮部分的改变。2. React Native Android 已于发布,第一个使用RN开发的Android App()已上架Play了。3. iOS6 javascriptCore.framework 为私有,如在iOS6上使用有拒审风险。(),可以通过这个库代替,涉及改动较多,只在实验阶段支持了iOS6。4. ListView 性能问题需要持续关注()React Native相对于Webview和Native的优势和劣势 @berg 也给出了较详细的描述,可以相互参照。鬼道
更新于2月3日:关于我们的最新动态,我们把React跑在了其他Native的实现,让React在无线不仅是ReactNative,就像我之前说的React更是一种模式:------------------------------------对React的理解,认为React是一种架构模式,无论是内建的DOM、Native还是React Canvas都是的一种基于React模式的具体实现,当我们评价React Native还是评价React Canvas,都是React生态想象空间的一种表现。React提出重新思考UI开发过程,其实不是面向浏览器,而是所有的前端,因为对前端开发而言我们需要涉及的领域已经开始包括了Web与Native。这里也分享淘宝基于React正在进行中的一些实践,是我认为能戳中极客们的G点让大家为了亢奋的事情。React Web端团队里最早使用React的线上产品: 知了,前端是React+KISSY, 后端是淘宝基于Node.js解决方案Midway,这是完全由前端主导的项目,在前端,通过React极大的方便了富交互页面的构建,同时也轻松的解决了页面内业务组件状态同步等问题。淘宝懂我,我们在面向用户的创新业务里毫无悬念的引入了React,不是为了技术而技术,而是基于React的开发过程,促使大家一切都是以组件的思考模式,这的确让业务也变的更加清晰,开发效率提升,维护成本降低,发现React的确改变之前曾经非常困扰我们的事情。淘宝懂我的入口在“我的淘宝”里,大家可以去围观: 。React Native端F8大会当天,React Native终于正式开源了,这着实让人兴奋了一把,因为我们知道React Native即将成为在手机端上必不可少的开发模式之一。因为已经有React的开发经验,稍微过目下文档,很自然就能过渡到React Native的开发。笔者稍微努力了下,复刻了下手机淘宝的首页,不到个把小时我这个菜鸟就差不多完成了大体的样子,让人惊讶于React Native这套技术方案的生产力。而且React Native开发与Web几乎一致的开发与调试体验,也更让我惊艳,这效率上差距可见一斑。但是,Android版本还未开源,React Native只支持iOS7+平台,而在淘宝移动业务里依旧需要支持iOS6平台,所以在iOS6与Android平台上只能暂时继续跑H5页面,在技术上我们很快就确定将React Native代码转为H5版本,做到大家梦寐以求 Write once, run everywhere,就如大家在微博上看到的,我们就做了一个简单的DEMO,基本确定这个方向的可行性。兴奋的同时,一个无法回避的事实,对Web前端来说这是一个全新的领域,就是一个大坑,需要我们去填平,填平这些坑的就是我们配套的基础设施。如图这是淘宝基于React的已经完成或正在进行中相关领域,当这些基础设施相对完善时,就是React Native爆发的时候,而我们现在做的事将是未来的肩膀。结束语:Web是未来,Native是当下,而我们在未来与当下之间。
先说结论:必有作为,但绝不会是一家独大,甚至很难成为主流。用过 React 会知道,React 的核心概念是「DOM Representation」,在开发者和 DOM 中间构建一个中间件,然后通过高效的算法来 diff 两次 Virtual DOM 渲染的差异,然后在最小范围内更新 DOM,在大部分情况下——注意是大部分不是所有——这种做法都是足够高效的,但是对于精细的需求、动画控制等——比如在移动设备上做一个跟随 touchmove 的元素,还要各种 transition 等等——场景 React 会显得力不从心,或者很笨拙。但是抛开这些太过复杂的需求,React 是有能力满足大部分的业务场景的。再说 React Native,这几天不停看见媒体用「Web 开发要 XXX」一类的题目来发稿,真是吐槽无力。React Native 根本都不算 Web 开发好不好——Webview 都没了还 Web 个 bird 啊...React Native 继承了 React 在 JavaScript 的扩展语法 JSX 中直接以声明式的方式来描述 UI 结构的机制,并实现了一个 CSS 的子集,这把「DOM Representation」的概念外扩成了「UI Representation」,由于不是操作真实 UI,就可以放到非 UI 线程来进行 render——所有做客户端 UI 开发的都应该知道 UI 线程是永远的痛,无论你怎么 render,render 的多低效,这些 render 都不会直接影响 UI,而要借由 React Native 来将改变更新回 UI 线程。由于目前没有任何示例代码,也看不到更细节的实现机制介绍,所以以下部分为猜测。如果 React Native 沿袭 React 的机制,就会同样是把两次 render 的 diff 结果算出来,然后把 diff 结果传递回主线程,在最小范围内更新 UI。所以,核心是以下三点:1. 在非 UI 线程渲染 UI Representation2. 高效的 diff 算法保证 UI update 的高效3. 没错,由于中间件的机制,React 很有可能成为一个跨平台的统一 UI 解决方案,可以理解为 UI 开发的虚拟机?声明式 UI 开发,简单快捷,必然大有作为。精细控制无力,复杂应用场景无法很好满足,必然受限。最后再说一句...不是能写 JavaScript 就叫 Web 开发...============================================看了 的答案后来补充。这个答案作为补充或扩展来回答「React + Flux 模型」是非常好的,但问题是「React Native」。React Native 的亮点是解决了在 Native 中使用声明式来开发 UI 的渲染效率问题,而不是软件架构和工程模型的问题,无论是 iOS 还是 Android 固有的模型也是非常好的。为啥 FE 会在乎这个?因为 FE 最习惯用声明式来开发 UI,而这么多年想参与到 Native 开发中的目标都没能达成,就是受制于最终的运行效率。React 作为一个 View Component 封装解决方案来讲,同 Polymer 以及 AngularJS 中 Directive 并没有本质区别,只是用不同的思路来封装 View 而已,用 React 也不一定非得用 Flux 模型,React 替换 Backbone.View 组件,用纯朴的 MVC 模型来描述也是 okay 的。但是当 component 很多且互相嵌套时,就需要有一个合理的模型来描述通信机制,优雅且高效,那就是 Flux 模型了。前年 React 刚发布,还没有提出 Flux 时,我们在终端产品中开始小范围尝试 React 就遇到了 component 之间通信麻烦或者不合理的问题,当时的解决方案是全局实例化了一个继承 Backbone Event 的对象作为 event hub,所有的 component 都在其上来 reg 和 trigger 事件。现在看来,就是简化版的 Flux 模型。不过我确实有一点遗漏的内容,React 的 DOM Representation 或者 React Native 的 UI Representation 的每个 component 都有一个 state 用来描述状态,而 component 某种意义上来说就是一个状态机,因此渲染结果是幂等的。近些年 Web 前端的开发越来越多的受到工程复杂度上升导致整体性能下降的困扰,所以最近几年的新型框架大多有一些独特的机制来提升性能,而这些机制大多是从 Native UI 或者游戏开发中借鉴来的,比如 AngularJS 中的数据 dirty check 机制,比如 React.js 中 Virtual DOM 的 diff 机制,这些特点同以前的前端框架或库相比,真的是非常特殊且先进的改进,往往也会成为这个框架或库的亮点之一,对 FE 来讲当然就是新鲜玩意啦。最后,Facebook 在 PHP 中直接写 HTML Tag 那东西叫 XHP,对应是 JSX 扩展语法,和 React 关系也不大...
哈哈,大家都不看好它,我倒是觉得它非常不错。先说一下传统的 hybrid app 的一些优劣势:优势:js 可以直接被 native 端执行,也可以和 native code 进行通讯,进而可以调用一些 native 提供的接口。 能直接被执行的好处在于可以直接从服务器上载入并执行 js 代码,这点在 iOS 上是 native code 和其他 to objc 的语言都难以做到的。这使我们有了一些更灵活的方法,来完成诸如应用内更新或者开发应用内插件之类的工作。同时,iOS 和 Android 可以共享一些前端部分的代码,使得代码能够更好地重用。劣势:界面渲染效率低,多线程支持差,GC 问题。在 WebView 中绘制界面、实现动画的效率都比较低,开销也比较大。WebWorker 提供的多线程在 native 端有很大的局限,js 在 GC 时也有可能卡 UI。React Native 的做法非常激进,完全抛弃了 HTML(抛弃了 HTML 不代表抛弃了声明式),抛弃了 WebView,在 background thread 里运行 js 并直接使用原生控件进行渲染。这从根本上解决了渲染问题,使得 js 不再只能做 hybrid app,而能做出具有 native behavior 的流畅靠谱的 native app。从这一点上来说 React Native 已经做得相当不错了,尽管它只实现了 CSS 的子集,但是考虑到 CSS 如此复杂而它又抛弃了使用 webview 渲染,这是可以接受的。===========但是,React 的意义绝不在于解决了一些 hybrid app 的痛点。React 是一个很有野心的项目,它的目标不仅仅是简单地使前端能用 js 写 native app,而是希望推广一个通用的前端构建方案,不论是 Web 前端,还是客户端前端。FB 在演讲里说,React 的目标不是 “Write once, run anywhere",因为不同平台的差异是客观存在的,设计风格也各有不同。它要做的,是 “Learn once, write anywhere”。React 里的 view 不仅可以是 DOM,也可以是 iOS 控件或者 Android 控件,不论是什么平台,都能 “build in React”。就我看来,前端不只是需要写网页,更重要的是要解决属于前端领域的各种问题。Web 前端和客户端前端在本质上是一致的,探索前端领域的最佳实践是一件很有意义的事。近些年前端比较火,相比于自成体系较为封闭的客户端前端, Web 前端在前端实践上的探索或许更多一些。不管是阿里的 Midway 那样侵入到后端的 UI layer,还是像 React Native 这样侵入到客户端前端,我认为都是非常值得称赞的探索。至于到底怎么评价 React Native,我觉得它和 React 一样赞。===========最后附个 FB 关于 React Native 的演讲:
一直在跟进 React.js , 中文论坛()也主要是我在维护, 吐个槽本人前端, Macbook 用户, Android 用户, 但是不会移动端的开发首先如果 Facebook 发布 React Native, 那么移动端开发的门槛瞬间降低, 非常好的消息当然这个也将促使更多人选择 React 这样一套方案, 社区当中的资源也会更丰富结果就是会有很多人来参与研究用 React 的范式怎样来编程, 这是我们非常希望看到的React 有一个观点很明白, 就是以往的编程太多过程式的写法, 他们想要变成声明式的,因为声明式的写法能讲底层逻辑交给可靠的代码, 那么开发者的门槛极大地降低发布会演讲提到的就是随着应用变大, 逻辑变复杂, 用 React 的话后来的开发者很好上手相信这也是很多人选择 Angular 的原因.. 虽然两者实现声明式编程的语法和方式差别还是不小那么 React 现在靠着它摆脱了 DOM 的高度的抽象, 想要把同样的开发方式复制到本地应用!顺带地, React 把前端的事件系统, Flexbox 布局, 打算复制到移动开发上这个对于前端开发者来说会是很好的消息, 特别是已经用 React 写了很多前端代码的对于移动端我希望是在 React Native 稳定版发布以后, 能被移动端开发者认可...就我个人来说, 我倾向于认为 Functional Reactive Programming 一路的图形开发前途更好比如 Elm, 比如 React, 对界面还有数据及逻辑都做了比较理论化的考虑..那我很期待各种图形开发当中能引入这个我认为非常高效的方案另外, Web 开发当中灵活的布局系统我也希望在我学习开发其他平台时能继续使用.
这是我做完 tutorial, 观察源代码后的评价:很适合用来布局, 用 flex-box 拯救约束布局! -- 不过实现还有一些小问题, 有些元素不是那么容易改大小和位置的, 内部的 Cassowary 约束不满足怎么办? 或者它凸出来把 flex-box 破坏掉, 或者把它内部的布局破坏掉来满足 flex-box, 两个布局系统打架很心累...它和 HTML/CSS 完全没关系, 元素比 HTML 简单很多, 能用的 style 都定义在 view class 中, 现在 commit 还很少, 支持的 style 种类非常少, 能力非常弱, 而且和 CSS style 不是完全对应的 (主要的 style 声明见 ) 现在问题来了: 是不是可以把有复杂 style 需求的组件放到 WebView 中去? 可惜的是, 可以新建 WebView component 但出来的完全是个黑箱, 现在还没法无缝的把 react-native 的 virtual dom 接到 WebView 内.它的 JS 引擎是用 WebView 自带的, 不能 JIT, 比浏览器里的 JS 性能差很多. 光用来布局或者做简单应用很舒心, 做复杂应用将会是耗电吃内存大户... 瓶颈部分改用 native 组件可以改善一下, 毕竟 Swift 写组件, JS 调用 so easy. (3月30日更正: 其实用的是 JavascriptCore.framework, 而且现在 Nitro engine 可以 JIT 了, 不过每次通信都 eval 的那小段代码是没有 JIT 的, 有些微影响但不严重)以后 Android 版发布后, 很可能会颠覆 Android 开发首选语言.对社会的危害: 一大波全端程序员又给自己的技能标签加上了 iOS, Android
用RN一两个月了,现在准备全面切回原生。在这里给各位一个忠告,免得后人掉坑。RN iOS 有一个臭名昭著的 issue 499(一年前的issue),官方至今没有解决。RN 自带的 ListView 是没有使用 Recycling 的,这样就使得 RN 无法使用大数据的长列表。如果你的 App 中使用无限加载或者多个较多数据的列表。那么你的 App 就会非常吃内存,卡死、甚至使得 App 闪退。已有的第三方解决方案都不能完美解决这个问题。RN iOS 适合无长列表的 App,但是如果是类似新闻客户端,数据展示类 App,千万千万千万不要使用。
Facebook 在 React.js Conf 2015 大会上推出了基于 JavaScript 的开源框架 React Native,结合了 Web 应用和 Native 应用的优势,可以使用 JavaScript 来开发 iOS 和 Android 原生应用。下面是对 React Native 官方文档的完整中文翻译教程:
其实最应该期待的是ui以及编译环境的整合,这些已经有ionic做榜样,js to native也有Ti趟了几年雷。工程结构上比ionic的angular讨巧。看起来会牛的,但这些优势目前我串不起来,没法预期会是个什么东西。我多说一点,以我的观察,没ide火起来难。
已有帐号?
无法登录?
社交帐号登录

我要回帖

更多关于 reactnative image 的文章

 

随机推荐