这是我参与「第五届青训营 」伴学笔记创作活动的第 9 天
一、本堂课重点内容:
本堂课的知识要点有哪些?
- 认识跨端技术
- 跨端技术方案
- 基于小程序跨端技术实践
二、详细知识点介绍:
认识跨端技术
跨端背景
伴随着业务模式的不断发展,产生了愈来愈多的业务场景,同时技术发展也产生了很多的客户端:PC端(Windows/Mac),移动端(安卓/IOS),web端/loT设备(车载设备/手表)等
痛点:
- 各端功能几乎一致但需要单独配置人员
- 开发维护成本高
- 安卓IOS发版周期长
跨端技术方案目标
- 研发效率高——学习成本低、多端一致
- 用户体验好——稳定性好,性能体验好
- 动态化——支持动态下发,满足日益增长的业务需求
跨端技术方案
hybrid方案
基于 webview 渲染界面,通过 JS bridge 把一部分功能系统开放给 JS 调用。
WebView容器的工作原理是基于Web技术实现界面和功能,通过将原生接口封装、暴露给JavaScript调用,JavaScript编写的页面可以运行在系统自带的WebView中。
优点:
- 对前端开发者友好
- 开发成本低
- 搭建桥接层和与原生能力打通
- CSS全集
- 一致性好
缺点:
受限于桥接层, 浏览器内核渲染独立于系统组件,无法保证原生体验,渲染效果差, 性能中等
原生渲染方案
通过 js 开发,通过中间层桥接之后使用原生组件来渲染我们的 UI,最著名: React Native
React Native 是一个使用JavaScript 和 React 来编写跨终端移动应用(Android 或 IOS)的一种解决方案
优点
1.RN可将标记元素转化为真实的原生UI元素,利用在任何平台上所呈现视图的现用方法
2.异步执行.RN于主UI线程分开工作,所以应用程序可以在不牺牲功能的前提下保持最大的性能
3.RN创建的应用程序允许开发人员创建和构建跨平台应用程序,这些应用程序时客户端的完全本机应用程序,因为它使用基于IOS活Android组件构建的JavaScript组件.节省了跨平台应用程序开发事件,并且应用程序维护更便宜
4.在组件开发方面,Native移动应用程序使用大量代码和类来在UI中进行渲染,但是RN只使用组件名称并声明其属性,它将在UI中呈现着两个平台都为移动应用开发节省了时间
5.无缝跨平台,通过React的声明式组件机制和JavaScript代码,现有的原生代码和api可以完美地嵌合到React组件中.提高了开发效率
6.秒速刷新,保持即刷新,借助JavaScript地动态特性,React Native能够让你光速迭代.
缺点
1.项目版本更新维护比较频繁
2.整体性能不如原生
3.涉及底层地功能,需要Android和IOS双端单独开发,JS调用
4.学习成本高,需要熟悉原生
5.试错成本高,有些问题较少解决方案,易耽误开发进度
调用系统功能和 Hybrid 类似,渲染界面使用原生组件渲染效率高,用户体验好
缺点是只能用系统原生的能力,所以和 web 端相比能力有限
自渲染方案
利用 skia 重新实现渲染管线,不依赖原生组件,因为安卓 ios 底层也使用类似的引擎来进行渲染,最著名的是:Flutter
Flutter是谷歌的移动UI框架,可以快速在iOS和Android上构建高质量的原生用户界面。 Flutter可以与现有的代码一起工作。在全世界,Flutter正在被越来越多的开发者和组织使用,并且Flutter是完全免费、开源的,可以用一套代码同时构建Android和iOS应用,性能可以达到原生应用一样的性能。
简单来讲,Flutter 从上到下可以分为三层:框架层、引擎层和嵌入层
框架层
底下两层被合并为一个dart UI层,对应的是Flutter中的dart:ui包,它是 Flutter Engine 暴露的底层UI库,提供动画、手势及绘制能力。
Rendering 渲染层,依赖于 Dart UI 层,渲染层会构建一棵由可渲染对象的组成的渲染树,当动态更新这些对象时,渲染树会找出变化的部分,然后更新渲染。渲染层可以说是Flutter 框架层中最核心的部分,它除了确定每个渲染对象的位置、大小之外还要进行坐标变换、绘制(调用底层 dart:ui )。
Widgets 层是 Flutter 提供的的一套基础组件库,在基础组件库之上,Flutter 还提供了 Material 和 Cupertino 两种视觉风格的组件库,它们分别实现了 Material 和 iOS 设计规范。
引擎层
引擎层是Flutter的核心,由C++实现,其中包括了 Skia 引擎、Dart 运行时、文字排版引擎等。在代码调用 dart:ui库时,调用最终会走到引擎层,然后实现真正的绘制和显示
嵌入层
嵌入层主要是将 Flutter 引擎 ”安装“ 到特定平台上,Flutter 代码可以通过嵌入层,以模块方式集成到现有的应用中,也可以作为应用的主体
使用 Dart 语言开发,页面渲染不依赖平台 系统能力依赖于平台提供
小程序方案
使用 DSL + JS 来开发,通过中间层桥接后调用原生能力,使用 webview 来渲染UI,它能写的代码也是有限的
重点:小程序的逻辑层和渲染层是分开的,是双线程的运行模式 渲染层,又叫视图层主要负责小程序的UI渲染,也就是展示给用户的部分,界面渲染相关的任务全都在 WebView 里执行,如果一个小程序存在多个界面,就存在多个 WebView 线程。因为小程序的视图和逻辑是分离的,所以不能在小程序 js 逻辑里操作 DOM 等元素,所以例如 Jquery 之类的框架不能在小程序里使用 逻辑层,主要负责逻辑处理、数据请求、接口调用等内容,它采用 JsCore 线程运行相关的 js,因为 JsCore 不是node 环境,所以部分的包在小程序里不能运行 系统层是负责和两个线程通信,并且和原生平台对接的,它可以调用一些平台提供给用户的能力,也可以帮助用户完成一些需要操作系统完成的内容,比如调用相机等等
分为两个线程:渲染线程使用 webview, 因为面向前端开发者,逻辑线程调用 JSC/安卓v8 这样一个单独运行 js 的环境
上述两个部分和我们的原生平台进行对接,然后原生平台调用接口给予能力返回调用结果, 在 Web 开发中,每个页面中 JS 线程与渲染线程是互斥的;
而在小程序中,JS 线程与渲染线程(视图层)是独立的,视图的渲染更新,并不会阻塞 JS 的执行,同时 JS 的逻辑执行,也不会阻塞视图的渲染更新。
JS 驱动视图的更新是异步的,并且 JS 无法直接访问视图的 DOM。逻辑层可以通过 api 调用客户端的原生能力,通过 setData 修改视图层的数据,视图层可以通过触发事件调用逻辑层的方法。
使用小程序 DSL + JS 开发,通过中间层桥接后调用原生能力,使用 webview 来渲染 UI 界面。
跨端技术方案对比
基于小程序跨端技术实践
Step.1 注册字节开发者,登录字节开发者平台后点击创建小程序(注:需要通过主体验证)。
Step.2 点击开发设置,设置webview域名,仅支持https。
Step.3 下载安装字节开发工具,选择创建项目,项目名称和目录可以自定义,AppID需要填写开发者平台上的开发设置上的AppID
Step.4 在首页pages/index.ttml文件中,增加web-view,将scr后的域名改成要发布的域名地址。如果本身有小程序项目,可以在需要Smobiler项目的所在界面,配置web-view。(如果显示不支持打开非业务地址,请查看Step2,添加检验文件)
若需要配置默认标题,需要如下图所示,在项目项app.json中修改"navigationBarTitleText": "标题名称"
Step.5 当页面能正常显示后,点击右上角上传按钮,填写项目备注后选择上传(若是不支持打开业务地址,且开发者平台上已配置webview域名,存在延迟,可以等待一定时间后再预览)
Step.6 在开发者工具上完成上传后,登录开发者平台,可以在小程序详情页的版本管理中查看到上传的测试版本,填写当前版本信息并上传三张小程序内容截图,完成提审,审核将会在 1-2 个工作日完成。
审核通过后,开发者点击发布即可进入线上 版本。(审核、发布官方文档见microapp.bytedance.com/docs/zh-CN/…) 。
性能优化
主要的优化策略可以归纳为三方面:
启动小程序方面:
分包加载
控制代码包大小
页面及页面层级方面:
合理使用setData调用,减少setData次数和数据量
数据通信方面:
精简代码,降低WXML结构和JS代码的复杂性。
js中提高数据更新速度
wxml 中提高数据更新速度
三、引用参考:
字节小程序开发指南:t.csdn.cn/Bur17