ベスト プラクティス

このドキュメントでは、スクリプトのパフォーマンスを向上させるためのベスト プラクティスについて説明します。

他のサービスへの呼び出しを最小限に抑える

スクリプト内で 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 を多用するスクリプトでライブラリを使用しない

ライブラリはコードの再利用に便利ですが、スクリプトの起動時間が長くなります。この遅延は、短い google.script.run 呼び出しを繰り返すクライアントサイドの HTML サービスのユーザー インターフェースで顕著になります。アドオンではライブラリの使用を控え、多くの google.script.run 呼び出しを行うスクリプトではライブラリの使用を避けてください。

キャッシュ サービスを使用する

キャッシュ サービスを使用して、スクリプトの実行間でリソースをキャッシュに保存します。キャッシュ保存により、データ取得の頻度が減少します。次の例は、キャッシュ サービスを使用して、遅い 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: 大規模なデータセットでは、これらの関数の処理が遅くなることがあります。INDEXMATCH または Apps Script を使用して、メモリ内でより効率的にルックアップを行うことを検討してください。
  • IMPORTRANGE: 多くのシートで IMPORTRANGE を頻繁に使用すると、ソースシートが大きい場合や負荷が高い場合に「内部エラー」が発生することがあります。データを一元的なソースに統合すると、この問題を解決できます。

スクリプトのタイムアウト処理

Apps Script には実行時間の上限があります(通常は 1 回の実行につき 6 分、一部の Google Workspace アカウントでは 30 分)。スクリプトが実行制限を超えて頻繁にクラッシュする場合:

  1. バッチ オペレーションを使用する: バッチ オペレーションを使用するセクションで説明したように、スプレッドシートやその他のサービスへの呼び出しを最小限に抑えます。
  2. タスクを分割する: 大きなタスクを、それぞれが制限時間内に完了できる小さなチャンクに分割します。
  3. 継続にトリガーを使用する: 実行時間の長いプロセスを再開するために、インストール可能な時間主導型トリガーを設定します。スクリプトでは、プロパティ サービスを使用して現在の状態(最後に処理された行のインデックスなど)を保存し、次の実行でその時点から続行できます。