|
小程序开放平台架构指南(上)
小程序开放平台架构指南(上)
姚泽源
贝壳产品技术
贝壳产品技术 “贝壳产品技术公众号”作为贝壳官方产品技术号,致力打造贝壳产品、技术干货分享平台,面向互联网/O2O开发/产品从业者,每周推送优质产品技术文章、技术沙龙活动及招聘信息等。欢迎大家关注我们。 242篇内容
2021年12月03日 16:07
本系列文章分为上下两篇:小程序开放平台架构指南(上)中介绍了小程序开放平台的核心价值点与开发路线图;小程序开放平台架构指南(下)里对小程序开放平台中两个关键问题: 跨端通信与跨端构建响应式 Dom 界面的解决思路进行了介绍。项目背景进入 2021 年, 提供小程序开放能力的平台越来越多, 除了京东/钉钉/虎牙/快手/飞书, 甚至在以保守出名的金融行业, 招商银行和云闪付也推出了自己的小程序开放平台. 在这样的背景下, 要不要实现自己的小程序开放平台, 如何实现小程序平台自然成为每个公司前端开发者心里的问题. 贝壳基础平台中心对小程序平台的实现进行了一定的调研, 这系列的文章即是对这段时间的总结。什么是小程序评估我们是否需要小程序, 首先得定义什么才是小程序。按微信的定义, 小程序是一种特殊的网页应用. 传统模式下, 逻辑层(js)和渲染层(dom)都在同一页面上执行, 但在小程序里, 逻辑层运行在 jsCore, 渲染层运行在 webview, 互相不能接触. 不仅如此, jsCore 中只支持使用 ECMAScript 规范中定义的语法, ECMA 规范之外, 无论是浏览器环境中的 Dom/window, 还是 Node.js 中提供的 fs/path 模块, 都未予以支持. 这当然使开发变得困难重重, 但作为补偿, 微信通过 wx 对象向逻辑层暴露了大量原生能力. 借助 wx 对象和微信平台本身的支持, 小程序最终实现了以下效果:快速的加载更强大的能力原生的体验易用且安全的微信数据开放高效和简单的开发小程序的优势与劣势这些收益当然很好, 但技术选型时, 我们需要先确认以下几个问题:在当前技术方案下, 实现这些收益, 我们需要付出那些成本有没有其他的方案也能实现这些收益在所有可能的解决方案中, 哪一种是收益成本比最高的 为什么所以, 第一个问题: 如果选择微信小程序方案, 我们需要付出那些成本微信小程序方案的成本在微信小程序的模型里, 由于逻辑层不能接触渲染层, 因此也就不能使用传统浏览器页面的方式开发小程序. 为了模拟这种环境, 我们需要开发专门的环境模拟器, 屏蔽几乎所有的全局函数, 禁止 js 接触 dom, 同时还要模拟小程序基础库提供的开放能力 API----简单来说, 我们需要开发一套 IDE 系统。其次, 实际业务开发中必然有必须操作 Dom 的场景, 比如Picker组件的scroolTo方法, 比如Canvas对象. 为了提供这些能力, 我们需要一个中间层将 Dom 操作封装为组件对象, 在逻辑层和渲染层之间转发操作指令和执行结果, 换句话说, 还要开发一套组件库。然后, 由于逻辑层和渲染层的分离, 为了最终可以渲染出界面, 所以我们需要设计一套类似虚拟 dom/vue 模板/jsx 的系统, 将逻辑层的操作映射为渲染层的实际 Dom, 这是一个webview-render.除了 webview-render 之外, 微信还要向逻辑层暴露原生能力, 这样就需要一层中间层在逻辑层和原生应用之间转发操作指令和运行结果, 也就是一套小程序基础库。Android/iOS 两端都要提供原生功能, 这样又至少需要一名 Android 开发和一名 iOS 开发, 如果公司有多条产品线(如微信/企业微信/QQ/...), 那么还需要开发一套小程序 SDK, 用于在多个平台间共享小程序能力。以上这些是小程序的硬件需求, 除此之外, 小程序的创建/预览/上传/审核/发布都需要一个后台进行交互, 所以我们还需要一个小程序后台系统。总结一下人力需求, IDE 一人, 组件库一人, 基础库+设计模板语法规范+编写 webview-render 一人, Android 一 iOS 一, 小程序后台一, 再加一名技术经理, 总计需要 7 名开发工程师. 按半年出 demo 算, 当第一版小程序平台上线时, 总成本大约是 7 *6 => 42 人月. 而且, 这只是一个 demo, 不包括后期的推广成本维护成本。有没有其他方案可以实现小程序的效果考虑到 IDE 工程师的薪资水准, 42 个人月的成本是相当可观的. 所以, 我们自然会想到一个问题: 除了小程序, 实现既定的期望目标, 我们还有其他方案吗当然有, 小程序方案成本高企原因其实只有一条: 逻辑层和渲染层相分离. 如果允许逻辑层直接操作 Dom, 那么:不需要开发专门的环境模拟器, 直接走传统 h5 开发方案即可不需要开发组件库, 直接操作 Dom 即可不需要设计模板语法, 不需要编写 webview-render, 让 js 直接操作 dom 即可js 调用原生能力的接口还是需要, Android/iOS 开发也需要, 后台开发可有可无----如果把调用原生能力的 js 传到 cdn 上对外开放, 允许开发者用自己的域名发布应用的话, 那后台开发也可以省掉。唯一的问题是...这不就是 js-bridge/hybrid 吗这当然是 js-bridge, 但没有什么. 作为一名成熟的技术人员, 根据任务目标选择合适的解决方案而不是最炫的解决方案是基本准则. 所以我们实际要解决的问题是, 是什么让微信团队放弃了简单明快的 js-bridge,而去选择了成本高昂前途未知的小程序方案(微信 15 年推出小程序时看衰的人不在少数)再回顾一下我们需要实现的任务目标和小程序/js-bridge/React-Native方案间的对比:需求目标&实现方法/方案名小程序方案js-bridge + webview 缓存改造React-Native首次快速加载 调用接口, 对特定小程序资源进行预缓存 调用接口, 对 url 资源进行预缓存 调用接口, 对特定应用资源进行预缓存二次启动快速加载 在本地缓存使用过的小程序的静态资源 通过修改 webview, 对使用过的页面静态资源进行缓存.如果本地已有缓存则直接读取缓存, 跳过网络加载流程. 或者直接利用 E-tag 字段对静态资源进行缓存 在本地缓存使用过的应用的静态资源更强大的能力 取决于原生向小程序应用开放多少能力 取决于原生向 js-bridge 开放多少能力 取决于原生向 React-Native 开放多少能力原生的体验 最终界面渲染在 webview 上, 并非原生体验. 对特殊标签(map/canvas)才使用原生渲染 最终界面渲染在 webview 上, 并非原生体验. 真正的原生应用----缺点是官方对很多原生能力欠奉, 例如视频播放功能, 到 2021 年 9 月仍没有官方支持高效和简单的开发 类 vue 语法, 但由于不支持 Dom API, 仍有一些学习成本 原汁原味的 web 应用开发体验, 如假包换 理论上可以直接写 React, 实际使用时受制于平台具体实现, 限制很大. 例如到 2021 年 9 月仍没有完善的虚拟列表支持易用且安全的微信数据开放 取决于原生能力开放度 取决于原生能力开放度 取决于原生能力开放度从表格可以看出, 在实现宣传中的任务目标方面, 小程序对其他竞品方案并没有决定性的优势。有观点认为小程序优势在于逻辑进程渲染进程分别进行, 所以加载速度会比网页快. 但实际上, 百度首页渲染时间分析显示, 网页渲染时间只有 58ms, 只占总渲染时长的 1.9%, js 运行时长(956ms)和静态资源加载时长(145ms)才是可控的占比大头。如果考虑到逻辑进程和渲染进程之间通信所消耗的时间, 以及不管是小程序还是 js-bridge 方案, 页面最终运算结果总会呈现在 webview 上这一事实. 双进程方案由于多了启动逻辑进程和进程通信的步骤, 在同等优化层次的情况下, 其性能只会比 js-bridge 更差, 不会更好。微信小程序启动流程 :hybrid 应用启动流程 :实际上, 微信小程序文档自己也提到, 微信是先提供了 js-bridge , 然后才提出了小程序方案。所以, 问题来了:什么才是小程序方案优于 js-bridge 等其他方案的关键因素小程序方案的真正优势2015 年, 微信首先推出了 js-bridge 方案向公司内部开发者开放原生能力, 但很快被平台上的其他开发者发现, 于是微信顺带推出了正式的 js-sdk 方案, 希望作为平台向开发者提供更多能力。但是, 违规应用层出不穷, 由于使用的是 js-bridge 方案, 所以微信只能通过封禁域名的方式对页面进行限制. 但微信的运营团队很快发现, 由于预期收入很高而违规成本又极低(域名 35 元/个/年), 黑产灰产团队完全不在乎域名的损失. 也就是说, 在微信平台上, js-bridge 虽然可以开放能力, 但却不能限制谁去使用这些能力. 不开放能力则平台生态难于发展, 贸然开放则又是稚子怀千金于闹市. 在这种情况下,安全可控成为了微信对技术方案的最高要求, 准确来说, 是这三点:不允许开发者把页面跳转到其他在线网页----确保审核人员看到的页面就是最终展示的页面不允许开发者直接访问 DOM----避免潜在 hack 点不允许开发者随意使用 window 上的某些未知的可能有危险的 API----白名单是最好的防御对应于这种诉求, 逻辑层和表现层完全分离的双进程方案, 对微信而言就是必然选择。通过限定 js 文件只能在 V8 容器中运行, 对业务方可调用的全局函数采用白名单模式, 解决了 js 本身带来的风险引入发布机制后, 开发者所需的静态资源可以被预先声明或缓存, 页面加载和切换过程中可以展示过度动画, 解决了页面打开过程中的白屏问题, 优化了用户体验.通过注册审核机制, 可以对平台应用进行预先审查, 对违规开发者按照申请主体进行封禁, 解决了域名模式下风险管控事实性瘫痪的问题.最关键的, 通过注册审核制, 页面开发者的身份得到了保证, 为更多深度功能的开放提供了前提.微信的国务院政务平台小程序支付宝的电子医保卡小程序...小程序平台的关键优势不在于性能/开发体验, 而在于为平台提供了一个安全可控的环境, 使之可以安心的向平台内的开发者暴露大量原来不可外露的原生能力, 除此之外, 快速发版, 页面载入时 loading 效果优化, 消除切换页面期间的白屏都属于小程序的附赠功能, 在技术选型中的权重可以忽略不提。所以, 评估是否需要小程序平台的关键在于以下几点:是否切实需要一个安全可控的环境用户向前端开发暴露原生能力(例如银行卡余额查询功能之于云闪付)是否准备将应用作为平台接入外部开发者, 对外开放(例如微信/百度/美团/京东)是否有相关的技术储备解决小程序平台开发过程中可能出现的问题(例如 IDE 的构建, 最近使用小程序功能的实现)明确了这三个问题的答案后, 剩下的, 就只是技术/成本问题. 所以问题来了, 小程序的开发路线图, 应该是什么样的在制定开发路线图前, 我们要先梳理小程序的业务流程, 以及相关的技术点。小程序业务流程小程序的业务流程可以分为外围和内部两部分. 外围指的是业务方从创建小程序到在 App 上启动的一系列操作, 内部则是小程序在 App 上从启动到退出的全部过程, 这里我们分开讨论。小程序外围流程小程序外围流程主要分为两部分:首先是注册发布流程:需要实现以下模块&功能:-后台-小程序注册接口-上传接口-提审接口-发布接口-IDE-创建小程序-npxminiprogram-clicreate-编辑-打开已有项目-预览小程序-npxminiprogram-clistart-小程序打包-npxminiprogram-clibuild-获取小程序信息-向后台上传小程序-登录后台,获取上传token-miniprogram-cli-整合在IDE中-提供create/start/build功能其次是启动流程:对应的, 是以下模块&功能:-App(Android&iOS)-小程序广场页(一般是聊天列表页下拉)-接口调用(获取小程序具体配置)-静态资源下载&校验-启动小程序-后台-根据预设条件判断detail接口返回值-符合条件返回小程序静态资源地址&md5校验值-不符合条件走异常流程-小程序未上线-小程序已下线-小程序已被屏蔽-所在平台未开通小程序-所在城市未开通小程序-所在用户组没有访问小程序权限-基础库版本过低-基础库版本过低,降级到h5地址-基础库版本为特定值,需要返回指定静态资源内容(锁版本)调研期间我们可以不考虑具体实现方案, 只整理完成小程序项目所需的前置技术点, 大致可以分为这么几类:#IDE选型-[]构建IDE可选方案集-[]VSCode插件-[]Electron+代码编辑器-[]代码编辑器方案-[][monaco-editor](https://microsoft.github.io/monaco-editor/)-[][vscode-web](https://github.com/microsoft/vscode/blob/main/remote/web/package.json)-[][code-server](https://github.com/cdr/code-server)(第三方公司实现的web版vscode)-[]CodeMirror-[]ace.js-[]订制VSCode-[][Theia](https://theia-ide.org/)-[][阿里-开天IDE-未公开发布](https://developer.aliyun.com/article/762768)-[]编写界面-[]创建小程序-[]登录小程序后台(以获取上传用的token)-[]启动预览-[]启动构建-[]上传小程序包-[]类chrome的DevTools#cli工具-[]制定/维护小程序项目模板-[]基于模板创建小程序项目(npxminiprogramcreate)-[]启动小程序开发环境(npxminiprogramstart)-[]构建小程序安装包(npxminiprogramstart)-[][进阶]打包输出source-map,支持监控线上错误/查看报错#App-[]小程序启动流程设计-[]逻辑进程渲染进程间通信方案设计-[]小程序实现方案设定-[]页面切换如何实现-[]前进/返回效果-[]打开新页面效果-[]从App进入小程序/从小程序跳转到App/从小程序跳转到App再返回小程序的交互过程如何实现/[进阶]如果跳转到外部App,如何实现(如微信小程序打开百度地图)-[]schema跳转方案-[]支付功能-[]本地静态缓存-[]Native&js通信方案实现-[]js如何调用Native中的接口-[]Native如何获取js中传入的参数-[]Native运行完成后,如何通知js.期间控制流程切换的时序图如何设定-[]js如何获取Native中执行方法后的结果-[]实现非ECMA语法-[]实现setTimeout#小程序后台-技术选型-项目方案(Express/koa)-ORM方案-CDN上传-redis库选择-日志记录-接口设计-Mock管理-文档管理-用户系统-注册/登录-项目权限管理-root用户-管理员-开发者-预览成员-小程序发布流程设计-上传->预览->提审->审核->发布-小程序项目配置-项目基础信息(logo/应用名/应用简介/etc)-降级策略-开城策略-注销应用-[进阶]监控系统-数据清洗-数据存储(ES/mongodb)-错误查询-source-map解析-性能监控-订制数据项-上报/处理/分析数据项#小程序基础库(运行在逻辑进程中)-[]API设计-[]页面启动-[]页面切换-[]页面路由管理-[]路由参数读取-[]触发页面生命周期事件#小程序webview-render(运行在渲染进程中)-[]订制渲染协议-[]向逻辑层转发Dom事件(支持冒泡)-[]单实例组件支持(例如地图组件)#组件库-[]技术方案选型-[]React-[]Vue-[][stencil](https://getstencil.com/)-[]特殊元素支持-[]Canvas#其他问题-[]构建小程序预览环境-[]版本管理与同步-[]alpha版本与正式版-[]管理小程序项目/小程序基础库/小程序webview-render/小程序组件库/Native小程序sdk之间版本对应关系-[]bug解决-[]逻辑进程引擎统一为V8-[]jsCore中setTimeout的bug其中, 最为关键的, 是这两个问题:在逻辑进程/渲染进程中, js 如何与 Native 进行通信 => 如果不能通信, 后续所有交互均无法进行在逻辑层中运行的 js, 如何在渲染层生成对应 Dom 操作, 以更新界面, 与用户交互 => 这是小程序的核心问题. 如果不能完成逻辑层 js 到渲染层 Dom 的惊险一跃, 整个小程序方案将会无从谈起欲知这两个问题究竟如何解决, 且听下文分解。参考资料微信官方文档_小程序技术发展史: https://developers.weixin.qq.com/miniprogram/dev/framework/quickstart微信小程序基础架构浅析: https://cloud.tencent.com/developer/article/1833749Taro Next H5 跨框架组件库实践: https://blog.aotu.io/notes/2020/04/13/2020-4-13-taro-components/Electron 在 Taro IDE 的开发实践: https://blog.aotu.io/notes/2020/04/07/electron-in-taro-ide/
预览时标签不可点
大前端69小程序5大前端 · 目录#大前端上一篇小程序开放平台架构指南(下)下一篇React16更新渲染源码分析关闭更多小程序广告搜索「undefined」网络结果
|
|