简体   繁体   中英

Google Sheets Script Performance With Slow Custom Function

Setup: I have a Google sheet where I would like to run a custom function implemented using a script. This script is used to perform a relatively lengthy URL lookup and decode process (10 ms per call, dependent on bandwidth and ping). The custom function uses one column as input, and returns the result.

Problem: When my Google sheet is opened, the column that uses this calculation is refreshed. This grinds the Google sheet to a halt for about 10 seconds, until each cell in the column is recalculated. This will only become worse as I add to my spreadsheet.

Question: Can I change my function script, or change a setting in Google sheets so that the slow custom function is only calculated when the input cell is changed?

For anyone curious, here is a demo sheet with my problem

On my answer to In google sheets can I wrap a standard function in a custom function to control when it is run? I shared the idea of having a couple of buttons called "freeze" / "unfreeze" to control when the recalculation of "expensive formulas" is done.

On this case, you could "freeze" the range with your custom function before closing the spreadsheet so the next time that you open it will open faster, then when you need to update the frozen range you "unfreeze" it.

After posting the original version the OP asked for a simple version but as my original implementation was something quick and dirty with stuff in Spanish I shared there just the most important code lines. The core methods services are

  • A global variable to store the formula if it will always be the same
  • copyTo to overwrite the formula results range with the values a la copy-paste-values-only
  • clear to delete the formula results pasted previously
  • setFormula to add the formula back to the spreadsheet.

Then I realized that I could improved that published an unlisted Google Sheets add-on that use the PropertiesService to implement a "formula store" with functions to add/remove/list the formulas and a dynamic menu instead of buttons.

Something else to try is to use a time-driven trigger that runs, let say nightly just in case that you forgot to freeze the range for the custom function results.

Slightly better performance if there are less custom functions. You can rewrite your function to take in an array, so you'd only have one function instead of 100 running at once.

function mySlowFunction(x) {
  //Utilities.sleep(x*100); //100 ms
  if (x.map) {
    return x.map(function(y) {return mySlowFunction(y) });
  } else {
    return x * 100;
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM