本文件列出能協助您改善指令碼效能的最佳做法。
盡量減少對其他服務的呼叫
在指令碼中使用 JavaScript 作業,比呼叫其他服務快上許多。而可在 Google Apps Script 中完成的任何作業,其速度比呼叫需要從 Google 伺服器或外部伺服器擷取資料 (例如對試算表、文件、協作平台、翻譯、UrlFetch 等) 執行呼叫的速度更快。建議您設法減少指令碼對這些服務發出的呼叫,讓指令碼執行速度更快。
考慮使用共用雲端硬碟進行協作
如果您與其他開發人員合作開發指令碼專案,可以透過共用雲端硬碟協作 Apps Script 專案。共用雲端硬碟中的檔案是由群組共同擁有,並不屬於個別使用者。這樣一來,您就能更輕鬆地開發及維護專案。
使用批次作業
指令碼通常需要讀取試算表中的資料、執行計算,然後將資料結果寫入試算表。Google Apps Script 已提供一些內建最佳化功能,例如使用前瞻快取功能來擷取指令碼可能會取得的內容,以及使用寫入快取功能來儲存可能會設定的內容。
您可以編寫指令碼,藉由盡量減少讀取和寫入次數,充分利用內建快取功能。交替使用讀取和寫入指令會導致速度變慢。如要加快指令碼的速度,請使用單一指令將所有資料讀入陣列,對陣列中的資料執行任何作業,然後使用單一指令將資料寫出。
以下是您不應遵循或使用的示例。以下程式碼可用於設定 100 x 100 試算表格狀檢視畫面中每個儲存格的背景顏色。它會使用名為 getColorFromCoordinates()
的函式 (未顯示於此),判斷要為每個儲存格使用哪種顏色:
// DO NOT USE THIS CODE. It is an example of SLOW, INEFFICIENT code.
// FOR DEMONSTRATION ONLY
var cell = sheet.getRange('a1');
for (var y = 0; y < 100; y++) {
xcoord = xmin;
for (var x = 0; x < 100; x++) {
var c = getColorFromCoordinates(xcoord, ycoord);
cell.offset(y, x).setBackgroundColor(c);
xcoord += xincrement;
}
ycoord -= yincrement;
SpreadsheetApp.flush();
}
這個指令碼效率不佳:它會循環處理 100 列和 100 欄,並連續寫入 10,000 個儲存格。Google Apps Script 的回寫快取有助於解決這個問題,因為它會在每行結尾處使用刷新功能強制回寫。由於快取功能,只有 100 次對試算表的呼叫。
不過,只要將呼叫分批處理,就能讓程式碼更有效率。以下的改寫作業會將儲存格範圍讀入稱為顏色的陣列,並對陣列中的資料執行色彩指派作業,並將陣列中的值寫入試算表:
// OKAY TO USE THIS EXAMPLE or code based on it.
var cell = sheet.getRange('a1');
var colors = new Array(100);
for (var y = 0; y < 100; y++) {
xcoord = xmin;
colors[y] = new Array(100);
for (var x = 0; x < 100; x++) {
colors[y][x] = getColorFromCoordinates(xcoord, ycoord);
xcoord += xincrement;
}
ycoord -= yincrement;
}
sheet.getRange(1, 1, 100, 100).setBackgrounds(colors);
效率不佳的程式碼大約需要 70 秒才能執行。高效率程式碼在 1 秒內執行了!
避免在大量使用 UI 的指令碼中使用程式庫
程式庫是重複使用程式碼的簡便方式,但會稍微增加啟動指令碼的時間。在執行時間相對較長的指令碼 (例如清理 Google 雲端硬碟檔案的公用程式指令碼) 時,系統不會察覺這個延遲,但如果用戶端 HTML 服務使用者介面會重複執行短期的 google.script.run
呼叫,延遲時間就會影響每次呼叫。因此,請謹慎在外掛程式中使用程式庫,並可能避免在會發出大量 google.script.run
呼叫的非外掛程式指令碼中使用程式庫。
使用快取服務
您可以使用快取服務,在指令碼執行期間快取資源。透過快取資料,您可以減少擷取資料的次數或頻率。舉例來說,假設您在 example.com 上有個 RSS 動態消息,需要 20 秒才能擷取,而您想加快平均要求的存取速度。以下範例說明如何使用快取服務加快資料存取速度。
function getRssFeed() {
var cache = CacheService.getScriptCache();
var cached = cache.get("rss-feed-contents");
if (cached != null) {
return cached;
}
// This fetch takes 20 seconds:
var result = UrlFetchApp.fetch("http://example.com/my-slow-rss-feed.xml");
var contents = result.getContentText();
cache.put("rss-feed-contents", contents, 1500); // cache for 25 minutes
return contents;
}
雖然如果項目不在快取中,您仍必須等待 20 秒,但後續存取作業會非常快速,直到項目在 25 分鐘後從快取中過期為止。