小程序架构设计(一)
在微信早期,我们内部就有这样的诉求,在微信打开的H5可以调用到微信原生一些能力,例如公众号文章里可以打开公众号的Profile页。所以早期微信提供了Webview到原生的通信机制,在Webview里注入JSBridge的接口,使得H5可以通过它调用到原生能力。
我们可以通过JSBridge微信预览图片的功能:
WeixinJSBridge.invoke(‘imagePreview‘, {
current: https://img1.gtimg.com/1.jpg‘,
urls: [
‘https://img1.gtimg.com/1.jpg‘,
‘https://img1.gtimg.com/2.jpg‘,
‘https://img1.gtimg.com/3.jpg‘
]
})
早期微信官方是没有暴露这些接口的,都是腾讯内部业务在使用,很多外部开发者发现后,就依葫芦画瓢地使用了。
从另外一个角度看,JSBridge是微信和H5的通信协议,有一些能力可能要组合不同的能力才能完整调用。如果我们直接开放这套API,相当于所有开发者都要直接理解这样的接口协议,显然是很不合理的。
所以在2015年初的时候,微信就发布了JSSDK,其实就是隐藏了内部一些细节,包装了几十个API给到上层业务直接调用。
前边的代码就变成了:
wx.previewImage({
current: https://img1.gtimg.com/1.jpg‘,
urls: [
‘https://img1.gtimg.com/1.jpg‘,
‘https://img1.gtimg.com/2.jpg‘,
‘https://img1.gtimg.com/3.jpg‘
]
})
开发者可以用JSSDK来调用微信的能力,来完成一些以前H5做不到或者难以做到的事情。
能力上得到了更多的支持,但是微信里的H5体验却没有改善。
第一点是加载H5时的白屏。在微信里打开链接后会看到白屏,有一些H5的服务不稳定,这个白屏现象会更严重。
第二点是在H5跳转到其他页面时,切换的效果也很不流畅,只能看到顶部绿色进度条在走。
随着JSSDK的开放,还出现了更不好对付的问题。
微信上越来越多干坏事的人,有人做假红包,有人诱导分享,有伪造一些官方活动。他们会利用JSSDK的分享能力变相的去裂变分享到各个群或者朋友圈,由于JSSDK是根据域名来赋予api权限的,运营人员封了一个域名后,他们立马用别的域名又继续做坏,要知道注册一个新的域名的成本是很低的。
龙哥在2016年微信公开课上提出了应用号的概念,我们要重新设计一个新的移动应用开发模式,同时我们要解决刚刚提到的一些问题。
至此,我们回顾一下目前移动应用开发的一些特点:
- Web开发的门槛比较低,而App开发门槛偏高而且需要考虑iOS和安卓多个平台;
- 刚刚说到H5会有白屏和页面切换不流畅的问题,原生App的体验就很好了;
- H5最大的优点是随时可以上线更新,但是App的更新就比较慢,需要审核上架,还需要用户主动安装更新。
我们更想要的一种开发模式应该是要满足一下几点:
- 像H5一样开发门槛低;
- 体验一定要好,要尽可能的接近原生App体验;
- 让开发者可以云端更新,而且我们平台要可以管控。
很多人可能会第一时间想到Facebook的React Native(下边简称RN),是不是RN就能解决这些问题呢?
是的,React Native貌似可以解决刚刚那些问题,我们也曾经想用RN来做。但是仔细分析了一下,我们发现了采用RN这个机制做开放平台还是存在一些问题。
- RN只支持CSS的子集,作为一个开放的生态,我们还要告诉外边千千万万的开发者,哪些CSS属性能用,哪些不能用;
- RN本身存在一些问题,这些依赖RN的修复,同时这样就变成太过依赖客户端发版本去解决开发者那边的Bug,这样修复周期太长。
- RN前阵子还搞出了一个Lisence问题,对我们来说也是存在隐患的。
所以我们舍弃了这样的方案,我们改用了Hybrid的方式。简单点说,就是把H5所有代码打包,一次性Load到本地再打开。这样的好处是我们可以用一种近似Web的方式来开发,同时在体验上也可以做到不错的效果,并且也是可以做到云端更新的。
现在留给我们的最后一个问题就是,平台的管控问题。
怎么理解呢?我们知道H5的界面结构是用HTML进行描述,浏览器进行一系列的解析最终绘制在界面上。
同时浏览器提供了可以操作界面的DOM API,开发者可以用这些API进行一些界面上的变动,从而实现UI交互。
既然我们要采用Web+离线包的方式,那我们要解决前边说过的安全问题,我们就要禁用掉很多危险的HTML标签,还要禁用掉一些API,我们要一直维护这样的白名单或者黑名单,实现成本太高了,而且未来浏览器内核一旦更新,对我们来说都是很大的安全隐患。
这就是小程序一开始遇到的问题,在下篇文章《小程序架构设计(二)》,我们再详细展开一下小程序是如何解决以上这个问题的。