小程序技术全解 | 青训营笔记
这是我参与「第四届青训营 」笔记创作活动的的第 27 天
课前
注册字节小程序账号
按照以下地址中的步骤注册字节小程序账号 microapp.bytedance.com/docs/zh-CN/…
安装字节小程序开发者工具并登录
- 访问 字节小程序 | 注册账号
- 下载安装完成后打开开发者工具并使用刚刚注册的账号就行登录
- 新建一个项目,其中appid填入测试号:testAppId 这样就成功创建一个小程序项目了,你可以在预期的过程中,自己做尝试修改代码看有什么变化
初步学习小程序相关概念和语法
在以下地址 字节小程序 | 小程序简介 学习简单预习下小程序相关概念,文件结构,组件,api 等,可以快速过下,了解下相关概念,后续完整语法 api 等,可以等时机开发时再学习
课程目标
先看下课程目标:
- 认识和了解小程序的业务产品价值
- 学习和掌握小程序相关技术原理
为什么我们讲技术之前要先讲下产品价值,这是因为小程序带来的更大的价值就是它的产品价值 它帮助例如微信这种超级 app 构筑了更加完整的生态,扩充了更多的业务场景,这才是小程序最最重要的价值。当然它也在技术上带来了很多价值,我们后面都会讲。 其实不论什么技术,最终都是要为业务服务的,技术本省不存在优劣,只存在是否适合。
发展历程
发展历程
2017、2018 年是小程序的发展初期,这个阶段最早由微信开始进行探索。
2017 年 1 月,小程序正式发布,这个时候小程序就有了很高的关注度,但这个时候还没有完全对个人开发者开放
2017 年 3 月份,小程序正式面向个人开发者开放,自此,小程序数量进入爆发期。
2017 年 4 月份最重要的带来了称为小程序码的新型图形码,为什么说小程序码很重要。因为它的到来真正能够让线下场景和线上小程序沟通串联起来。
2017 年 9 月份支付宝小程序也开始了公测,标志着各大厂竟相进入到小程序领域开始竞争,因为围绕着小程序各大超级 app 能够构筑和丰富独属于自己的生态。
2017 年 12 月份轻度游戏,小游戏上线,跳一跳风靡一时,不知道大家都有没有玩过
进入 2018 年,小程序在 1 月份带来了打开 app 的能力,这也标志着小程序为其他引流功能的功能开放
同时在 2018 年,百度小程序,qq 小程序、头条小程序(现在叫字节小程序),都相继上线。“巨头”都加速布局小程序生态
2019 年,小程序被纳入腾讯最高战略,同时微信为小程序带来更加丰富的入口,开放更多的流量,如,微信主页下拉出现小程序桌面,微信搜索也可以搜索到小程序,同时微信公众号也可以自由挂载小程序,这些入口意味着更多的场景渗透。
2019 年 9 月份,小程序开放贴片广告,正式开始商业化建设,其实对所有企业来说所以业务最终都是为了赚钱嘛。随着小程序越来越复杂,小程序包 4M 的限制越来越无法满足,所以在 11 月份小程序开发包的总包上线上升至 12M ,让开发者能够构建更加复杂的小程序应用。
进入 2020 年,疫情的出现也加速了各种小程序的出现,同时微信为小程序赋予了直播和小商店更多的属性,为小程序的商业化带来更多的可行性。
再往后发展出了越来越多的场景,小程序整体也逐渐发展的越来越成熟。
核心数据
说完发展历程我们可以看一组核心数据,这是到 2020 年底的数据,可以看出小程序的数量特别的庞大,虽然出现的不是特别久。到现在只会更多
小程序生态
小程序是超级 app 发展到一个阶段的必然产物,因为这些超级 app 想要构筑更多的场景,让更多的人用只靠自己做是永远做不完的,所以需要开放出来给其他开发者做。所以小程序目前的生态也基本是围绕各个超级 app 来的。
业务价值
与 Web 的区别
- 有着固定的语法以及统一的版本管理,平台可以更方便地进行审核
- 平台能够控制各个入口,如二维码、文章内嵌、端内分享。入口上也能带来更好的用户体验。
- 小程序基于特殊的架构,在流畅度上比 Web 更好,有更优秀的跳转体验
三大价值
-
渠道价值
由于小程序的便携性,依托于超级平台,小程序能够充分为很多场景导流,如美团和美团优选微信小程序带来的流量占比分别是 40% 和 80%
-
业务探索价值
相比原生 app 来说,小程序的开发难度和成本都降低了很多,这就创造了很多场景开发者能够用小程序来快速试错,不断探索新的业务价值。
-
数字升级价值
线下到线上如何做?从轻消费类的快餐、茶饮到地产汽车等大宗消费,小程序都展示了良好的容错空间。我们线下场景的小程序覆盖范围很广。
技术解析
小程序原理
第三方开发应用最简单方便的方式:WebView + JSBridge
我现在有一个超级 app,比如说抖音,微信,我要让外部的开发者在我的平台上开发三方应用,怎样是最简单的?使用我们的 web 技术来开发。WebView 和 JSBridege
WebView 我们可以简单理解为 app 内置的浏览器,我们可以在 app 内展示网页,但是除了 web 本身,我们想让开发者能够通过 js 调用更多 app 上的功能, App 上的功能比如打开相机,打开地图等,这些单靠 web api 本身做不到,这就需要用到 JSBridege 了
顾名思义 JSBridege 就是 js 和 native 代码之间的桥梁,让两者能够沟通相互调用,实现 JSBridge 的方式有很多,如代码注入,url 拦截等。总之它的作用就是让 js 和 native 代码能够相互沟通和调用。
这种方式的问题:
- 无网络的情况体验不佳 —— 资源离线化
- 网页切换体验不佳
- 如何管控保证安全
最重要的一点如何管控保证安全,我们对外开放先不说功能是否齐全,最重要的一点就是要保证平台的安全,因为你永远无法杜绝有人恶意在你的平台作恶。这个问题是很大的,先想下我们的方案,比如可以靠人来审核,把所有的网页链接都管控起来,经过审核的链接才可以在平台打开,先不考虑数量的问题,网页的动态性无法解决
方案需要的特点:
- 开发门槛低
- HTML CSS JS
- 接近原生的使用体验
- 资源加载 + 渲染 + 页面切换
- 多 WebView
- 能够保证安全可控
- 独立 JS 沙箱。把 dom 的 api 都禁用掉
这又带来一个问题,不操作 dom 如何渲染页面。其实这个方案,之前很多框架都有,比如 react ,我们只需要关系数据流而不需要操作具体的 dom 就可以根据数据来渲染页面,这样一个结构
Data -> 根据数据处理 DOM -> 页面
形成如上方案,在浏览器中,当 js 操作频繁的时候我们的动画就会卡顿,因为他们是在同一进程中的,我们这种结构将 js 和渲染分离顺带解决了这个问题。 这样的通信结构,决定了小程序的性能问题在数据传递。
小程序语法
TTML
<view
tt:for="{{list}}"
tt:if ="{{isOpen}}"
bindtap="onTap"
/>
JS
Page({
data: {
list: ["a", "b", "c"],
isOpen: true;
}
onTap: function() {
console.log('tap me!');
}
})
TTSS
view {
background-color: "red";
width: 750rpx:
}
实现番茄钟
TTML
<view class="container">
<view class="clock">
{{ timeText }}
</view>
<button tt:if="{{ running }}" class="button" bindtap="onReset">重置</button>
<button tt:else class="button" bindtap="onStart">开始</button>
</view>
JS
const DEFAULT_TIME = 25 * 60;
function formatTime (time) {
const minutes = Math.floor(time / 60);
const seconds = time % 60;
const mText = `0${minutes}`.slice(-2);
const sText = `0${seconds}`.slice(-2);
return `${mText} : ${sText}`;
}
Page({
data: {
timeText: formatTime(DEFAULT_TIME),
running: false,
},
setTimer: function () {
this.timer = setInterval(() => {
this.time = this.time - 1;
if (this.time < 0) {
clearInterval(this.timer);
return;
}
this.setData({
timeText: formatTime(this.time),
})
}, 1000)
},
onStart: function () {
if (!this.timer) {
this.time = DEFAULT_TIME
this.setTimer()
this.setData({
runing: true
})
}
},
onReset: function () {
clearInterval(this.timer)
this.timer = null
this.time = DEFAULT_TIME
this.setData({
timeText: formatTime(this.time),
running: flase
})
}
})
相关拓展
跨端框架介绍
目前的小程序跨端框架主要为了解决两个问题:
- 复杂应用构建
- 一次开发可以跨多端
跨端框架原理
不论什么框架,都逃不开这两种实现方式:解释编译时和运行时。
编译时
ast 解析
编译时方案有个天然的缺陷,无法完全抹平差异,不论是 React 和 vue 等各种框架,它们的用法都十分多样,而且会不断添加新的特性,而小程序本身确有很多的限制,那么在转换过程中,很多特性没有办法进行转换,所以就要给框架的书写代码的时候加上很多限制,这背离了我们的初衷,所有现在更多的方案采用运行时的方案
运行时
运行时的方案能够实现主要依赖这两个部分,一个是虚拟 DOM ,一个是 Template组件。
运行时的方案也不是完美的,前面在讲小程序原理的时候说 setData 是小程序的性能瓶颈,运行时的方案,因为要传递虚拟 DOM 的各种属性到渲染层
在一些场景下相比小程序原生语法性能会更差
课后
- 自己实现一个番茄时钟,要求能够正确展示倒计时,并能够重置和开始
- 有余力的同学,可以添加更多功能如加入登录功能,设置多个番茄,自定义番茄时间等等
- 可下载以下代码,并导入小程序开发者工具中,进行参考