图片加载阻塞进程
在做活动或者做年度总结的活动页面时,需要自己做一个加载器,来确保用户正式进入浏览后有一个比较好的阅读体验,特别是针对图片部分,处理不好就会遇见页面白屏或者加载动画消失不见,特别是针对ios 上的webkit机制。
- 正常的视频如下(文章丢失了,所以找不到了)

- 异常下视频所示,没有进度条了(文章丢失了,所以找不到了)

- 我写的脚本如下
js
loadResources(resources, onComplete) {
resources = Object.assign(resources, this.cqLinks);
const keys = Object.keys(resources);
const total = keys.length;
let loaded = 0;
// 预加载图片
keys.forEach((key) => {
const img = new Image();
img.src = resources[key];
img.onload = () => {
loaded++;
const progress = Math.round((loaded / total) * 100);
this.resourceProcess = progress;
if (loaded === total) {
onComplete && onComplete();
}
};
img.onerror = () => {
console.error(`Failed to load image: ${resources[key]}`);
loaded++;
const progress = Math.round((loaded / total) * 100);
this.resourceProcess = progress;
if (loaded === total) {
onComplete && onComplete();
}
};
});
},为什么会产生这种现象
webview 在处理并发的图片onload回调,会占用主线程,而是 iOS WKWebView 在“并发图片 onload 回调”这个层面本身就扛不住。 单只这个样的现象
iOS WebView(WKWebView)在「并发 Image onload」时,会长期占用主线程
UI 渲染被完全饿死
最开始我使用了throttle/raf以为会解决问题,但其实没有,必须不让同时触发

该怎么避免这种问题
减少并发onload的使用,给浏览器一些空闲的时间,代码如下
js
async loadResources(resources, onComplete) {
resources = Object.assign({}, resources, this.cqLinks);
const urls = Object.values(resources);
const total = urls.length;
let loaded = 0;
let index = 0;
const concurrency = 3;
const updateProgress = () => {
this.resourceProcess = Math.round((loaded / total) * 100);
};
const worker = async () => {
while (index < urls.length) {
const current = index++;
await new Promise((resolve) => {
const img = new Image();
img.src = urls[current];
img.onload = img.onerror = () => {
loaded++;
updateProgress();
resolve();
};
});
await new Promise(r => requestAnimationFrame(r));
}
};
await Promise.all(
Array.from({ length: concurrency }, worker)
);
onComplete && onComplete();
}