小程序技术全解 | 青训营笔记

70 阅读9分钟

小程序技术全解 | 青训营笔记

这是我参与「第四届青训营 」笔记创作活动的的第 27 天

课前

注册字节小程序账号

按照以下地址中的步骤注册字节小程序账号 microapp.bytedance.com/docs/zh-CN/…

安装字节小程序开发者工具并登录

  1. 访问 字节小程序 | 注册账号
  2. 下载安装完成后打开开发者工具并使用刚刚注册的账号就行登录
  3. 新建一个项目,其中appid填入测试号:testAppId 这样就成功创建一个小程序项目了,你可以在预期的过程中,自己做尝试修改代码看有什么变化

初步学习小程序相关概念和语法

在以下地址 字节小程序 | 小程序简介 学习简单预习下小程序相关概念,文件结构,组件,api 等,可以快速过下,了解下相关概念,后续完整语法 api 等,可以等时机开发时再学习

课程目标

先看下课程目标:

  • 认识和了解小程序的业务产品价值
  • 学习和掌握小程序相关技术原理

为什么我们讲技术之前要先讲下产品价值,这是因为小程序带来的更大的价值就是它的产品价值 它帮助例如微信这种超级 app 构筑了更加完整的生态,扩充了更多的业务场景,这才是小程序最最重要的价值。当然它也在技术上带来了很多价值,我们后面都会讲。 其实不论什么技术,最终都是要为业务服务的,技术本省不存在优劣,只存在是否适合。

发展历程

发展历程

Pasted image 20220819101203.png

2017、2018 年是小程序的发展初期,这个阶段最早由微信开始进行探索。

2017 年 1 月,小程序正式发布,这个时候小程序就有了很高的关注度,但这个时候还没有完全对个人开发者开放

2017 年 3 月份,小程序正式面向个人开发者开放,自此,小程序数量进入爆发期。

2017 年 4 月份最重要的带来了称为小程序码的新型图形码,为什么说小程序码很重要。因为它的到来真正能够让线下场景和线上小程序沟通串联起来。

2017 年 9 月份支付宝小程序也开始了公测,标志着各大厂竟相进入到小程序领域开始竞争,因为围绕着小程序各大超级 app 能够构筑和丰富独属于自己的生态。

2017 年 12 月份轻度游戏,小游戏上线,跳一跳风靡一时,不知道大家都有没有玩过

进入 2018 年,小程序在 1 月份带来了打开 app 的能力,这也标志着小程序为其他引流功能的功能开放

Pasted image 20220819101415.png

同时在 2018 年,百度小程序,qq 小程序、头条小程序(现在叫字节小程序),都相继上线。“巨头”都加速布局小程序生态

2019 年,小程序被纳入腾讯最高战略,同时微信为小程序带来更加丰富的入口,开放更多的流量,如,微信主页下拉出现小程序桌面,微信搜索也可以搜索到小程序,同时微信公众号也可以自由挂载小程序,这些入口意味着更多的场景渗透。

2019 年 9 月份,小程序开放贴片广告,正式开始商业化建设,其实对所有企业来说所以业务最终都是为了赚钱嘛。随着小程序越来越复杂,小程序包 4M 的限制越来越无法满足,所以在 11 月份小程序开发包的总包上线上升至 12M ,让开发者能够构建更加复杂的小程序应用。

Pasted image 20220819101637.png

进入 2020 年,疫情的出现也加速了各种小程序的出现,同时微信为小程序赋予了直播和小商店更多的属性,为小程序的商业化带来更多的可行性。

再往后发展出了越来越多的场景,小程序整体也逐渐发展的越来越成熟。

核心数据

Pasted image 20220819101742.png

说完发展历程我们可以看一组核心数据,这是到 2020 年底的数据,可以看出小程序的数量特别的庞大,虽然出现的不是特别久。到现在只会更多

小程序生态

Pasted image 20220819101829.png

小程序是超级 app 发展到一个阶段的必然产物,因为这些超级 app 想要构筑更多的场景,让更多的人用只靠自己做是永远做不完的,所以需要开放出来给其他开发者做。所以小程序目前的生态也基本是围绕各个超级 app 来的。

业务价值

与 Web 的区别

  1. 有着固定的语法以及统一的版本管理,平台可以更方便地进行审核
  2. 平台能够控制各个入口,如二维码、文章内嵌、端内分享。入口上也能带来更好的用户体验。
  3. 小程序基于特殊的架构,在流畅度上比 Web 更好,有更优秀的跳转体验

三大价值

  1. 渠道价值

    由于小程序的便携性,依托于超级平台,小程序能够充分为很多场景导流,如美团和美团优选微信小程序带来的流量占比分别是 40% 和 80%

  2. 业务探索价值

    相比原生 app 来说,小程序的开发难度和成本都降低了很多,这就创造了很多场景开发者能够用小程序来快速试错,不断探索新的业务价值。

  3. 数字升级价值

    线下到线上如何做?从轻消费类的快餐、茶饮到地产汽车等大宗消费,小程序都展示了良好的容错空间。我们线下场景的小程序覆盖范围很广。

技术解析

小程序原理

第三方开发应用最简单方便的方式: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 -> 页面

Pasted image 20220819104048.png

形成如上方案,在浏览器中,当 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
    })
  }
})

Pasted image 20220819104923.png

相关拓展

跨端框架介绍

目前的小程序跨端框架主要为了解决两个问题:

  • 复杂应用构建
  • 一次开发可以跨多端

Pasted image 20220819110337.png

跨端框架原理

不论什么框架,都逃不开这两种实现方式:解释编译时和运行时。

编译时

Pasted image 20220819110454.png

ast 解析

Pasted image 20220819110503.png

编译时方案有个天然的缺陷,无法完全抹平差异,不论是 React 和 vue 等各种框架,它们的用法都十分多样,而且会不断添加新的特性,而小程序本身确有很多的限制,那么在转换过程中,很多特性没有办法进行转换,所以就要给框架的书写代码的时候加上很多限制,这背离了我们的初衷,所有现在更多的方案采用运行时的方案

运行时

运行时的方案能够实现主要依赖这两个部分,一个是虚拟 DOM ,一个是 Template组件。

Pasted image 20220819110727.png

运行时的方案也不是完美的,前面在讲小程序原理的时候说 setData 是小程序的性能瓶颈,运行时的方案,因为要传递虚拟 DOM 的各种属性到渲染层

Pasted image 20220819110904.png

在一些场景下相比小程序原生语法性能会更差

课后

  1. 自己实现一个番茄时钟,要求能够正确展示倒计时,并能够重置和开始
  2. 有余力的同学,可以添加更多功能如加入登录功能,设置多个番茄,自定义番茄时间等等
  3. 可下载以下代码,并导入小程序开发者工具中,进行参考

bytedance.feishu.cn/docx/doxcnP…