ベスト プラクティス

このドキュメントでは、スクリプトのパフォーマンス改善に役立つベスト プラクティスについて説明します。

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

スクリプト内で JavaScript オペレーションを使用すると、他のサービスを呼び出すよりもはるかに高速です。Google Apps Script 自体で実行できる処理は、Google のサーバーや外部サーバーからデータを取得する必要がある呼び出し(スプレッドシート、ドキュメント、サイト、翻訳、UrlFetch などに対するリクエスト)を実行するよりもはるかに高速です。スクリプトがそれらのサービスに対して行う呼び出しを最小限に抑える方法を見つければ、スクリプトの実行速度が向上します。

共有ドライブでのコラボレーションを検討する

他のデベロッパーとスクリプト プロジェクトで作業している場合は、共有ドライブを使用して Apps Script プロジェクトを共同編集できます。共有ドライブ内のファイルのオーナーは、個人ではなくグループです。これにより、プロジェクトの開発とメンテナンスが容易になります。

バッチ オペレーションを使用する

スクリプトは通常、スプレッドシートからデータを読み取って計算を行い、データの結果をスプレッドシートに書き出す必要があります。Google Apps Script にはあらかじめ最適化機能が組み込まれています。たとえば、先読みキャッシュを使用してスクリプトが取得できる可能性が高い内容を取得したり、キャッシュに書き込みを行って設定内容を保存したりできます。

読み取りと書き込みの回数を最小限に抑えることで、組み込みキャッシュを最大限に活用するためのスクリプトを作成できます。読み取りコマンドと書き込みコマンドを交互に繰り返すのは遅くなります。スクリプトを高速化するには、1 つのコマンドですべてのデータを配列に読み込み、配列内のデータに対して任意のオペレーションを実行して、1 つのコマンドでデータを書き出します。

以下に例を示しますが、これに従ったり、使用したりしてはいけない例です。次のコードを使用して、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).setBackgroundColors(colors);

非効率的なコードの実行には約 70 秒かかります。この効率的なコードは わずか 1 秒で実行できます

UI を多用するスクリプトでライブラリを回避する

ライブラリはコードの再利用には便利な方法ですが、スクリプトの開始にかかる時間が若干長くなります。この遅延は、比較的長時間実行されるスクリプト(Google ドライブのファイルをクリーンアップするユーティリティ スクリプトなど)ではそれほど顕著ではありませんが、google.script.run 呼び出しを短時間繰り返すクライアントサイドの HTML サービス ユーザー インターフェースでは、すべての呼び出しに影響します。この問題のため、アドオンでのライブラリの使用は慎重に行い、多数の 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 分でキャッシュから期限切れになります。