小程序的简介
小程序的诞生
2017 年 1 月 9 日,是 iPhone 诞生十周年,为了向乔布斯致敬,微信产品经理张小龙选择在这天发布了“微信小程序”。张小龙对微信小程序的定义可以用下面几句话概括:
小程序是一种不需要下载安装即可使用的应用程序,它实现了应用“触手可及”的梦想,用户扫一扫或者搜一下即可打开应用,并且“用完即走”,用户不用关心是否安装太多应用的问题。应用将无处不在,随时可用,但又无须安装卸载。
虽然百度曾经在 2013 年就提出过轻应用的概念,与小程序的理念不谋而合,但当时的百度轻应用并没有激起太大的浪花。直到 2017 年微信正式提出小程序的概念后,依托微信强大的平台流量,才让小程序逐渐出现在大众的视野当中。再之后就是随着小程序越来越火爆,各大顶流公司开始推出自家的小程序平台。
为什么会出现小程序
小程序是移动互联网时代为争夺用户流量,构建繁荣生态的平台产物。这是我对小程序的理解。第一,小程序的诞生起源于移动互联网时代的兴起,小程序诞生之前用户需要通过手机应用市场下载并安装应用程序,有了小程序就不需要单独下载和安装应用程序了,也无需在各大手机应用市场分发应用。第二,小程序诞生的目的是争夺用户流量、构建繁荣生态。用户流量基本都是被各大app占领,有了小程序就可以让用户只使用一个app即可完成任何想做的事情,无需跳出打开其他的应用程序,所以这也让平台可以吸引更多人参与进来一起建设小程序生态。第三小程序终归是平台的产物,它只属于平台,无论是微信小程序还是阿里系小程序抑或是头条系小程序,每个平台的小程序都是长在平台上的,离开对应的平台就无法存在。
小程序的优缺点和使用场景
小程序的优缺点都很清晰,优点是无需安装、随时可用、媲美原生的用户体验。缺点是开发门槛较高,尤其是当你的小程序需要投放在微信、阿里以及其他平台上时,需要考虑各个平台的差异,好在目前有了各种跨端框架,可以帮助开发者抹平平台间的差异,让小程序开发变得越来越简单 。
相应地,小程序的好处那么多,也不是所有的场景都适用,主要还是要看业务场景。如果你的目标用户都在某一个平台上,并且需要借助平台的某些能力来实现你的业务需求,又期望比较好的用户体验,那么小程序就是你的最佳选择。
小程序基础知识
小程序的组成结构
我们以支付宝小程序为例,介绍下支付宝小程序的组成结构,一个完整的小程序主要由以下几部分组成。
app.js 用于注册小程序,配置小程序的生命周期。app.json 用于对小程序进行全局配置,设置页面文件的路径、窗口表现、多 tab、分包、插件等。app.acss 作为全局样式,作用于当前小程序的所有页面。小程序的所有页面都放在 pages 目录下,每个页面由页面逻辑、页面结构、页面样式、页面配置四个文件组成。熟悉 web 开发的同学可以发现,小程序的文件目录和普通的 web 程序没有太大区别,唯一的区别就是小程序有自己的语法规则,比如阿里系的页面结构要遵循 axml 语法,微信小程序要遵循 wxml 语法;阿里系的样式遵循 acss 语法,微信小程序要遵循 wxss 语法。具体的语法规则这里就不再赘述了,可以到阿里或微信小程序官方文档里查阅。
-- app.js -- 入口文件
-- app.acss -- 全局样式
-- app.json -- 全局应用配置
-- pages -- 页面文件目录
-- home
-- index.js -- 页面逻辑
-- index.axml -- 页面结构
-- index.acss -- 页面样式
-- index.json -- 页面配置
此外,平台会提供小程序开发工具,一般是个IDE,可以帮助开发者开发、调试和打包小程序代码。小程序管理后台可以完成小程序的发布。小程序的开发本身没有太大的难度,主要是要熟悉对应平台小程序的语法,这些基础知识可以到小程序官方网站里研磨学习。
小程序运行原理
小程序和 web 应用的区别
web 应用代表着开放互联,所有的 web 应用都是开放的,任何用户都可以毫无障碍的访问使用它。但是很不幸,小程序的诞生之初就依托于某个平台,所以一个小程序只能运行在对应的小程序平台上,一个微信小程序无法运行在支付宝或者钉钉上。此外,web 的开发标准也是全世界统一的,遵循统一的 W3C 标准。同样很遗憾,小程序的开发标准却和平台息息相关,要遵守平台自己的语法规则,而这套规则却不能在其他平台使用。如果你想让你的 web 应用仍用户可以访问使用,那只需要开发一遍即可。如果你想让你的小程序运行在微信、阿里等各个平台上,你却不得不写多套代码,虽然跨端框架可以帮助开发者去解决大部分问题,但仍需要花时间和精力去解决这些问题。小程序似乎与互联网的开放互联精神相违背,但存在即合理,小程序本身的存在有其商业上的考虑,作为开发者的我们只能寄希望于未来所有的小程序平台可以拉齐标准,虽然希望很迷茫,但还是希望能看到一些些改变。
小程序双线程模型
熟悉 web 开发的同学都知道 JS 是单线程的,无论是 UI 渲染还是逻辑计算都在一个 JS 线程里执行。这就会导致视图渲染和逻辑计算相互抢占资源。与 web 应用不同,小程序运行架构分为视图线程 webview 和应用服务线程 woker 两个部分,两个线程同时运行,webview 负责渲染, worker 则负责存储数据和执行业务逻辑。小程序的这种运行架构天然就会比 web 应用有更好的性能。
- webview 和 woker 之间的通信是异步的。这意味着当我们调用 setData 设置页面数据时,我们的数据并不会立即渲染,而是需要从 worker 异步传输到 webview
- 数据传输时需要序列化为字符串,然后通过 evaluateJavascript 方式传输,数据大小会影响性能。
截图来自微信官方文档
由于,开发者的 JS 逻辑代码放到了单独的 worker 线程去运行,不在 webview 线程里,所以这个环境没有 webview 任何接口,不提供任何和 DOM 相关的的 API,因此开发者就没办法直接操作 DOM,杜绝了开发者任意修改页面内容和随意的跳转网页。从这里可以看出小程序的渲染与计算分离的双线程模型设计更多的是出于性能和安全方面考虑,一方面提升了小程序的性能,优化了用户体验,另一方面对平台开发者加以约束,杜绝一些危险操作。
小程序应用启动机制
以支付宝小程序为例,其他小程序类似
下载:小程序无需下载,用户第一次使用小程序时,支付宝客户端会从服务器下载小程序的资源,下载后的小程序资源会缓存在支付宝客户端一段时间。当用户再次打开已经缓存资源的小程序时,会跳过下载过程,更快地打开小程序。
冷启动:当用户打开未启动过,或者是已经销毁的小程序时,称为冷启动。此时小程序会执行初始化,初始化完成后,会触发 onLaunch 回调函数。
热启动:当用户打开已经关闭但仍处于后台运行的小程序时,称为热启动。在这种情况下,小程序并不会被销毁后重启,而仅是从后台切换到前台,此时,onShow 函数会触发,onLaunch 回调函数不会被触发。
前台运行: 当用户首次打开小程序时候,小程序会处于前台运行状态。
后台运行: 用户点击右上角关闭按钮关闭小程序,或者按下设备 Home 键离开支付宝客户端时,小程序并不会直接销毁,而是进入后台运行状态。
从后台运行切换为前台运行: 当未被系统销毁的小程序再度被打开或者激活时,会从后台运行切换为前台运行。
当小程序从后台进入前台显示时会触发 onShow,当小程序从前台到后台时会触发 onHide。
销毁: 用户点击右上角关闭按钮关闭小程序时,小程序仅是进入后台运行,不会被销毁。只有当小程序进入后台运行状态一定时间,或者占用系统资源过高时,才会被真正销毁。
小程序页面运行机制
下图说明了页面 Page 对象的生命周期。
小程序主要靠视图线程(Webview)和应用服务线程(Worker)来控制管理。视图线程和应用服务线程同时运行。
- 应用服务线程启动后运行 app.onLaunch 和 app.onShow 以完成 App 创建,再运行 page.onLoad 和 page.onShow 以完成 Page 创建,此时等待视图线程初始化完成通知。
- 视图线程初始化完成通知应用服务线程,应用服务线程将初始化数据发送给视图线程进行渲染,此时视图线程完成第一次数据渲染。
- 第一次渲染完成后视图线程进入就绪状态并通知应用服务线程,应用服务线程调用 page.onReady 函数并进入活动状态。
- 应用线程进入活动状态后每次数据修改将会通知视图线程进行渲染。当切换页面进入后台,应用线程调用page.onHide 函数后,进入存活状态;页面返回到前台将调用 page.onShow 函数,进入活动状态;当调用返回或重定向页面后将调用 page.onUnload 函数,进行页面销毁。
总结
本篇作为小程序的开发入门文章,主要介绍了小程序诞生的背景以及小程序的基础知识,并且介绍了小程序的运行原理。对于开发者来说,只有在熟悉了一个技术诞生的背景和运行原理之后,开发工作才会更加得心应手,后面会从跨端框架方面来介绍如何选择合适的跨端框架,未完待续,敬请期待!