最佳实践

本文档列出了可提升脚本性能的最佳实践。

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

在脚本中使用 JavaScript 操作比调用其他服务更快。在 Google Apps 脚本本身中完成的任何操作都比从 Google 服务器或外部服务器(例如对 Google 表格、Google 文档、Google 协作平台、Google 翻译和 UrlFetch 的请求)提取数据更快。如果您尽量减少服务调用,脚本的运行速度会更快。

通过共享云端硬盘展开协作

如果您与其他开发者一起处理脚本项目,请使用共享云端硬盘进行协作。 共享云端硬盘中的文件归群组(而非个人)所有,因此可以更轻松地进行项目开发和维护。

使用批量操作

脚本通常从电子表格中读取数据、执行计算,并将结果写回电子表格。Apps 脚本使用内置的优化功能,例如预读和写入缓存。

通过尽量减少读取和写入操作,最大限度地利用内置缓存。交替执行读取和写入命令的速度较慢。如需加快脚本运行速度,请使用一个命令将所有数据读入数组,对数组数据执行操作,然后使用一个命令将数据写出。

避免交替执行读取和写入操作,如以下低效示例所示:

// 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 秒即可运行完毕。

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

便于重复使用代码,但会增加脚本启动时间。在反复进行短时间运行的 google.script.run 调用的客户端 HTML 服务界面中,此延迟非常明显。在插件中谨慎使用库,并避免在进行多次 google.script.run 调用的脚本中使用库。

使用 Cache 服务

使用 Cache 服务可在脚本执行之间缓存资源。缓存可降低数据提取频率。 以下示例展示了如何使用 Cache 服务来加快对慢速 RSS Feed 的访问速度。

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:一个无服务器、扩容能力极强的数据仓库。您可以使用关联工作表直接在 Google 表格中分析大型 BigQuery 数据集,也可以使用 BigQuery 服务通过 Apps 脚本与数据进行互动。

公式性能优化

大量使用某些公式可能会降低电子表格的运行速度:

  • ARRAYFORMULA:虽然很有用,但大规模 ARRAYFORMULA 计算可能需要大量资源。
  • VLOOKUP 和 OFFSET:这些函数在大型数据集上运行速度可能会很慢。考虑使用 INDEXMATCH 或 Apps 脚本在内存中更高效地执行查找。
  • IMPORTRANGE:如果在多个工作表中频繁使用 IMPORTRANGE,当源工作表很大或处于繁重负载下时,可能会导致“内部错误”。将数据整合到集中式来源中会有所帮助。

脚本超时处理

Apps 脚本有执行时间限制(通常每次执行 6 分钟,对于某些 Google Workspace 账号,此时间限制为 30 分钟)。如果您的脚本因超出执行限制而频繁崩溃,请执行以下操作:

  1. 使用批量操作:如使用批量操作部分中所述,尽量减少对电子表格和其他服务的调用。
  2. 拆分任务:将大型任务拆分为较小的块,确保每个块都能在时间限制内完成。
  3. 使用续传触发器:设置可安装的定时触发器,以恢复长时间运行的进程。您的脚本可以使用 Properties 服务存储其当前状态(例如,上次处理的行索引),并在下次执行时从该点继续。