Google Apps Script操作Google Slides导入大量图片运行缓慢优化求助
我太懂你这种烦恼了——批量导入图片时脚本卡得要死,Google Apps Script里最耗时间的就是反复调用各种服务(比如Spreadsheet、Drive、Slides),咱们从几个核心方向优化你的代码,应该能大幅提速:
1. 把重复的服务调用“缓存”起来,别每次都重新打开表格
你看你的Getcellimage函数,每次都要重新openById打开地图表格,这就像每次用文件都要重新从硬盘里翻出来,太浪费时间了!咱们只在主函数里打开一次表格,然后把实例传给子函数用:
修改Getcellimage,让它接收表格实例和提前构建的坐标映射表作为参数:
function Getcellimage(mapspreadsheet, X, Y, coordMap) { try { // 用内存映射表快速查找坐标,替代耗时的TextFinder调用 const coordKey = `${X},${Y}`; const positioncellfinder = coordMap[coordKey]; if (!positioncellfinder) throw new Error("Coordinate not found"); const imgthingy = mapspreadsheet.getSheetByName('IMG') .getRange(positioncellfinder).getValue(); console.log(imgthingy); return imgthingy; } catch (error) { console.log(`cellimageerror: ${error}`); return "https://drive.google.com/file/d/1R9qlYwqWSlWhrDLVTJLaJQKet3Smt9R8/view?usp=sharing"; } }
然后在主函数里提前打开表格,并一次性加载坐标数据到内存映射表:
// 主函数里只打开一次地图表格 const mapspreadsheet = SpreadsheetApp.openById('1VMox84RztQX_A1FDLPAdqVsop_pTdxMtASiempOvfIw'); // 提前加载坐标数据,转成内存映射表(后续查找直接在内存中完成) const coordinatesSheet = mapspreadsheet.getSheetByName('coordinates'); const coordinatesData = coordinatesSheet.getDataRange().getValues(); const coordMap = {}; for (let row = 0; row < coordinatesData.length; row++) { for (let col = 0; col < coordinatesData[row].length; col++) { const coord = coordinatesData[row][col]; if (coord && typeof coord === 'string' && coord.includes(',')) { coordMap[coord] = coordinatesSheet.getRange(row+1, col+1).getA1Notation(); } } }
2. 跳过Drive文件调用,直接用图片URL插入
你现在每次插入图片都要先DriveApp.getFileById获取文件,其实Slides的insertImage支持直接用可访问的图片URL!咱们把Drive的分享URL转换成直接嵌入的URL,省掉Drive服务的调用:
修改GetIdFromUrl确保返回正确的文件ID,然后构造直接嵌入的URL:
function GetIdFromUrl(url) { const match = url.match(/[-\w]{25,}/); return match ? match[0] : null; }
然后修改Getandinsertimage,直接用URL插入图片:
function Getandinsertimage(slide, mapspreadsheet, PLAYERX, PLAYERY, X, Y, coordMap) { const imgUrl = Getcellimage(mapspreadsheet, PLAYERX + X, PLAYERY + Y, coordMap); const fileId = GetIdFromUrl(imgUrl); if (fileId) { // 构造直接可嵌入的图片URL(注意确保图片权限为公开可查看) const directImgUrl = `https://drive.google.com/uc?id=${fileId}`; // 根据偏移计算图片位置(替换成你的基础坐标和尺寸) const baseX = 200; const baseY = 200; const imgSize = 45; const posX = baseX + X * imgSize; const posY = baseY + Y * imgSize; slide.insertImage(directImgUrl, posX, posY, imgSize, imgSize); } }
3. 只获取一次Slides实例,避免重复调用
你现在在Getandinsertimage里每次都要getSlides()[0]获取幻灯片,主函数里提前获取一次传给子函数就行:
// 主函数里只获取一次目标幻灯片 const slide = Local.getSlides()[0]; // 调用GetMap时把slide和coordMap一起传进去 GetMap(slide, mapspreadsheet, PLAYERX, PLAYERY, coordMap);
然后修改GetMap接收参数:
function GetMap(slide, mapspreadsheet, PLAYERX, PLAYERY, coordMap) { Getandinsertimage(slide, mapspreadsheet, PLAYERX, PLAYERY, 1, 0, coordMap); Getandinsertimage(slide, mapspreadsheet, PLAYERX, PLAYERY, -1, 0, coordMap); Getandinsertimage(slide, mapspreadsheet, PLAYERX, PLAYERY, 0, 1, coordMap); // ... 其他所有Getandinsertimage调用都补充coordMap参数 }
4. 简化嵌套的条件判断,让代码更高效易读
你主函数里一堆嵌套的if-else看着头大,改成对象映射不仅代码清晰,运行效率也会高一点:
// 把动作逻辑做成映射表,替代嵌套判断 const actionHandlers = { up: () => { console.log("moving player up!"); PlayerData.getRange(`D${PlayerRow}`).setValue(positionY + 1); GetMap(slide, mapspreadsheet, positionX, positionY + 1, coordMap); }, down: () => { console.log("moving player down!"); PlayerData.getRange(`D${PlayerRow}`).setValue(positionY - 1); GetMap(slide, mapspreadsheet, positionX, positionY - 1, coordMap); }, left: () => { console.log("moving player left!"); PlayerData.getRange(`C${PlayerRow}`).setValue(positionX - 1); GetMap(slide, mapspreadsheet, positionX - 1, positionY, coordMap); }, right: () => { console.log("moving player right!"); PlayerData.getRange(`C${PlayerRow}`).setValue(positionX + 1); GetMap(slide, mapspreadsheet, positionX + 1, positionY, coordMap); }, // 其他动作(block/attack)可以继续添加在这里 }; // 调用对应的动作逻辑 if (actionHandlers[textboxvalue]) { actionHandlers[textboxvalue](); } else { console.log(`Unknown action: ${textboxvalue}`); }
核心优化思路总结
Google Apps Script的运行瓶颈几乎都在服务调用次数上——每次调用Spreadsheet、Drive、Slides服务都要和Google服务器通信,耗时很长。咱们做的这些优化都是尽量把重复的服务调用改成内存操作,减少和服务器的交互次数,这样脚本运行速度会提升一大截!
备注:内容来源于stack exchange,提问作者Jackson Steciuk

