本文列出可協助您改善指令碼效能的最佳做法。
盡量減少對其他服務的呼叫
在指令碼中使用 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 次對試算表的呼叫。
不過,透過批次呼叫,可以讓程式碼更有效率。以下是重新撰寫的程式碼,其中會將儲存格範圍讀入名為 colors 的陣列,並對陣列中的資料執行顏色指派作業,然後將陣列中的值寫入試算表:
// 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 雲端硬碟檔案的工具指令碼),這項延遲情形不會明顯,但對於會重複執行短時間 google.script.run
呼叫的用戶端 HTML Service 使用者介面,延遲情形會影響每個呼叫。因此,在外掛程式中,應盡量少用程式庫,並避免在執行大量 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 分鐘後從快取中過期為止。