最近朋友圈已经被微信小程序刷屏了,这也难怪,腾讯的产品拥有广泛的影响力,谁便推出个东西,都会有很多人认为会改变世界,这不,张小龙刚一发布微信小程序的消息,很多人(技术的和非技术的)就跟打了鸡血似的,估计现在已经鸡血告急了!
我也看了网上的一些关于微信小程序的文章,估计那帮家伙连微信小程序是什么都没搞清楚,就在那里一本正经地胡说八道。好吧,我就通过本文让大家了解一些什么是微信小程序,以及微信小程序到底能为我们带来什么。
关于微信小程序的误解和讨论已经太多了。这里就说一些主要的。
1. 微信小程序与Web(B/S)的关系
2. 小程序的性能可能不如原生App
3. 腾讯要做一个AppStore,和苹果、Google对掐
4. 由于微信小程序入口太深,对于高频应用不适合
5. 微信小程序会逐渐取代原生App,原生App必将没落
1. 微信小程序与Web(B/S)的关系
由于之前有微信公众号,而公众号里面的程序其实就是将移动Web(主要是HTML5、CSS、JavaScript等技术)嵌入到微信中,当然,会调用一些微信提供的API。所以很多人自然而然会想到,微信小程序用的也是HTML5。不过说实话,微信小程序和HTML5、甚至和Web,一毛钱关系都没用。因为Web就是性能低下的代名词,尤其对于那些最求完美、有强迫症的家伙,在手机上使用Web简直不能忍受。千万别说,等以后手机性能会和现在的PC一样牛叉就好了,哈哈,等到那时候,就会出现比手机更牛叉,更小巧,当然,性能也更差的设备,如果手机成为了PC,那么这些新出现的设备将会取代现在手机的位置。就像永远等待新产品降价再买,真的降价了,又会有更好的产品问世,既享受新产品,又享受低价的时候将永远不会到来。
既然说微信小程序和Web一点关系都没有,那么有什么证据呢?这一点从官方文档的描述就可以看出。感兴趣的读者可以通过下面的地址查看微信小程序官方文档。
https://mp.weixin.qq.com/wiki
微信小程序分为工程和页面两部分,工程由三个文件组成:app.js、app.json和app.wxss。其中app.js是JavaScript文件,用于编写全局的事件,如微信小程序启动时要执行的代码,有点像iOS工程中AppDelegate.m文件的作用。app.json用于配置微信小程序,如由哪些页面组成,有点像Android工程中AndroidManifest.xml文件的作用。app.wxss是公共样式表,用于设置整个工程都可以使用的样式,有点像Android中theme或style资源,全局都可以使用。
可能有人会问,微信小程序不是使用了JavaScript吗?难道和Web没有关系。谁告诉你JavaScript和Web有关系了,JavaScript只是一种语言,未必用在Web上,JavaScript同样可以用在服务端,如Node.js。
微信小程序的页面部分由4个文件组成。这里的页面实际上就是窗口。假设页面名字为index,那么该页面由index.js、index.wxml、index.wxss和index.json组成。index.js用于编写页面的逻辑代码、index.wxml是腾讯自己设计的一种标记语言,可以称为微信标记语言,用于描述UI的、index.wxss是针对该页面的样式表,私有的。index.json是针对页面的配置文件。
这里关键点是index.wxss。这东西似曾相识,用过React Native的读者应该很熟悉JSX,一种描述UI的类XML语言。其基本原理是通过XML文件描述UI,并动态创建原生的UI。例如,React Native用View来描述顶层视图,用Text来描述文本输出控件,那么我们可以使用下面的代码来模拟这一动态创建过程。
Android: View component = null; if(tag == “View”) { component = new ViewGroup(…); } else if(tag == “Text”) { component = new TextView(…); } iOS: UIView *component; if(tag == “View”) { component = [UIView new]; } else if(tag == “Text”) { component = [UILabel new]; }
上面描述的是基本的动态创建组件的过程,当然,实际实现要比这个复杂的多,这里只做了原理上的描述。很显然,系统会根据不同平台,以及在JSX中的描述,生成不同的原生组件。
微信小程序的原理类似,对于React Native来说,使用的是JSX,而微信小程序用的是wxml(微信标记语言),一种腾讯自己设计的类JSX的语言,下面是wxml的代码示例。
<view class="container"> <view bindtap="bindViewTap" class="userinfo"> <image class="userinfo-avatar" src="{{userInfo.avatarUrl}}" background-size="cover"></image> <text class="userinfo-nickname">{{userInfo.nickName}}</text> </view> <view class="usermotto"> <text class="user-motto">{{motto}}</text> </view> </view>
下面则是JSX的代码示例。
<View style={{flex:1}}> <DrawerLayoutAndroid ref={drawerLayoutAndroid => { this.drawerLayoutAndroid = drawerLayoutAndroid; }} drawerWidth={150} drawerPosition={DrawerLayoutAndroid.positions.left} renderNavigationView={() =>navigationView}> <View style={{flex: 1, alignItems:‘center‘}}> <Text style={{margin: 10, fontSize: 15, textAlign: ‘right‘}}>我是主布局内容</Text> </View> </DrawerLayoutAndroid> <View style={{flexDirection:‘row‘}}> <Text style={{flex:1}} onPress={this.onPress.bind(this)}>Open</Text> <Text style={{flex:1}} onPress={()=>this.drawerLayoutAndroid.closeDrawer(0)}>Close</Text> </View> </View>
从上面两端代码可以看出,JSX和wxml非常类似,只是具体的组件名称和命名风格不同,例如,JSX所有组件名称首字母都大写(如Text),而wxml所有组件名称首字母都小写(如text),其他的还有组件属性有一定的差异。
不管JSX和wxml的代码风格是否一样,系统处理他们的原理都是一样的,就是根据这些代码自动生成原生的组件,就像前面描述的动态创建原生组件的过程一样。
原生和热布局混合开发
尽管本文的主标题是微信小程序,不过核心要点则是原生和热布局混合开发。这里只是用微信小程序做一个引子。由于目前移动平台主要有Android和iOS。这两个平台使用的开发技术完全不同(前者主要使用Java,后者主要使用OC或Swift),所以就需要有一种可以同时开发两种平台的技术,这样理论上开发成本可以节省一半。
以前比较流行的技术是混合开发(Hybird),这种技术很简单,就是HTML5+CSS+JavaScript的结合。就和木桶原理一样,木桶装多少水,是由最短那个模板决定的,而这三个组合,HTML5就成为那个短板,从而拖慢了Hybird的整体性能。
其实对于Hybird技术,我们只需要其中的两个优势:跨平台和热更新。跨平台很好理解,各个平台都会有Web浏览器,而热更新主要是逻辑代码和UI布局的热更新。逻辑代码这个不用操心,热更新就用JavaScript好了,这里主要讨论UI布局的热更新。在Hybird时代,使用的是HTML5和CSS。这东西热更新没问题,但性能有问题,如果把HTML5组件和原生的组件放到同一个窗口,是可以感觉到他们的不同的。所以现在的主要焦点集中在UI布局既可以实现热更新,性能达到或接近原生组件。HTML5达到了前者的要求,但没有达到后者的要求。我们知道,Android布局使用了Layout,iOS布局使用了storyboard,不管是那种技术,都不支持热更新,都是固化到apk和ipa文件中的。不过这两种技术都支持动态创建组件,所以React Native率先推出了利用JSX描述组件的位置、尺寸以及其他属性,然后再根据这些属性动态创建本地组件的技术。其实JSX会生成一种中间状态,我们可以称为虚拟DOM(Virtual DOM),其实就是一种中间组件而已,然后系统会根据运行平台的不同(Android和iOS),将其动态生成不同平台的原生组件,这样很容易实现热更新,因为JSX就是个普通的文本文件,可以谁便从网络上下载,这一点和HTML5相同。由于组件都是动态创建的原生的,所以和在Layout、storyboard中定义的静态原生组件的性能相同,因此,很容易解决前面描述的问题。我们也可以把这种利用XML或其他格式描述UI布局,并实现动态生成原生组件的技术称为原生热布局。
微信小程序借鉴了React Native的原理。所不同的是,React Native是通用的,而且可以任意扩展。而微信小程序必须运行在微信提供的架构上,是一种寄生的原生热布局。
其实,除了React Native和微信小程序,还有阿里巴巴的Weex(http://alibaba.github.io/weex),这是阿里巴巴前端团队发布的一个开源框架,有兴趣的读者可以到这个地址研究下这些框架。也是用了类似Virtual DOM的技术,可以三位一体(Android/iOS/HTML5),这一点,React Native对应的React.js可以生产HTML5,微信小程序理论上也可以。希望以后能推出类似的技术,开发微信小程序的同时,也可以同时开发基于HTML5的微信公众号。
通过原生热布局的应用,App的性能完全可以和原生媲美(其实就是动态生成的原生组件),目前已经有很多类似的框架问世,相信以后会更多。相信这些原生热布局的方式以后会在很长一段时间成为跨平台开发的主流,因为她的颜值实在太高了!
组件与变量绑定
微信小程序有一个比较有意思的特性,就是可以将组件和变量进行绑定,当更新组件时(如text),只需修改变量的值,组件就会做相应的更新,这一点区别于传统更新组件的方式:通过id或name引用组件,然后使用组件中相关方式或属性进行更新。例如,下面的代码
<text class="user-motto">{{motto}}</text>
其中motto是一个变量,在index.js文件中定义,代码如下:
var app = getApp() Page({ data: { motto: ‘Hello World‘, userInfo: {} }, … … })
现在只需要修改data中的motto变量的值,text组件就会自动显示该变量的值。
其实React Native也同样采用了这种方式,只不过React Native也可以采用直接引用组件的方式来更新组件。
2. 小程序的性能可能不如原生App
这个问题前面已经回答了,小程序采用了动态生成原生组件的方式。不管里面具体是如何做的,总之,要想让性能达到原生App的程度,除了使用原生组件外,没有其他方式。HTML5再怎么优化,也不可能有原生App的性能。就和汽车速度再快,也不可能超过飞机的速度,因为运动介子不同,也就决定了他的极限。
3. 腾讯要做一个AppStore,和苹果、Google对掐
好吧,持这种观点的同学应该比较富有想象力。当然,小程序需要运行在微信中,这是毫无疑问的,从表面上看,确实和AppStore比较像。不过腾讯可能只想做个小程序(你们想多了),因为微信在国内的用户增长量已经到了极限,不可能有大的飞跃了。腾讯继续另一个东西来刺激增长,也许是来自投资人的压力,或来自盈利的压力,腾讯在隔一段时间必须做点什么,从QQ到微信,再从微信到小程序,就是这样,如果不出所料,在若干年后,如果腾讯还存在的话,可能会推出其他什么东西,估计到时应该会有很多人说,这东西必将取代微信小程序,_^_。
当然,还有人说,腾讯是要做个OS,其实这就扯远了,腾讯是互联网公司,不是软件公司,做OS不是他的强项。再说,小程序和OS差着十万八千里呢。其实微信小程序就是借用了React Native的原理(在RN出现的同时,腾讯一直在研究这种技术,估计是为微信小程序做技术上的储备),将原始热布局嵌入到了微信,并提供了一些公开的接口的微信扩展。我觉得将微信小程序定义为微信扩展更合适。
4. 由于微信小程序入口太深,对于高频应用不适合
入口太深,弄浅就好了。Android和iOS很容易直接将App中的功能作为单独的App安装在系统上,作为第一层的图标,这只是技术问题而已,对于腾讯都不是问题。
5. 微信小程序会逐渐取代原生App,原生App必将没落
都说了,小程序是微信的扩展,而且由于其封闭性,无法让程序员*扩展(微信是不可能开源的),所以小程序不能像React Native一样可以开发各种App,只是作为微信的一种补充而已。所以原生App在未来仍然将作为主流。当然,也会带来一些不同,可怜的技术哥又有多了一个活,就是除了原生App、微信公众号外,还要开发微信小程序!好吧,祝技术哥好运!
微信小程序的开发
腾讯自己做了一款小程序开发工具,读者可以从下面的地址下载。
https://mp.weixin.qq.com/debug/wxadoc/dev/devtools/devtools.html?t=1475052047016
下面是截图
看样子还不错,不过必须要有App ID才能进行开发。目前小程序在内侧阶段,只有受到邀请才能自己生产App ID。不过大家可以看一下官方的文档,基本可以了解开发的过程。在该页也包含了小程序中的API和组件列表,和React Native相当接近。
学习微信小程序的前导技术
小程序逻辑代码使用的JavaScript,所以要想编写小程序,必须学会JavaScript,除了JavaScript外,读者可以先研究一下React Native技术,因为这种技术和小程序非常类似,基本上RN学会后,开发小程序就会变得非常轻松。为了让读者尽快进入微信小程序的世界,我特意开发了JavaScript和React Native的视频课程:(JavaScript)http://edu.csdn.net/course/detail/2910 (React Native)http://edu.csdn.net/course/detail/2883 通过这些课程,读者可以为学习小程序做充分的准备。