最佳实践

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

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

在脚本中使用 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 秒即可运行完毕。

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

便于重复使用代码,但 会增加脚本启动时间。在客户端 HTML 服务界面中,如果重复进行 短时运行的 google.script.run 调用,这种延迟会很明显。在 插件 中谨慎使用库,并避免在进行大量 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 服务存储其当前状态(例如,上次处理的行索引),并在下次执行时从该点继续。