Best practice

Questa pagina illustra diverse best practice per lo sviluppo con gli script Google Ads.

Selettori

Filtra con selettori

Se possibile, utilizza i filtri per richiedere solo le entità di cui hai bisogno. L'applicazione di filtri appropriati presenta i seguenti vantaggi:

  • Il codice è più semplice e facile da comprendere.
  • Lo script verrà eseguito molto più rapidamente.

Confronta i seguenti snippet di codice:

Approccio alla programmazione Snippet di codice
Filtrare i dati utilizzando i selettori (opzione consigliata)
var keywords = AdsApp.keywords()
    .withCondition('Clicks > 10')
    .forDateRange('LAST_MONTH')
    .get();
while (keywords.hasNext()) {
  var keyword = keywords.next();
  // Do work here.
}
Filtro nel codice (non consigliato)
var keywords = AdsApp.keywords().get();

while (keywords.hasNext()) {
  var keyword = keywords.next();
  var stats = keyword.getStatsFor(
      'LAST_MONTH');
  if (stats.getClicks() > 10) {
    // Do work here.
  }
}

Il secondo approccio non è consigliato perché tenta di recuperare l'elenco di tutte le parole chiave del tuo account solo per applicare un filtro all'elenco.

Evita di attraversare la gerarchia della campagna

Quando vuoi recuperare entità a un determinato livello, utilizza un metodo di raccolta a quel livello anziché attraversare l'intera gerarchia della campagna. Oltre a essere più semplice, questa soluzione avrà un rendimento molto migliore: il sistema non dovrà consultare inutilmente tutte le campagne e tutti i gruppi di annunci.

Confronta i seguenti snippet di codice che recuperano tutti gli annunci nel tuo account:

Approccio alla programmazione Snippet di codice
Utilizzare il metodo di raccolta appropriato (consigliato)

var ads = AdsApp.ads();

Attraversa la gerarchia (opzione sconsigliata)
var campaigns = AdsApp.campaigns().get();
while (campaigns.hasNext()) {
  var adGroups = campaigns.next().
      adGroups().get();
  while (adGroups.hasNext()) {
    var ads = adGroups.next().ads().get();
    // Do your work here.
  }
}

Il secondo approccio non è consigliato perché tenta di recuperare intere gerarchie di oggetti (campagne, gruppi di annunci), mentre sono necessari solo gli annunci.

Utilizzare metodi specifici della funzione di accesso padre

A volte è necessario ottenere l'entità principale di un oggetto recuperato. In questo caso, devi utilizzare un metodo di accesso fornito anziché recuperare intere gerarchie.

Confronta i seguenti snippet di codice che recuperano i gruppi di annunci con annunci di testo con più di 50 clic il mese scorso:

Approccio alla programmazione Snippet di codice
Utilizzare il metodo di accesso al genitore appropriato (consigliato)
var ads = AdsApp.ads()
    .withCondition('Clicks > 50')
    .forDateRange('LAST_MONTH')
    .get();

while (ads.hasNext()) {
  var ad = ads.next();
  var adGroup = ad.getAdGroup();
  var campaign = ad.getCampaign();
  // Store (campaign, adGroup) to an array.
}
Eseguire la scansione della gerarchia (opzione non consigliata)
var campaigns = AdsApp.campaigns().get();
while (campaigns.hasNext()) {
  var adGroups = campaigns.next()
      .adGroups()
      .get();
  while (adGroups.hasNext()) {
    var ads = adGroups.ads()
       .withCondition('Clicks > 50')
       .forDateRange('LAST_MONTH')
       .get();
    if (ads.totalNumEntities() > 0) {
      // Store (campaign, adGroup) to an array.
    }
  }
}

Il secondo approccio non è consigliato perché recupera l'intera gerarchia delle campagne e dei gruppi di annunci nel tuo account, mentre ti serve solo un sottoinsieme di campagne e gruppi di annunci associati al tuo insieme di annunci. Il primo approccio si limita a recuperare solo la raccolta di annunci pertinente e utilizza un metodo appropriato per accedere agli oggetti principali.

Utilizzare filtri principali specifici

Per accedere alle entità all'interno di una campagna o di un gruppo di annunci specifico, utilizza un filtro specifico nel selettore anziché recuperare e poi attraversare una gerarchia.

Confronta i seguenti snippet di codice che recuperano l'elenco degli annunci di testo all'interno di una campagna e di un gruppo di annunci specificati con più di 50 clic nell'ultimo mese.

Approccio alla programmazione Snippet di codice
Utilizzare i filtri a livello di entità principale appropriati (opzione consigliata)
var ads = AdsApp.ads()
    .withCondition('CampaignName = "Campaign 1"')
    .withCondition('AdGroupName = "AdGroup 1"')
    .withCondition('Clicks > 50')
    .forDateRange('LAST_MONTH')
    .get();

while (ads.hasNext()) {
  var ad = ads.next();
  var adGroup = ad.getAdGroup();
  var campaign = ad.getCampaign();
  // Store (campaign, adGroup, ad) to
  // an array.
}
Eseguire la scansione della gerarchia (opzione non consigliata)
var campaigns = AdsApp.campaigns()
    .withCondition('Name = "Campaign 1"')
    .get();

while (campaigns.hasNext()) {
  var adGroups = campaigns.next()
      .adGroups()
      .withCondition('Name = "AdGroup 1"')
      .get();
  while (adGroups.hasNext()) {
    var ads = adGroups.ads()
       .withCondition('Clicks > 50')
       .forDateRange('LAST_MONTH')
       .get();
    while (ads.hasNext()) {
      var ad = ads.next();
      // Store (campaign, adGroup, ad) to
      // an array.
    }
  }
}

Il secondo approccio non è consigliato perché esegue l'iterazione sulla gerarchia delle campagne e dei gruppi di annunci nel tuo account, mentre ti serve solo un insieme selezionato di annunci e le relative campagne e gruppi di annunci principali. Il primo approccio limita l'estrazione all'elenco di annunci applicando un filtro specifico per le entità principali sul selettore.

Se possibile, utilizza gli ID per l'applicazione di filtri

Quando filtri per entità, è preferibile filtrare per ID anziché per altri campi.

Considera i seguenti snippet di codice che selezionano una campagna.

Approccio alla programmazione Snippet di codice
Filtro per ID (consigliato)
var campaign = AdsApp.campaigns()
    .withIds([12345])
    .get()
    .next();
Filtra per nome (meno ottimale)
var campaign = AdsApp.campaigns()
    .withCondition('Name="foo"')
    .get()
    .next();

Il secondo approccio è meno ottimale perché filtriamo in base a un campo diverso dall'ID.

Filtra per ID genitori, se possibile

Quando selezioni un'entità, filtra per ID principali, se possibile. In questo modo, le query verranno eseguite più rapidamente perché l'elenco delle entità recuperate dai server viene limitato durante il filtro dei risultati.

Considera il seguente snippet di codice che recupera un gruppo di annunci tramite il relativo ID. Supponiamo che l'ID campagna principale sia noto.

Approccio alla programmazione Snippet di codice
Filtrare in base agli ID campagna e gruppo di annunci (opzione consigliata)
var adGroup = AdsApp.adGroups()
    .withIds([12345])
    .withCondition('CampaignId="54678"')
    .get()
    .next();
Filtra solo per ID gruppo di annunci (meno ottimale)
var adGroup = AdsApp.adGroups()
    .withIds([12345])
    .get()
    .next();

Anche se entrambi gli snippet di codice forniscono risultati identici, il filtro aggiuntivo nello snippet di codice 1 che utilizza un ID (CampaignId="54678") principale rende il codice più efficiente limitando l'elenco di entità che il server deve eseguire per l'iterazione durante il filtro dei risultati.

Utilizzare le etichette quando sono presenti troppe condizioni di filtro

Quando hai troppe condizioni di filtro, è buona norma creare un'etichetta per le entità che elabori e utilizzarla per filtrarle.

Considera il seguente snippet di codice che recupera un elenco di campagne per nome.

Approccio alla programmazione Snippet di codice
Utilizzare un'etichetta (opzione consigliata)
var label = AdsApp.labels()
    .withCondition('Name = "My Label"')
    .get()
    .next();
var campaigns = label.campaigns.get();
while (campaigns.hasNext()) {
  var campaign = campaigns.next();
  // Do more work
}
Creare selettori complessi (opzione non consigliata)
var campaignNames = [‘foo’, ‘bar’, ‘baz’];

for (var i = 0; i < campaignNames.length; i++) {
  campaignNames[i] = '"' + campaignNames[i] + '"';
}

var campaigns = AdsApp.campaigns
    .withCondition('CampaignName in [' + campaignNames.join(',') + ']')
    .get();

while (campaigns.hasNext()) {
  var campaign = campaigns.next();
  // Do more work.
}

Sebbene entrambi gli snippet di codice offrano un livello di prestazioni simile, il secondo approccio tende a generare codice più complesso con l'aumento del numero di condizioni nel selettore. Inoltre, è più semplice applicare l'etichetta a una nuova entità che modificare lo script per includere una nuova entità.

Limita il numero di condizioni nella clausola IN

Quando esegui gli script, un caso d'uso comune è eseguire un report per un elenco di entità. In genere, gli sviluppatori ottengono questo risultato creando una query AWQL molto lunga che filtra in base agli ID entità utilizzando una clausola IN. Questo approccio funziona correttamente quando il numero di entità è limitato. Tuttavia, con l'aumento della lunghezza della query, il rendimento dello script peggiora per due motivi:

  • L'analisi di una query più lunga richiede più tempo.
  • Ogni ID aggiunto a una clausola IN è una condizione aggiuntiva da valutare, pertanto richiede più tempo.

In queste condizioni, è preferibile applicare un'etichetta alle entità e poi filtrare in base a LabelId.

Approccio alla programmazione Snippet di codice
Applicare un'etichetta e filtrare per labelID (opzione consigliata)
// The label applied to the entity is "Report Entities"
var label = AdsApp.labels()
    .withCondition('LabelName contains "Report Entities"')
    .get()
    .next();

var report = AdsApp.report('SELECT AdGroupId, Id, Clicks, ' +
    'Impressions, Cost FROM KEYWORDS_PERFORMANCE_REPORT ' +
    'WHERE LabelId = "' + label.getId() + '"');
Creare una query lunga utilizzando la clausola IN (opzione non consigliata)
var report = AdsApp.report('SELECT AdGroupId, Id, Clicks, ' +
    'Impressions, Cost FROM KEYWORDS_PERFORMANCE_REPORT WHERE ' +
    'AdGroupId IN (123, 456) and Id in (123,345, 456…)');

Aggiornamenti sull'account

Modifiche collettive

Quando apporti modifiche a un'entità Google Ads, gli script Google Ads non eseguono immediatamente la modifica. Cerca invece di combinare più modifiche in batch, in modo da poter emettere una singola richiesta che apporti più modifiche. Questo approccio rende gli script più veloci e riduce il carico sui server di Google Ads. Tuttavia, esistono alcuni pattern di codice che forzano gli script Google Ads a eliminare frequentemente il batch di operazioni, causando così un'esecuzione lenta dello script.

Considera lo script seguente che aggiorna le offerte di un elenco di parole chiave.

Approccio alla programmazione Snippet di codice
Monitorare gli elementi aggiornati (opzione consigliata)
var keywords = AdsApp.keywords()
    .withCondition('Clicks > 50')
    .withCondition('CampaignName = "Campaign 1"')
    .withCondition('AdGroupName = "AdGroup 1"')
    .forDateRange('LAST_MONTH')
    .get();

var list = [];
while (keywords.hasNext()) {
  var keyword = keywords.next();
  keyword.bidding().setCpc(1.5);
  list.push(keyword);
}

for (var i = 0; i < list.length; i++) {
  var keyword = list[i];
  Logger.log('%s, %s', keyword.getText(),
      keyword.bidding().getCpc());
}
Recupero degli elementi aggiornati in un ciclo stretto (opzione non consigliata)
var keywords = AdsApp.keywords()
    .withCondition('Clicks > 50')
    .withCondition('CampaignName = "Campaign 1"')
    .withCondition('AdGroupName = "AdGroup 1"')
    .forDateRange('LAST_MONTH')
    .get();

while (keywords.hasNext()) {
  var keyword = keywords.next();
  keyword.bidding().setCpc(1.5);
  Logger.log('%s, %s', keyword.getText(),
      keyword.bidding().getCpc());
}

Il secondo approccio non è consigliato poiché la chiamata a keyword.bidding().getCpc() forza gli script Google Ads a svuotare l'operazione setCpc() e a eseguire una sola operazione alla volta. Il primo approccio, sebbene simile al secondo, ha il vantaggio aggiuntivo di supportare il raggruppamento poiché la chiamata getCpc() viene eseguita in un loop separato da quello in cui viene chiamata setCpc().

Utilizza i generatori quando possibile

Gli script Google Ads supportano due modi per creare nuovi oggetti: i generatori e i metodi di creazione. I builder sono più flessibili dei metodi di creazione, poiché ti consentono di accedere all'oggetto creato dalla chiamata API.

Considera i seguenti snippet di codice:

Approccio alla programmazione Snippet di codice
Utilizzare i generatori (opzione consigliata)
var operation = adGroup.newKeywordBuilder()
    .withText('shoes')
    .build();
var keyword = operation.getResult();
Utilizzare i metodi di creazione (non consigliato)
adGroup.createKeyword('shoes');
var keyword = adGroup.keywords()
    .withCondition('KeywordText="shoes"')
    .get()
    .next();

Il secondo approccio non è preferito a causa dell'operazione di selezione aggiuntiva necessaria per recuperare la parola chiave. Inoltre, anche i metodi di creazione sono ritirati.

Tuttavia, tieni presente che i generatori, se utilizzati in modo errato, possono impedire agli script Google Ads di raggruppare le operazioni.

Considera i seguenti snippet di codice che creano un elenco di parole chiave e stampano l'ID delle parole chiave appena create:

Approccio alla programmazione Snippet di codice
Monitorare gli elementi aggiornati (opzione consigliata)
var keywords = [‘foo’, ‘bar’, ‘baz’];

var list = [];
for (var i = 0; i < keywords.length; i++) {
  var operation = adGroup.newKeywordBuilder()
      .withText(keywords[i])
      .build();
  list.push(operation);
}

for (var i = 0; i < list.length; i++) {
  var operation = list[i];
  var result = operation.getResult();
  Logger.log('%s %s', result.getId(),
      result.getText());
}
Recuperare gli elementi aggiornati in un loop stretto (sconsigliato)
var keywords = [‘foo’, ‘bar’, ‘baz’];

for (var i = 0; i < keywords.length; i++) {
  var operation = adGroup.newKeywordBuilder()
      .withText(keywords[i])
      .build();
  var result = operation.getResult();
  Logger.log('%s %s', result.getId(),
      result.getText());
}

Il secondo approccio non è preferito perché chiama operation.getResult() all'interno dello stesso ciclo che crea l'operazione, forzando così gli script Google Ads a eseguire un'operazione alla volta. Il primo approccio, pur essendo simile, consente il batching poiché chiamiamo operation.getResult() in un ciclo diverso da quello in cui è stato creato.

Valuta la possibilità di utilizzare i caricamenti collettivi per gli aggiornamenti di grandi dimensioni

Un'attività comune svolta dagli sviluppatori è eseguire report e aggiornare le proprietà delle entità (ad es. le offerte per parole chiave) in base ai valori di rendimento correnti. Quando devi aggiornare un numero elevato di entità, i caricamenti collettivi tendono a offrire un rendimento migliore. Ad esempio, considera i seguenti script che aumentano il valore MaxCpc delle parole chiave il cui TopImpressionPercentage > 0.4 per l'ultimo mese è:

Approccio alla programmazione Snippet di codice
Utilizzare il caricamento collettivo (opzione consigliata)

var report = AdsApp.report(
  'SELECT AdGroupId, Id, CpcBid FROM KEYWORDS_PERFORMANCE_REPORT ' +
  'WHERE TopImpressionPercentage > 0.4 DURING LAST_MONTH');

var upload = AdsApp.bulkUploads().newCsvUpload([
  report.getColumnHeader('AdGroupId').getBulkUploadColumnName(),
  report.getColumnHeader('Id').getBulkUploadColumnName(),
  report.getColumnHeader('CpcBid').getBulkUploadColumnName()]);
upload.forCampaignManagement();

var reportRows = report.rows();
while (reportRows.hasNext()) {
  var row = reportRows.next();
  row['CpcBid'] = row['CpcBid'] + 0.02;
  upload.append(row.formatForUpload());
}

upload.apply();
Selezionare e aggiornare le parole chiave per ID (meno ottimale)
var reportRows = AdsApp.report('SELECT AdGroupId, Id, CpcBid FROM ' +
    'KEYWORDS_PERFORMANCE_REPORT WHERE TopImpressionPercentage > 0.4 ' +
    ' DURING LAST_MONTH')
    .rows();

var map = {
};

while (reportRows.hasNext()) {
  var row = reportRows.next();
  var adGroupId = row['AdGroupId'];
  var id = row['Id'];

  if (map[adGroupId] == null) {
    map[adGroupId] = [];
  }
  map[adGroupId].push([adGroupId, id]);
}

for (var key in map) {
  var keywords = AdsApp.keywords()
      .withCondition('AdGroupId="' + key + '"')
      .withIds(map[key])
      .get();

  while (keywords.hasNext()) {
    var keyword = keywords.next();
    keyword.bidding().setCpc(keyword.bidding().getCpc() + 0.02);
  }
}

Sebbene il secondo approccio offra prestazioni abbastanza buone, in questo caso è preferibile il primo approccio poiché

  • Gli script Google Ads hanno un limite al numero di oggetti che possono essere recuperati o aggiornati in una singola esecuzione e le operazioni di selezione e aggiornamento nel secondo approccio vengono conteggiate ai fini di questo limite.

  • I caricamenti collettivi hanno limiti più elevati sia in termini di numero di entità che possono essere aggiornate sia in termini di tempo di esecuzione complessivo.

Raggruppare i caricamenti collettivi per campagna

Quando crei i caricamenti collettivi, prova a raggruppare le operazioni per campagna principale. In questo modo aumenti l'efficienza e riduci le probabilità di modifiche/errori di concorrenza in conflitto.

Considera due attività di caricamento collettivo in esecuzione in parallelo. Uno mette in pausa gli annunci in un gruppo di annunci, l'altro regola le offerte per parola chiave. Anche se le operazioni non sono correlate, possono essere applicate a entità nello stesso gruppo di annunci (o a due gruppi di annunci diversi nella stessa campagna). In questi casi, il sistema blocca l'entità principale (la campagna o il gruppo di annunci condiviso), causando il blocco delle attività di caricamento collettivo tra loro.

Gli script Google Ads possono ottimizzare l'esecuzione all'interno di una singola attività di caricamento collettivo, quindi la cosa più semplice da fare è eseguire una sola attività di caricamento collettivo per account alla volta. Se decidi di eseguire più di un caricamento collettivo per account, assicurati che i caricamenti collettivi funzionino su un elenco di campagne mutuamente esclusive (e delle relative entità secondarie) per un rendimento ottimale.

Rapporti

Utilizza i report per il recupero delle statistiche

Per recuperare un numero elevato di entità e le relative statistiche, spesso è preferibile utilizzare i report anziché i metodi standard di AdsApp. L'utilizzo dei report è preferibile per i seguenti motivi:

  • I report offrono prestazioni migliori per query di grandi dimensioni.
  • I report non raggiungeranno le normali quote di recupero.

Confronta i seguenti snippet di codice che recuperano i clic, le impressioni, il costo e il testo di tutte le parole chiave che hanno ricevuto più di 50 clic il mese scorso:

Approccio alla programmazione Snippet di codice
Utilizzare i report (opzione consigliata)
  report = AdsApp.search(
      'SELECT ' +
      '   ad_group_criterion.keyword.text, ' +
      '   metrics.clicks, ' +
      '   metrics.cost_micros, ' +
      '   metrics.impressions ' +
      'FROM ' +
      '   keyword_view ' +
      'WHERE ' +
      '   segments.date DURING LAST_MONTH ' +
      '   AND metrics.clicks > 50');
  while (report.hasNext()) {
    var row = report.next();
    Logger.log('Keyword: %s Impressions: %s ' +
        'Clicks: %s Cost: %s',
        row.adGroupCriterion.keyword.text,
        row.metrics.impressions,
        row.metrics.clicks,
        row.metrics.cost);
  }
Utilizzare gli iteratori AdsApp (non consigliato)
var keywords = AdsApp.keywords()
    .withCondition('metrics.clicks > 50')
    .forDateRange('LAST_MONTH')
    .get();
while (keywords.hasNext()) {
  var keyword = keywords.next();
  var stats = keyword.getStatsFor('LAST_MONTH');
  Logger.log('Keyword: %s Impressions: %s ' +
      'Clicks: %s Cost: %s',
      keyword.getText(),
      stats.getImpressions(),
      stats.getClicks(),
      stats.getCost());
}

Il secondo approccio non è preferito perché esegue l'iterazione sulle parole chiave e recupera le statistiche una entità alla volta. In questo caso, i report hanno un rendimento migliore poiché recuperano tutti i dati in una singola chiamata e li trasmettono in streaming in base alle esigenze. Inoltre, le parole chiave recuperate nel secondo approccio vengono conteggiate ai fini della quota dello script per il numero di entità recuperate utilizzando una chiamata get().

Utilizza la ricerca al posto del report

Il metodo report è stato creato per la vecchia infrastruttura e restituisce i risultati in un formato piatto anche se utilizzi GAQL. Ciò significa che deve trasformare i risultati della query in modo che corrispondano al vecchio stile, che non è supportato per tutti i campi e aggiunge un overhead a ogni chiamata.

Ti consigliamo di utilizzare la ricerca per sfruttare tutte le funzionalità dei nuovi report dell'API Google Ads.

Preferire GAQL ad AWQL

Sebbene AWQL sia ancora supportato nelle query dei report e nelle chiamate withCondition, viene eseguito tramite un livello di traduzione che non è completamente compatibile con il vero AWQL. Per avere il controllo completo sulle query, assicurati di utilizzare GAQL.

Se hai query AWQL esistenti che vuoi tradurre, abbiamo uno strumento di migrazione delle query che può aiutarti.

Non selezionare più righe del necessario

La velocità di esecuzione dei report (e dei selettori) si basa sul numero totale di righe che verrebbero restituite dal report, indipendentemente dal fatto che vengano o meno eseguite. Ciò significa che devi sempre utilizzare filtri specifici per ridurre al minimo il set di risultati in modo che corrisponda al tuo caso d'uso.

Ad esempio, supponiamo che tu voglia trovare gruppi di annunci con offerte al di fuori di un determinato intervallo. Sarebbe più rapido eseguire due query distinte, una per le offerte al di sotto della soglia minima e un'altra per le offerte al di sopra della soglia massima, rispetto a recuperare tutti i gruppi di annunci e ignorare quelli che non ti interessano.

Approccio alla programmazione Snippet di codice
Utilizzare due query (opzione consigliata)
var adGroups = []
var report = AdsApp.search(
    'SELECT ad_group.name, ad_group.cpc_bid_micros' +
    ' FROM ad_group WHERE ad_group.cpc_bid_micros < 1000000');

while (report.hasNext()) {
  var row = report.next();
  adGroups.push(row.adGroup);
}
var report = AdsApp.search(
    'SELECT ad_group.name, ad_group.cpc_bid_micros' +
    ' FROM ad_group WHERE ad_group.cpc_bid_micros > 2000000');

while (report.hasNext()) {
  var row = report.next();
  adGroups.push(row.adGroup);
}
Applicare un filtro da una query generica (opzione non consigliata)
var adGroups = []
var report = AdsApp.search(
    'SELECT ad_group.name, ad_group.cpc_bid_micros' +
    ' FROM ad_group');

while (report.hasNext()) {
  var row = report.next();
  var cpcBidMicros = row.adGroup.cpcBidMicros;
  if (cpcBidMicros < 1000000 || cpcBidMicros > 2000000) {
    adGroups.push(row.adGroup);
  }
}

Script di Ad Manager (Centro clienti)

Preferisci eseguireInParallel rispetto all'esecuzione seriale

Quando scrivi script per gli account amministratore, utilizza executeInParallel() anziché l'esecuzione seriale, se possibile. executeInParallel() concede allo script più tempo di elaborazione (fino a un'ora) e fino a 30 minuti per account elaborato (invece di 30 minuti combinati per l'esecuzione seriale). Consulta la pagina relativa ai limiti per maggiori dettagli.

Fogli di lavoro

Utilizzare le operazioni collettive durante l'aggiornamento dei fogli di lavoro

Quando aggiorni i fogli di lavoro, prova a utilizzare i metodi delle operazioni collettive (ad esempio getRange()) rispetto ai metodi che aggiornano una cella alla volta.

Considera il seguente snippet di codice che genera un pattern frattale in un foglio di lavoro.

Approccio alla programmazione Snippet di codice
Aggiornare un intervallo di celle in una singola chiamata (opzione consigliata)
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] = getColor_(xcoord, ycoord);
    xcoord += xincrement;
  }
  ycoord -= yincrement;
}
sheet.getRange(1, 1, 100, 100).setBackgroundColors(colors);
Aggiornare una cella alla volta (sconsigliato)
var cell = sheet.getRange('a1');
for (var y = 0; y < 100; y++) {
  xcoord = xmin;
  for (var x = 0; x < 100; x++) {
    var c = getColor_(xcoord, ycoord);
    cell.offset(y, x).setBackgroundColor(c);
    xcoord += xincrement;
  }
  ycoord -= yincrement;
  SpreadsheetApp.flush();
}

Anche se Fogli Google tenta di ottimizzare il secondo snippet di codice memorizzando nella cache i valori, il rendimento è comunque scarso rispetto al primo snippet, a causa del numero di chiamate API effettuate.