perf(app): OTA下载进度节流 — 20%步进轻提示根治卡顿

问题: plus.nativeUI.showWaiting 每次下载回调都触发原生等待框更新,
      高频调用导致主线程阻塞产生无响应/掉帧。

修复:
1. 废除 plus.nativeUI.showWaiting 全系列调用
2. 改用 uni.showToast + position:'top' 顶部轻提示
3. 核心: 节流阀 lastProgress — 每跨越20%才触发一次UI更新
   整个下载过程最多5次toast (20/40/60/80/100%),根治跨端卡顿
4. 初始toast '已转入后台下载...' 给用户明确反馈
5. 安装/重启逻辑保持不变(静默安装+2s自动重启)
This commit is contained in:
2026-08-11 18:01:17 +08:00
parent 3cb85f28b4
commit 7e4d796ce3

View File

@ -109,35 +109,32 @@ export default {
success: (modalRes) => {
if (!modalRes.confirm) return;
// 🚀 使用原生等待框,原地更新文字,杜绝闪烁
plus.nativeUI.showWaiting("正在下载 0%");
// 初始反馈:告知用户已转入后台
uni.showToast({ title: '已转入后台下载...', icon: 'none', position: 'top' });
const downloadTask = uni.downloadFile({
url: wgtUrl,
success: (downloadRes) => {
if (downloadRes.statusCode !== 200) {
plus.nativeUI.closeWaiting();
uni.showToast({ title: "下载失败", icon: "none" });
return;
}
// 安装阶段 — 原生等待框直接更新文字,无闪烁
plus.nativeUI.showWaiting("正在安装...");
// 安装阶段 — toast 轻提示
uni.showToast({ title: "正在安装...", icon: "none", position: "top" });
plus.runtime.install(
downloadRes.tempFilePath,
{ force: true },
() => {
plus.nativeUI.closeWaiting();
console.log("[OTA] WGT 安装成功");
// 🚀 静默重启toast 提示后自动重启,无需用户杀后台
// 🚀 静默重启toast 提示后自动重启
plus.nativeUI.toast("新版本已就绪,即将重启...");
setTimeout(() => {
plus.runtime.restart();
}, 2000);
},
(err) => {
plus.nativeUI.closeWaiting();
console.error("[OTA] 安装失败:", err.message);
uni.showToast({
title: "更新失败: " + (err.message || "未知错误"),
@ -148,18 +145,24 @@ export default {
);
},
fail: (err) => {
plus.nativeUI.closeWaiting();
console.error("[OTA] 下载失败:", err.errMsg);
uni.showToast({ title: "下载失败,请检查网络", icon: "none" });
},
});
// 下载进度 — 稳定更新原生等待框文字,不会闪烁
// 🚀 核心性能优化:节流阀 — 每跨越 20% 才触发一次轻提示
let lastProgress = 0;
if (downloadTask && downloadTask.onProgressUpdate) {
downloadTask.onProgressUpdate((res) => {
const pct = res.progress;
if (pct < 100) {
plus.nativeUI.showWaiting(`正在下载 ${pct}%`);
if (pct - lastProgress >= 20 && pct < 100) {
lastProgress = pct;
uni.showToast({
title: `新版本下载中 ${pct}%`,
icon: "none",
position: "top",
duration: 1200,
});
}
});
}