最佳实践

本文档列出了有助于您提升脚本性能的最佳实践。

尽量减少对其他服务的调用

在脚本中使用 JavaScript 操作比调用其他服务快得多。在 Google Apps 脚本本身中可以完成的任何操作都比需要从 Google 服务器或外部服务器(例如 Google 表格、Google 文档、Google 协作平台、Google 翻译、UrlFetch 等)提取数据的调用快得多。如果您能找到方法来最大限度地减少脚本对这些服务的调用,脚本的运行速度就会更快。

考虑使用共享云端硬盘进行协作

如果您正与其他开发者一起处理脚本项目,可以通过共享云端硬盘协作处理 Apps 脚本项目。 共享云端硬盘中的文件归群组(而非个人)所有。这有助于更轻松地开发和维护项目。

使用批量操作

脚本通常需要从电子表格中读取数据、执行计算,然后将数据结果写入电子表格。Google Apps 脚本已经具有一些内置优化功能,例如使用预读缓存来检索脚本可能获取的内容,以及使用写入缓存来保存可能设置的内容。

您可以编写脚本,通过尽可能减少读取和写入次数来充分利用内置缓存。交替读取和写入命令的速度较慢。为了加快脚本运行速度,您可以使用一个命令将所有数据读入数组,对数组中的数据执行任何操作,然后使用一个命令将数据写出。

以下是一个示例,但您不应遵循或使用此示例。某脚本使用以下代码来设置 100x100 的电子表格网格中每个单元格的背景颜色。它使用名为 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 脚本回写缓存很有帮助,因为它会在每行末尾使用 flush 强制执行回写。由于存在缓存,因此对电子表格的调用只有 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 秒即可运行完毕!

避免在界面繁重的脚本中使用库

是一种重用代码的便捷方式,但会略微增加启动脚本所需的时间。对于运行时间相对较长的脚本(例如用于清理 Google 云端硬盘文件的实用脚本),这种延迟并不明显,但对于反复进行短时间运行的 google.script.run 调用的客户端 HTML 服务界面,这种延迟会影响每次调用。由于存在此问题,因此应谨慎使用插件中的库,并且您可能需要在进行大量 google.script.run 调用的非插件脚本中避免使用库。

使用 Cache 服务

您可以使用缓存服务在脚本执行之间缓存资源。通过缓存数据,您可以减少获取数据的次数或频率。假设您在 example.com 上有一个 RSS Feed,需要 20 秒才能提取,并且您希望加快平均请求的访问速度。以下示例展示了如何使用 Cache Service 来加快对这些数据的访问速度。

  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 分钟后从缓存中过期。