背景
中国移动云盘(原“和彩云网盘”)是中国移动重磅推出的安全、智能、不限速、移动用户免流的智能云盘,致力于成为5G时代用户个人与家庭的数字资产管理中心,是中国移动继语音、短信、流量后的“第四项基础服务”。
照片、音视频的备份和使用是市面上全部网盘用户的重点体验场景,用户将照片等资源备份到云盘,以节省本地资源存储。批量的图片、音视频缩略图加载,偶然因网络原因出现加载迟钝等异常。中国移动云盘技术团队,致力于实现极致流畅的图文加载体验连续优化。
办理方案
以中国移动云盘鸿蒙原生版为例,借助华为Remote Communication Kit提供的智能网络感知服务,中国移动云盘通过三个步调,提升了用户使用云盘时的加载体验,为用户提供更丝滑的云盘服务。
步调一:动态预加载机制
以中国移动云盘的相册为例,当用户打开相册时,图文加载地区分为预加载地区、预渲染地区以及可见地区。
首先,智能网络感知服务资助中国移动云盘优先保证用户可见地区的加载完成,并跟随屏幕滑动动态调解预加载地区,同时通过本地文件缓存替代实时加载的形式,在屏幕滑动时大大降低了图片白块概率;再通过减少预渲染地区预加载的图片数目,降低UI渲染带来的CPU负载开销。
步调二:动态取消加载机制
当用户快速滑动屏幕时,偶然候有的资源已经滑出了屏幕,但网络请求还未到达。中国移动云盘基于智能网络感知服务的网络请求可取消机制,在用户快速滑动时,将滑过屏幕的资源取消加载,降低网络负载。
步调三:智能网络感知下动态调控预加载地区机制
基于RCP的网络耗时统计本领,可以盘算出每个资源请求的平均耗时,感知网络质量并智能调解预加载地区。在网络质量好时,增大预加载地区,网络质量差时,就降低预加载地区。
结果展示
最终,通过中国移动云盘专家与华为网络通讯专家团结构建图文资源动态加载,实现了鸿蒙原生版中国移动云盘网络资源如本地资源一样的流畅加载体验。
优化前:偶然因网络原因出现加载占位图和加载过程动画。
优化后:随意滑动,图文内容加载非常流畅天然。
开辟指南
1、下载并安装:
- ohpm install @netteam/prefetcher
复制代码 有关 OpenHarmony ohpm 环境配置的更多信息,请参阅如何安装 OpenHarmony ohpm 包。
2、集成预取器:
在深入探究细节之前,需要提及两点。
1.预取程序驱动用户代码获取所显示聚会集的项目所引用的资源。换句话说,用户代码获取 URL 存储在聚集项目中的图像。
2.有两种使用 Prefetcher API 的方法。第一种方法假设生存项目的数据源实现了两种附加方法:prefetch()和cancel() IDataSourcePrefetching。第二种方法(稍后先容)使用用户注册的回调来执行相同的使命。方法的选择由用户决定,但“基于回调”的方法比“基于预取数据源”的方法更具上风:
更容易构造工作线程上的提取。
支持以数组形式出现的聚集,并因此支持Repeat组件。
通过遵循单一责任原则来更好地构造应用程序代码,由于数据源不负责执行获取。
3、使用“基于预取数据源”的方法
以下是Prefetcher 演示存储库中示例应用程序之一的具体代码片段。该应用程序演示了预取器库的使用。演示应用程序包罗大量图像。每幅图像都是在应用程序内合成的彩色矩形。获取操纵在主应用程序线程上执行。

- import { BasicPrefetcher, IDataSourcePrefetching } from '@netteam/prefetcher';
- import { image } from '@kit.ImageKit';
- import { create10x10Bitmap, getRandomColor } from 'examples_common'; // Code of these functions is omitted for brevity
- const ITEMS_ON_SCREEN = 8;
- @Component
- export struct PrefetcherDemoComponent {
- private readonly dataSource = new SimulationDataSource(2000, 500);
- private readonly prefetcher = new BasicPrefetcher(this.dataSource);
- build() {
- Column() {
- List() {
- LazyForEach(this.dataSource, (item: PictureItem) => {
- ListItem() {
- PictureItemComponent({ info: item })
- .height(`${100 / ITEMS_ON_SCREEN}%`)
- }
- }, (item: PictureItem) => item.title)
- }
- .onScrollIndex((start: number, end: number) => {
- this.prefetcher.visibleAreaChanged(start, end);
- })
- }
- }
- }
- @Component
- export default struct PictureItemComponent {
- @ObjectLink info: PictureItem;
- build() {
- Row() {
- Image(this.info.imagePixelMap)
- .objectFit(ImageFit.Contain)
- .width('40%')
- Text(this.info.title)
- .width('60%')
- }
- }
- }
- @Observed
- export class PictureItem {
- readonly color: number;
- title: string;
- imagePixelMap: image.PixelMap | undefined;
- key: string;
- constructor(color: number, title: string) {
- this.color = color;
- this.title = title;
- this.key = title;
- }
- }
- type ItemIndex = number;
- type TimerId = number;
- class SimulationDataSource implements IDataSourcePrefetching {
- private readonly items: PictureItem[];
- private readonly fetchDelayMs: number;
- private readonly fetches: Map<ItemIndex, TimerId> = new Map();
- constructor(numItems: number, fetchDelayMs: number) {
- this.items = [];
- this.fetchDelayMs = fetchDelayMs;
- for (let i = 0; i < numItems; i++) {
- const item = new PictureItem(getRandomColor(), `Item ${i}`);
- this.items.push(item);
- }
- }
- async prefetch(index: number): Promise<void> {
- const item = this.items[index];
- if (item.imagePixelMap) {
- return;
- }
- // Simulate long running operation
- return new Promise<void>(resolve => {
- const timeoutId = setTimeout(async () => {
- this.fetches.delete(index);
- const bitmap = create10x10Bitmap(item.color);
- const imageSource: image.ImageSource = image.createImageSource(bitmap);
- item.imagePixelMap = await imageSource.createPixelMap();
- resolve();
- }, this.fetchDelayMs);
- this.fetches.set(index, timeoutId);
- });
- }
- cancel(index: number): void {
- const timerId = this.fetches.get(index);
- if (timerId) {
- this.fetches.delete(index);
- clearTimeout(timerId);
- }
- }
- totalCount(): number {
- return this.items.length;
- }
- getData(index: number): PictureItem {
- return this.items[index];
- }
- registerDataChangeListener(_: DataChangeListener): void {}
- unregisterDataChangeListener(_: DataChangeListener): void {}
- }
复制代码 该类PictureItem表现引用需要“下载”才能出现给用户的数据的项目。获取后,它将得到Image组件的像素图。
是SimulationDataSource与预取器和组件链接的数据源LazyForEach。其单个参数指定列表大小。它负责执行获取操纵并模拟获取图像,并附加延迟,可在其构造函数中设置。延迟以毫秒为单元指定。
一旦图片准备好,就会包装每个并允许显示图像PictureItemComponent。PictureItem
探索更多
Remote Communication Kit是HarmonyOS体系提供对HTTP发起数据请求的NAPI封装,通过@hms.collaboration.rcp(简称rcp)模块将相关本领开放给开辟者,为开辟者提供基于rcp的文件上传与下载的开辟实践。
访问Remote Communication Kit华为开辟者联盟官网,以及开辟者方案示例,了解更多详情开始使用。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |