SPFx获取SharePoint Online列表附件速度过慢,求优化方案
你当前的代码在循环里逐个await获取每个列表项的附件,属于串行异步请求——每个附件请求都要等上一个完成才会发起,总耗时是所有单个请求时间的累加,这就是速度慢的核心原因。下面是两种针对性优化方案:
方案1:一次查询获取所有列表项及附件(最优)
直接在初始查询列表项时,通过expand关联附件信息,只需要1次请求就能拿到所有需要的数据,彻底消除多次请求的开销。
修改后的核心代码示例:
// 初始查询时直接展开附件关联 const items = await sp.web.lists.getByTitle(this.properties.listName) .items .select("ID", "AttachmentFiles") // 选择需要的字段,包含附件集合 .expand("AttachmentFiles") // 展开附件数据 .get(); // 遍历处理每个列表项的附件 items.forEach(item => { console.log('ID:' + item.ID); if (item.AttachmentFiles && item.AttachmentFiles.length > 0) { item.AttachmentFiles.forEach(file => { const fileUrl = file.ServerRelativeUrl; console.log('fileUrl:' + fileUrl); }); } });
优势:从原来的N+1次请求(1次列表查询+N次附件查询)减少到1次请求,性能提升最显著,完全解决单个附件耗时累加的问题。
方案2:并行发起所有附件请求(次优)
如果因为业务限制无法使用方案1,可以把所有获取附件的Promise收集起来,用Promise.all并行执行,让所有请求同时发起,总耗时接近单个请求的时间,而非累加。
修改后的核心代码示例:
// 假设r是初始查询返回的列表项数组 // 先收集所有获取附件的Promise对象 const attachmentPromises = r.map(item => { console.log('ID:' + item["ID"]); return sp.web.lists.getByTitle(this.properties.listName) .items.getById(Number(item["ID"])) .attachmentFiles(); }); // 并行执行所有附件请求 const allAttachmentInfos = await Promise.all(attachmentPromises); // 遍历处理所有附件结果 allAttachmentInfos.forEach((attachmentInfo, index) => { console.log('ID:' + r[index]["ID"] + ' 的附件:'); attachmentInfo.map(file => { const fileUrl = file.ServerRelativeUrl; console.log('fileUrl:' + fileUrl); }); });
优势:把串行请求改成并行,总耗时从N * 0.3s压缩到约0.3s,大幅提升获取效率。
内容的提问来源于stack exchange,提问作者Pete Whelan
相关产品推荐
相关产品推荐

