这是我参加[第五届青训营]伴学笔记创作活动的第8天
本课程重要内容
- 跨端是什么,给大家介绍跨端产生的背景及解决的问题
- 跨端技术方案介绍,给大家介绍目前主流的跨端技术方案(hybrid 方案/原生渲染方案/自渲染方案/小程序方案)以及对比
- 基于小程序跨端实践,带大家了解开发抖音小程序以及优化小程序
通过课后回顾的问题,巩固所学知识
跨端
随着业务的发展,产生了越来越多的业务场景,同时随着技术的发展,产生了越来越多的端,PC端(Windows、Mac),移动端(安卓、iOS)、web端、IoT设备(车载设备、手表)等,但各端功能几乎一致却需要单独配置研发人员,开发和维护成本较高,并且安装和iOS发版周期长,所以有了跨端的概念。
理想的跨端技术方案的目标
- 研发效率高-学习成本低且多端一致性高
- 用户体验好-稳定性高和性能体验好
- 动态化-支持动态化下发,满足日益增长的业务需求
目前市面上的跨端技术方案
hybrid方案
基于WebView(浏览器)渲染,通过JS Bridge把一部分系统能力开放给JS调用。
原生渲染方案
使用JS开发,通过中间层桥接后使用原生组件来渲染UI界面
例子:React Native
与hybrid相比,渲染底层不同
自渲染方案
利用开源渲染引擎Skia重新实现渲染管线,不依赖原生组件
例子:Flutter
小程序方案
使用小程序DSL+JS开发,通过中间层桥接后调用原生能力,使用webview 来渲染UI界面。
例子:字节小程序
小程序运行原理
四种技术方案比较
| 技术方案 | 视图层 | 逻辑层 | 优点 | 缺点 |
|---|---|---|---|---|
| hybrid方案 | webview | webiew JS thread | 1.开发成本低2.CSS全集3.一致性好 | 1.性能中等 |
| 原生渲染方案 | 原生组件 | JS Engine | 1.性能好 | 1.CSS子集2.一致性一般 |
| 自渲染方案 | Skia | Dart VM | 1.性能最好2.一致性好 | 1.CSS子集2.Dart生态一般3.开发成本较高 |
| 小程序方案 | webview+原生组件 | JS Engine | 1.开发成本低2. CSS 全集3.一致性好 | 1.性能较好 |
开发小程序实战
界面展示
小程序性能优化
【意义】为了留住用户,提升转化率,提升用户体验
【性能指标】LCP尽可能提前
指标看板
【优化手段】从启动性能、运行时性能两方面的体验来分析
较少包体积
合理使用分包
使用分包加载是优化小程序启动耗时效果最明显的手段。建议开发者按照照功能划分,将小程序的功能按使用频率和场景拆分成分包,实现代码包的按需加载。同时需要注意控制分包数量,避免过多拆包。
移除无用文件
目前小程序打包是会将工程下所有文件都打入代码包内,在开发迭代过程中,如果不及时清理无用的资源,会使得包体积越来越大,开发过程中要养成良好的习惯--及时清理没有使用到的资 源,防止资源冗余
控制包内静态资源
避免在代码包中包含或在ttss中内联过多,过大的代码包内的图片,应尽量采用网络图片,代码包内的图片一般应只包含一些体积较小的图标,声音,视频等其他类型的资源应尽量避免放到代码包中。
小程序代码包在下载时会使用Gzip算法进行压缩,降低下载时传输的数据量。这些资源文件会占用大量代码包体积,并且通常难以进一步被压缩,对于下载耗时的影响比代码文件要大很多。
减少同步逻辑
优先使用异步API
在小程序启动流程中,会注入开发者代码并顺序同步执行App.onLaunchApp.onShow, Page.onLoad, Page.onShow。在小程序初始化代码(Page,App定义之外的内容)和启动相关的几个生命周期中,应避免过度使用Sync结尾的同步API
避免启动时运行过多同步代码
在小程序初始化代码(Page,App定义之外的内容)和启动相关关的几个生命周期中,应避免执行复杂的计算逻辑
更早的展示首屏数据
尽早调用关键API和请求
首屏绘制可能会依赖API数据和网络请求,尽早的调用相关API,发送相关关网络请求,能提前数据准备时间
接入数据预取。
大部分小程序在渲染首页时,需要依赖服务端的接口数据,小程序为开开发者提供了数据预取,方便开发者在小程序冷启动时提前发起请求,并缓存请求内容
避免非必要的reLaunch
reLaunch会先关闭所有页面,非必要的reLaunch会导致首页白屏时间明显显增长。
合理缓存数据
网络数据缓存
小程序提供了tt.getStorage、tt.setStorage等读写本地缓存的能力,数据居存储在本地,返回的会比网络请求快。如果开发者基于某些原因无法采用数据预拉取,我们推荐优先从缓存中获取数据来渲染视图,等待网络请求返回后进行更新。
API数据缓存
对调用频次高的方法的结果进行缓存,例如对于tt.getSystemlnfo,tt.getSystemInfosync的结果应进行缓存,避免重复调用。
图片优化
选择合适的图片格式
对于不需要透明格式的图片,推荐采用jpeg格式来代替png格式。如果有条件,尽可能使用webp格式图片,能大幅缩小图片体积。
进行合理的压缩
图片尽可能压缩到200kb以下,压缩的同时也需要兼顾图片的质量
使用CDN并开启缓存
使用CDN,能大幅减少图片资源的下载速度。开启HTTP缓存控制后,下一次加载同样的图片,会直接从缓存读取,大大提升图片加哦速度。
更多优化手段
框架骨架屏
通过小程序框架提供骨架屏机制,能比业务中创建的骨架屏加载时机更靠前,使用这一机制,可以减少用户的白屏等待时长,给用户带来更好的体验。
占位组件
为自定义组件配置占位组件,可以指定该组件不在小程序启动时立即注入,而是等到页面中其他元素渲染完成后才注入。通过占位组件,能减少启动耗时。
合理使用setData
- 减少发送频率
- 动画不使用setData
合理使用自定义组件
合理的拆分组件数量
Page中的setData会触发渲染层以页面级别进行diff操作,如果页面比较复杂且没有使用自定义组件,那么diff的成本会很高,导致体验比较差(更新卡顿、不粘手等感受)。如果页面转换 为若干个组件,如果在组件中setData,只会触发渲染层对应组件的diff操作,diff成本会降低很多,使用体验也会提升很多。
只注册当前使用的组件
同时在usingComponents建议只注册当前页面有使用到的自定义组件,在小程序框架会根据usingComponents中的自定义组件注册(无论开发我者在运行时是否有使用)
同步修改初始data
在app.json中增加配置component2:true后,支持在created生命周期期中修改自定义组件初始数据,自定义组件将在created生命周期执行完成后开始渲染。开启后有以下优化点:
- 能够很好的解决依赖计算逻辑导致的data频繁变更。避免初始数据依赖大量计算逻辑时,由于data变化导致页面渲染内容闪动或频繁变动问题
- 优化observer触发方式,减少因数据变更导致的通信,提升小程序性能体验,合理的使用方式能进一步提升用户体验
合理监听处理事件
合理监听处理scroll事件
避免在scroll事件中高频执行耗时操作,会明显降低FPS
去掉不必要的事件绑定
去掉不必要的事件绑定(ttml中的bind和catch),从而减少通信的数据量和次数
内存优化
及时解绑事件监听
事件监听结束后,应及时解绑监听器
及时清理定时器
开发者在开发如「秒杀倒计时」等功能时,可能会使用sethnterval设置定时器,页面或组件销毁前,需要调用clearlnteerval方法取消定时器
导航栏适配
适当开启自定义导航栏
避免在app.json中全局开启动态导航栏,仅在需要的页面中配置,降低适配成本。
关键信息避开状态栏和胶囊按钮
如果开启自定义导航栏,需要通过tt.getCustomButtonBoundingClieentRect获取自定义导航栏下不可改变的元素来进行导航栏的适配
X分屏适配
通过onResize监听显示区域变化
小程序支持组件和页面的生命周期函数onResize用于在显示区域的尺寸发生变化的时候返回当前页面的信息。其中组件需要作为页面配置置到app.json中触发事件
不使用JS设置ScrollView高度
scroll-view中分屏变为全屏时需要重新设置scroll-view高度,可能会会出现空白区域问题,建议使用CSS(vh)完成自适应布局
【性能评分工具】小程序开发工具自带的,在调试器的audits中,快速感知问题方向
【性能分析工具】在调试器的trace中,追寻具体问题位置
课后回顾
- 跨端解决了什么问题?
- 常见的跨端技术方案以及其技术原理和区别
- 跨端技术方案中的核心部分?
- 抖音小程序开发与 web 开发有哪些异同?
- 小程序性能优化会关注的性能指标以及进行性能优化的方向?可以使用哪些工具来提升效率?
- 小程序 setData 如何优化?