このドキュメントでは、スクリプトのパフォーマンスを向上させるためのベスト プラクティスについて説明します。
他のサービスへの呼び出しを最小限に抑える
スクリプト内で JavaScript オペレーションを使用する方が、他のサービスを呼び出すよりも高速です。Google Apps Script 自体で実行する処理は、Google のサーバーや外部サーバーからデータを取得するよりも高速です。たとえば、スプレッドシート、ドキュメント、サイト、翻訳、UrlFetch へのリクエストなどです。サービス呼び出しを最小限に抑えると、スクリプトの実行速度が向上します。
共有ドライブで共同作業を行う
他のデベロッパーとスクリプト プロジェクトで作業する場合は、 共有ドライブを使用して共同作業を行います。 共有ドライブ内のファイルは、個人ではなくグループが所有するため、プロジェクトの開発と保守が容易になります。
バッチ オペレーションを使用する
スクリプトは通常、スプレッドシートからデータを読み取り、計算を実行して、結果を書き戻します。Apps Script では、先読みや書き込みキャッシュなどの組み込みの最適化が使用されます。
読み取りと書き込みを最小限に抑えることで、組み込みキャッシュを最大限に活用できます。読み取りコマンドと書き込みコマンドを交互に実行すると、処理が遅くなります。スクリプトを高速化するには、1 つのコマンドで配列にすべてのデータを読み込み、配列データに対してオペレーションを実行し、1 つのコマンドでデータを書き出します。
次の非効率的な例のように、読み取りと書き込みを交互に行うことは避けてください。
// 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();
}
このスクリプトは、連続した書き込みで 10,000 個のセルをループ処理するため、非効率的です。書き戻しキャッシュは役立ちますが、呼び出しをバッチ処理する方がはるかに効率的です。
// 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 を多用するスクリプトではライブラリを使用しない
ライブラリはコードの再利用に便利ですが、
スクリプトの起動時間が長くなります。この遅延は、
HTML Service 呼び出しを繰り返し行うクライアントサイドのユーザー インターフェースで顕著になります。google.script.runアドオンではライブラリを控えめに使用し、アドオン
呼び出しを多く行うスクリプトではライブラリを使用しないでください。google.script.run
Cache サービスを使用する
Cache サービスを使用して、スクリプトの実行間でリソースをキャッシュに保存します 。キャッシュに保存すると、データの取得頻度が減ります。 次の例は、Cache サービスを使用して、遅い RSS フィードへのアクセスを高速化する方法を示しています。
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 秒待つ必要がありますが、アイテムが期限切れになるまで、後続のアクセスは高速になります。
大規模なデータセットと複雑な計算
Google
スプレッドシートは強力なツールですが、データセットが大きくなり、計算が複雑になるにつれて、スプレッドシートの遅延、IMPORTRANGE
エラー、スクリプトのタイムアウトなどのパフォーマンスの問題が発生する可能性があります。
データベースを使用する場合
スプレッドシートが 1,000 万セルの上限に近づいている場合や、接続されたフォームが多く(10 個以上)、シート間の複雑な数式がある場合は、専用のデータベース ソリューションの使用を検討してください。
- Google Cloud SQL: MySQL、PostgreSQL、SQL Server 向けのフルマネージド リレーショナル データベース サービス。JDBC サービスを使用して、Cloud SQL や Oracle、MongoDB などの他の外部データベースに接続します(適切なブリッジを使用)。
- BigQuery: サーバーレスで高度にスケーラブルなデータ ウェアハウス。コネクテッド シートを使用して、スプレッドシートで直接 BigQuery の大規模なデータセットを分析できます。また、BigQuery サービスを使用して、Apps Script からデータとやり取りすることもできます。
数式のパフォーマンスの最適化
特定の数式を多用すると、スプレッドシートの処理速度が低下する可能性があります。
- ARRAYFORMULA: 便利ですが、大規模な
ARRAYFORMULA計算はコストがかかる可能性があります。 - VLOOKUP と OFFSET: これらの関数は、大規模なデータセットでは処理が遅くなる可能性があります。
INDEXとMATCHを使用するか、Apps Script を使用して、メモリ内でより効率的にルックアップを行うことを検討してください。 - IMPORTRANGE: 多くのシートで
IMPORTRANGEを頻繁に使用すると、ソースシートが大規模な場合や負荷が高い場合に「内部エラー」が発生する可能性があります。データを一元的なソースに統合すると、この問題を軽減できます。
スクリプトのタイムアウト処理
Apps Script には実行時間の制限があります(通常は 1 回の実行につき 6 分、一部の Google Workspace アカウントでは 30 分)。スクリプトが実行時間の上限を超えて頻繁にクラッシュする場合は、次のことを行います。
- バッチ オペレーションを使用する: バッチ オペレーションの使用セクションで説明したように、スプレッドシートや他のサービスへの呼び出しを最小限に抑えます。
- タスクを分割する: 大きなタスクを、それぞれが時間制限内に完了できる小さなチャンクに分割します。
- トリガーを使用して継続する: 実行時間の長いプロセスを再開するために、インストール可能な時間主導型トリガーを設定します。スクリプトは、Properties サービスを使用して現在の状態(最後に処理された行インデックスなど)を保存し、次の実行でその時点から続行できます。