Weex线上踩坑实录

1,721 阅读8分钟

关于weex的基础集成网上有很多博客,我就不重点介绍,今天主要分享一下weex文档中并没有的,在实际项目集成中的碰到的注意点和坑。满满的经验和干货,希望能对大家有所帮助。

1.如何集成到fragment中

集成到fragment的情况还是很普遍的,因为现在很多app都是采用activity内嵌fragment的开发方式,把实际功能都放到fragment中。再比如在tab上一般是tablayout(bottomNavigationView)+fragment的布局,tab上内容也需要使用weex来开发。

在weex文档中只说明了怎么集成到activity中,网上也有很多人在问如何将weex集成到fragment。其实答案很简单,weex渲染出来的内容其实只是在一个控件中,所以只需要和普通的fragment开发一样,将weex sdk嵌入即可。根据weex官方描述,在回调IWXRenderListeneronViewCreated返回创建的view。所以我们只需要让fragment实现IWXRenderListener,然后在onViewCreated中将渲染出来的view添加到整个视图容器中即可。

最后提一点优化,除了考虑到weex使用到fragment中,当然也要考虑到有些页面不是内嵌fragment的情况。这里可以不用重新写一套weex sdk的集成,直接让activity使用已经集成了weex的fragment即可。

2.加载方式选择

在weex文档中提供了2种常用的加载js方式,本地加载和远程加载。笔者在weex开发者大会上问过手淘官方的人员,他们表示手淘首页入口9成都是weex的页面,并且这2中加载方式都有用到,根据实际业务团队自己来灵活选择。

我们是使用的打开app或者前后台切换时下载js,然后直接加载本地js的方式。该方式由于不用每次从网上下载,所以加载效率会高一些,但是也有缺点,就是每次线上发布以后需要一段时间用户才能下载到代码并生效,并不能及时的达到更新效果。

注意:不要采用在上一个页面点击时去判断本地js版本,然后下载运行的方式。该方式看起来很美好,又能实时更新效率又高,但是其实并不然。问题在于该方式需要去请求服务器获取js更新状态,万一网络差的时候就一直不会初始化容器,此时用户点击多次就会打开多个页面,非常的不友好,而且会给服务器带来无所谓的压力。

3.不同的业务模块中如何进行业务交互

weex和rn不一样,在rn中所有的业务默认都是放到一个模块中的,所以rn帮我们处理了通信这一块内容。但是weex不一样,weex中不同业务是不同的js文件,导致通信困难。

网上有说使用storage的方式,但是这个方式其实不太好,经过和前端协商,我们决定自己写一套业务模块中通信方式。我们自定义了一个仓库类,提供set方法保存业务模块通信中要传的值的key和value,前端调用set方法可以将值保存到客户端,然后加载B模块时由我们客户端将值给B模块,也就是通过fireGlobalEventCallback推送给前端使用。

4.如何构造一个前端调用体系

这里的前端调用体系是指在vue代码中调用到客户端的方法,包括自定义控件、客户端功能等。官方告诉我们是通过JScallback的方式,但是我们总不能在客户端写很多个方法一一对应吧,这里我们写的比较简单,让前端传入一个约定好的伪协议过来,其中包括需要调用的方法、传的参数等内容,接下来在客户端中解析该协议对应到实际的方法。当然这里其实可以考虑用设计模式优化一下,面向修改关闭,会更加符合solid原则。

5.关于网络框架、图片框架

weex的sample中是使用最简单的httpurlconnection来请求数据,但是这个是没有任何优化的基础访问。但是也提供给了我们自行修改的方式,那就是setHttpAdapter(),通过该方法可以使用适合自己公司的网络框架,比如OkHttp、Retrofit等等,weex官方也是建议修改一下网络框架,能够提高访问效率。

weex并没有提供图片加载的方式,用官方的解释来说就是大家的方式都不一样,加进去会让sdk很臃肿,而且不一定能符合各个公司的实际业务场景。所以weex官方只提供了一个setImageAdapter()来让我们自定义适合自己的图片框架,我们必须实现IWXImgLoaderAdapter,不然图片是没办法加载出来的。

注意:图片加载框架需要考虑到gif等其他格式,做好兼容性测试,我们当时ios就出现过问题。

6.关于降级措施

由于我们是使用先下载到本地,然后加载本地js的方式,所以不能避免的一个问题是在打开weex页面的时候实际的业务代码还没下载。针对这种情况,我们使用了降级策略,在打开weex页面之前首先判断一下本地是否有该业务代码,如果没有就打开入口上已配置的h5链接

7.有关打点方面

这里只分享客户端这边的打点,我们在下载js的流程中都有好几个打点,分别是下载成功(失败及原因)、解压成功(失败及原因)、增量更新成功(失败及原因),除此之外,还有进入weex页面信息、weex渲染成功与否、是否进入降级以及降级原因等基本打点。

8.其他weex文档没有提及的要点

weex文档很不全面,导致实际运用到项目中的时候坑点多多,weex上线以后最初基本每个版本都要上一些代码去填坑。当然weex官方是提前知道这些的,只是没有及时分享出来而已。举几个例子,比如ua、cookie等的支持都需要客户端进行支持。

ua:weex sdk中有带一个默认ua,但那肯定不是我们想要的,一般服务端需要的是带app信息的ua。

cookie:cookie的话是在请求时需要带上的,所以我们需要让weex的网络请求框架带上。这些在第一次上线时不一定能考虑到,但是客户端发版问题一直都是老大难,这里分享出来希望能对大家有所帮助。除此之外,我们需要赋予前端保存和修改cookie的能力,所以我们在客户端提供好了相关的set和get方法。

9.线上已知weex的未解决bug

我们上线以来碰到了很多的问题,其中大部分weex团队得到了解决,笔者在此对weex团队表示感谢,比如只支持aremabi,导致和项目中其他功能冲突的问题、还有线上崩溃也越来越少,说明weex已经逐步越来越成熟。但是不可否认的是,目前weex仍然有一些问题,比如weex sdk中有framework层初始化失败的问题,发生的概率大概在千分之三左右,weex官方的建议是这个问题无法在sdk中修复,需要自己去判断是否初始化,万一没有初始化便进入降级策略,他们在最新的weex sdk中是已提供了是否初始化的接口的。还有一个线上已知问题是部分三星手机上会crash问题,该问题只出现在三星手机上,目前weex官方没有得到解决。另外,weex对recyclerview的支持不是很好,导致有些列表的效果实现不了,相信这个在以后应该会解决。另外还有些莫名其妙的问题,不知道该怎么说,也不是很重要,这里就不一一描述了,不过相信weex的逐步成熟,这些问题都会迎刃而解的。

10.其他建议

由于weex目前本身就不大稳定,加上第一次使用,避免不了会碰到很多的坑,所以可以使用灰度发布的方式,根据设备号或者id分流只发布一部分的用户使用weex页面,这样万一出现问题影响范围较小,如果一段时间以后没问题再大批量上线。集成weex的客户端开发人员也要学习一下vue,这样自己就可以测试weex的集成代码,提升和前端人员的沟通效率。多关注weex的社区以及github、jira、钉钉群等weex官方平台,有问题可以在里面提issue,笔者亲自体验还是会回复的,包括现在weex官方已经提供了一个专用weex讨论群,有阿里人员在里面解答问题。有空可以研究一下weex底层的代码和核心原理,提升技术的深度和看源码的能力。

最后:以上经验都是笔者作为在线上项目中实际使用过weex,然后分享的在使用过程中的感受。绝对不是网上随便搬抄的,希望能对大家实际应用weex到项目中有所帮助。也欢迎使用过weex的同学探讨相关的技术,一起进步。