承接上一篇:HarmonyOS应用开发性能优化(篇二)
在使用Web组件加载H5页面时,经常会有长列表、视频等场景。由于Web目前最高只有60帧,想要更加流畅的体验,必须要将原生组件放到Web上。
同层渲染和非同层渲染显示Web页面的方式如下:
在有些主页场景,会跳转到各个复杂模块中去,有些模块并不是常用模块,我们可以使用动态延迟加载的方式,减少无用模块的加载。页面在引入依赖的加载模块时,如果不是首帧必须显示的内容模块,可以使用动态加载的方式(await import),延迟模块的加载时间,加快首帧显示的加载速度。
import { pageOne, pagesOneData } from './pageOne'
import { pageTwo, pagesTwoData } from './pageTwo'
import { pageThree, pagesThreeData } from './pageThree'
import { pageFour, pagesFourData } from './pageFour'
// ...
import router from '@ohos.router'
async loadPageOne(key: string) {
if (key == "pageOne") {
let { PageOneLoader } = await import("../pages/PageLoader")
this.PageOneLoader = PageOneLoader
}
}
首次绘制组件时,若组件被标记为启用renderGroup状态,将对组件以及其子节点进行离屏绘制,将绘制结果进行缓存,此后当需要重新绘制组件时,就会优先使用缓存而不必重新执行绘制了,从而降低绘制负载,优化渲染性能。
build() {
Column() {
Image(this.image)
.height(20)
.width(20)
.objectFit(ImageFit.Contain)
.margin({left: 15})
Text(this.text)
.fontSize(10)
.fontColor("#182431")
.margin({top: 5})
.width(50)
.opacity(0.8)
.textAlign(TextAlign.Center)
}
.backgroundColor("#e3e3e3")
.width(50)
.height(50)
.borderRadius(25)
.renderGroup(true)
}
控制元素显示与隐藏是一种常见的场景,使用Visibility.None、if条件判断等都能够实现该效果。其中if条件判断控制的是组件的创建、布局阶段,visibility属性控制的是元素在布局阶段是否参与布局渲染。使用时如果使用的方式不当,将引起性能上的问题。如果会频繁响应显示与隐藏的交互效果,建议使用切换Visibility.None/Visibility.Hidden和Visibility.Visible来控制元素显示与隐藏,在组件无需展示的时候进行缓存,提高性能。
build() {
Column() {
Button("Switch visible and hidden").onClick(() => {
this.isVisible =!(this.isVisible)
}).width('100%')
Stack() {
Scroll() {
Column() {
ForEach(this.data, (item: number) => {
Image($r('app.media.icon')).width('25%').height('12.5%')
}, (item: number) => item.toString())
// 使用显隐控制切换,不会频繁创建与销毁组件
}.visibility(this.isVisible? Visibility.Visible : Visibility.None)
}
}
}
}
下面通过一个动画场景的示例,演示如何有效减少渲染进程中的冗余开销,从而提升系统性能与界面流畅度。
组件转场动画指在组件出现和消失时做动画,有两种实现方式:
Text("toggle state")
.onClick(() => {
this.count++
const thisCount: number = this.count
this.show = true
// 通过改变透明度属性,对Text控件做隐藏或出现的动画
animateTo({ duration: 1000, onFinish: () => {
// 最后一个动画且是让Text控件隐藏的动画,再改变条件使控件消失
if(thisCount === this.count && this.mOpacity === 0) {
this.show = false
}
}}, () => {
this.mOpacity = this.mOpacity === 1? 0 : 1
})
})
build() {
Column() {
Row() {
if (this.show) {
Text('value')
// 设置id,使转场可打断
.id("myText")
.transition(TransitionEffect.OPACITY.animation({duration: 1000}))
}
}
.width("100%")
.height(100)
.justifyContent(FlexAlign.Center)
Text("toggle state")
.onClick(() => {
// 通过transition,做透明度的出现或消失动画
this.show =!this.show
})
}
}
由于每次animateTo都需要进行动画前后的对比,使用多个animateTo的性能就不如只使用一个animateTo。特别是针对设置在同一个组件的属性,能减少该组件更新的次数。
func1() {
animateTo({curve: Curve.Sharp, duration: 1000}, () => {
// 不推荐
this.w = (this.w === 100? 200 : 100)
})
}
func2() {
animateTo({curve: Curve.Sharp, duration: 1000}, () => {
// 不推荐
this.color = (this.color === Color.Yellow? Color.Red : Color.Yellow)
})
}
func() {
animateTo({curve: Curve.Sharp, duration: 1000}, () => {
// 推荐
this.w = (this.w === 100? 200 : 100)
this.color = (this.color === Color.Yellow? Color.Red : Color.Yellow)
})
}
animateTo会将执行动画闭包前后的状态进行对比,对差异部分进行动画。为了对比,会在执行animateTo的动画闭包之前,将所有变更的状态变量和脏节点都刷新。如果多个animateTo之间存在状态更新,会导致执行下一个animateTo之前又存在需要更新的脏节点,可能造成冗余更新。
struct MyComponent {
@State width: number = 200
@State height: number = 50
@State color: Color = Color.Red
build() {
Column() {
Text( "click" )
.height(this.h)
.onClick(() => {
this.w = 100
// h是非动画属性
this.h = 100
animateTo({curve: Curve.Sharp, duration: 1000}, () => {
this.w = 200
})
this.color = Color.Yellow
animateTo({curve: Curve.Linear, duration: 2000}, () => {
this.color = Color.Red
})
})
}
.width("100%")
.height("100%")
}
}
struct MyComponent {
@State w: number = 100
@State h: number = 50
@State color: Color = Color.Yellow
build() {
Column() {
Text("click")
.height(this.h)
.onClick(() => {
this.w = 100
animateTo({curve: Curve.Sharp, duration: 1000}, () => {
this.w = (this.w === 100? 200 : 100)
})
animateTo({curve: Curve.Linear, duration: 2000}, () => {
this.color = (this.color === Color.Yellow? Color.Red : Color.Yellow)
})
})
}
.width("100%")
.height("100%")
}
}
--THE END--
HarmonyOS应用开发性能优化(篇一)
HarmonyOS应用开发性能优化(篇二)
HarmonyOS应用开发性能优化(篇三)
更多内容请参见视频教程:《HarmonyOS应用开发实战指南》