Skip to content

Commit 09e2a1b

Browse files
committed
⚡️ 优化站点图标加载问题 #474
1 parent 9c016db commit 09e2a1b

2 files changed

Lines changed: 75 additions & 57 deletions

File tree

src/app/service/service_worker/system.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,15 @@ export class SystemService {
3232
});
3333
this.group.on("loadFavicon", async (url) => {
3434
// 加载favicon图标
35-
return fetch(url)
36-
.then((response) => response.blob())
37-
.then((blob) => createObjectURL(this.sender, blob, true))
38-
.catch(() => {
39-
return "";
40-
});
35+
// 对url做一个缓存
36+
return Cache.getInstance().getOrSet(`favicon:${url}`, async () => {
37+
return fetch(url)
38+
.then((response) => response.blob())
39+
.then((blob) => createObjectURL(this.sender, blob, true))
40+
.catch(() => {
41+
return "";
42+
});
43+
});
4144
});
4245
}
4346
}

src/pages/store/utils.ts

Lines changed: 66 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -6,56 +6,71 @@ import Cache from "@App/app/cache";
66
import { SystemClient } from "@App/app/service/service_worker/client";
77
import { message } from "./global";
88

9-
// 在scriptSlice创建后处理favicon加载
9+
// 将数组分成指定大小的批次
10+
const chunkArray = <T>(array: T[], chunkSize: number): T[][] => {
11+
const chunks: T[][] = [];
12+
for (let i = 0; i < array.length; i += chunkSize) {
13+
chunks.push(array.slice(i, i + chunkSize));
14+
}
15+
return chunks;
16+
};
17+
18+
// 处理单个脚本的favicon
19+
const processScriptFavicon = async (script: Script) => {
20+
return {
21+
uuid: script.uuid,
22+
fav: await Cache.getInstance().getOrSet(`favicon:${script.uuid}`, async () => {
23+
const icons = await extractFavicons(script.metadata!.match || [], script.metadata!.include || []);
24+
if (icons.length === 0) return [];
25+
26+
// 从缓存中获取favicon图标
27+
const systemClient = new SystemClient(message);
28+
const newIcons = await Promise.all(
29+
icons.map((icon) => {
30+
// 没有的话缓存到本地使用URL.createObjectURL
31+
if (!icon.icon) {
32+
return Promise.resolve({
33+
match: icon.match,
34+
website: icon.website,
35+
icon: "",
36+
});
37+
}
38+
// 因为需要持久化URL.createObjectURL,所以需要通过调用到offscreen来创建
39+
return systemClient
40+
.loadFavicon(icon.icon)
41+
.then((url) => ({
42+
match: icon.match,
43+
website: icon.website,
44+
icon: url,
45+
}))
46+
.catch(() => ({
47+
match: icon.match,
48+
website: icon.website,
49+
icon: "",
50+
}));
51+
})
52+
);
53+
return newIcons;
54+
}),
55+
};
56+
};
57+
58+
// 在scriptSlice创建后处理favicon加载,以批次方式处理
1059
export const loadScriptFavicons = async (scripts: Script[]) => {
11-
const icons = await Promise.all(
12-
scripts.map((item) => {
13-
return Cache.getInstance().getOrSet(`favicon:${item.uuid}`, async () => {
14-
const icons = await extractFavicons(item.metadata!.match || [], item.metadata!.include || []);
15-
if (icons.length > 0) {
16-
// 从缓存中获取favicon图标
17-
const systemClient = new SystemClient(message);
18-
const newIcons = await Promise.all(
19-
icons.map((icon) => {
20-
// 没有的话缓存到本地使用URL.createObjectURL
21-
if (!icon.icon) {
22-
return Promise.resolve({
23-
match: icon.match,
24-
website: icon.website,
25-
icon: "",
26-
});
27-
}
28-
// 因为需要持久化URL.createObjectURL,所以需要通过调用到offscreen来创建
29-
return systemClient
30-
.loadFavicon(icon.icon)
31-
.then((url) => {
32-
return {
33-
match: icon.match,
34-
website: icon.website,
35-
icon: url,
36-
};
37-
})
38-
.catch(() => {
39-
return {
40-
match: icon.match,
41-
website: icon.website,
42-
icon: "",
43-
};
44-
});
45-
})
46-
);
47-
return newIcons;
48-
}
49-
return Promise.resolve([]);
50-
});
51-
})
52-
);
53-
store.dispatch(
54-
scriptSlice.actions.setScriptFavicon(
55-
icons.map((item, index) => ({
56-
uuid: scripts[index].uuid,
57-
fav: item,
58-
}))
59-
)
60-
);
60+
const batchSize = 20; // 每批处理20个脚本
61+
const scriptChunks = chunkArray(scripts, batchSize);
62+
const results = [];
63+
64+
// 逐批处理脚本
65+
for (const chunk of scriptChunks) {
66+
const chunkResults = await Promise.all(chunk.map(processScriptFavicon));
67+
68+
// 每完成一批就更新一次store
69+
store.dispatch(scriptSlice.actions.setScriptFavicon(chunkResults));
70+
71+
results.push(...chunkResults);
72+
}
73+
74+
// 最后再做一次完整更新,确保所有数据都已更新
75+
store.dispatch(scriptSlice.actions.setScriptFavicon(results));
6176
};

0 commit comments

Comments
 (0)