本篇看点
- 阅读目标:判断哪些重数据处理适合进入 Worker,并用对比实验验证收益。
- 核心问题:Worker 适合纯计算和重数据处理,不适合夹带 UI、副作用和导航逻辑。
- 对比迁移:对应 Flutter isolate/compute 和 iOS GCD/OperationQueue/Task.detached。
前言
移动端性能问题里,有一种很隐蔽:不是 UI 写错了,而是你在主线程做了太多事情。大 JSON 解析、批量过滤、图片处理、复杂排序、离线数据合并,都可能让页面滑动卡顿。
Flutter 里你会想到 isolate 和 compute;iOS 里会想到 GCD、OperationQueue、Task.detached。HarmonyOS 里,Worker 是处理这类任务的重要能力。
一. 什么时候需要 Worker
不是所有异步都需要 Worker。网络请求本身异步,不代表回调里的数据处理也轻。
适合放 Worker 的任务:
- 大数组过滤、排序、分组。
- 大 JSON 解析后再清洗。
- 批量计算推荐结果。
- 图片压缩、元数据处理。
- 离线缓存合并。
不适合放 Worker 的任务:
- 简单按钮点击。
- 少量表单校验。
- 轻量字符串拼接。
- 直接操作 UI 的逻辑。
二. Worker 的价值是保护 UI 线程
假设搜索历史和专辑数据很多,用户输入关键词后要过滤:
ts
function filterAlbums(keyword: string, albums: Album[]): Album[] {
return albums.filter((album: Album) => {
return album.title.includes(keyword) || album.author.includes(keyword);
});
}
数据少时没问题。数据多时,如果每次输入都在主线程跑过滤,输入会卡,列表滚动也会受影响。
Worker 的思路是:主线程只发送任务,Worker 处理完再把结果发回来。
三. 任务要设计成可序列化消息
Worker 通信采用消息传递。任务结构清楚,主线程和 Worker 的边界也会清楚:
ts
interface WorkerFilterRequest {
taskId: string;
keyword: string;
items: Album[];
}
interface WorkerFilterResponse {
taskId: string;
items: Album[];
costMs: number;
}
taskId 很关键,它用来处理竞态。用户快速输入时,旧任务可能晚回来,这时要避免覆盖新结果。
四. 仍然要防旧结果覆盖
Worker 不是用了就万事大吉。主线程收到结果后仍然要判断:
ts
private latestTaskId: string = '';
handleWorkerResponse(response: WorkerFilterResponse) {
if (response.taskId !== this.latestTaskId) {
return;
}
this.items = response.items;
}
这个问题和网络请求竞态完全一样。Flutter isolate、iOS 后台队列也都会遇到旧任务回填的问题。
五. Worker 只承接合适的任务
Worker 适合处理纯计算或重数据处理。页面路由、Toast、播放器控制、弹窗等 UI 逻辑,仍然留在主线程和页面控制层。
推荐边界:
txt
View
-> Store
-> WorkerTaskService
-> Worker
Store 发起任务,Worker 返回结果,Store 再决定页面状态。这样可测试,也不容易把 UI 和并发揉在一起。
六. 性能实验要有对比
Worker 案例适合提供两种模式:
- 主线程直接处理,观察卡顿和耗时。
- Worker 处理,观察 UI 可交互性。
对有 Flutter/iOS 背景的人,这种对比比 API 罗列更有价值。因为你能迅速把 Worker 映射到 isolate/GCD,但也能看到 HarmonyOS 的通信方式和限制。
七. 实践经验
第一,数据量很小也上 Worker,反而增加通信成本。
第二,Worker 返回旧结果覆盖新输入结果。
第三,Worker 里夹带 UI 逻辑,架构变乱。
第四,大对象频繁来回传,通信成本超过计算收益。
小结
Worker 的价值在于保护主线程体验。判断是否使用 Worker,要看任务是否重、是否频繁、是否能纯计算化、是否值得承担通信成本。
今日练习
- 给一次大数组过滤任务设计 request/response 消息结构。
- 加入
taskId,确保旧 Worker 结果不会覆盖新输入结果。 - 对比主线程过滤和 Worker 过滤的耗时与交互流畅度。