Best practice

Questa pagina illustra varie 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 comprensibile.
  • Lo script verrà eseguito molto più velocemente.

Confronta i seguenti snippet di codice:

Approccio alla programmazione Snippet di codice
Filtrare 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.
}
Filtra in base al 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 nell'account solo per applicare un filtro all'elenco.

Evita di attraversare la gerarchia delle campagne

Quando vuoi recuperare le 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 funzione avrà anche un rendimento molto migliore: il sistema non dovrà leggere 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
Utilizza un metodo di raccolta appropriato (consigliato)

var ads = AdsApp.ads();

Attraversa la gerarchia (non consigliato)
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 richiesti solo gli annunci.

Utilizzare metodi di accesso principali specifici

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

Confronta i seguenti snippet di codice che recuperano i gruppi di annunci che contengono annunci di testo con più di 50 clic nell'ultimo mese:

Approccio alla programmazione Snippet di codice
Utilizzare il metodo della funzione di accesso principale 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.
}
Attraversa la gerarchia (non consigliato)
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 poiché recupera tutte le gerarchie di campagne e gruppi di annunci nel tuo account, mentre ti serve solo un sottoinsieme di campagne e gruppi di annunci associato al tuo insieme di annunci. Il primo approccio si limita a recuperare solo la raccolta di annunci pertinenti e utilizza un metodo appropriato per accedere agli oggetti principali.

Utilizza 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é recuperarlo e poi attraversare una gerarchia.

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

Approccio alla programmazione Snippet di codice
Utilizza filtri a livello 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.
}
Attraversa la gerarchia (non consigliato)
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 è sconsigliato perché esegue l'iterazione della gerarchia di campagne e gruppi di annunci nel tuo account, mentre ti serve solo un insieme selezionato di annunci e i relativi gruppi di annunci e campagne principali. Il primo approccio limita l'iterazione all'elenco di annunci applicando un filtro specifico per le entità padre sul selettore.

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

Quando filtri le entità, è preferibile filtrare in base alle entità in base ai loro ID anziché ad altri campi.

Per selezionare una campagna, prendi in considerazione i seguenti snippet di codice.

Approccio alla programmazione Snippet di codice
Filtra 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é applichiamo un filtro in base a un campo non ID.

Se possibile, filtra per ID parentale

Quando selezioni un'entità, filtra in base all'ID padre, se possibile. Ciò velocizza le query limitando l'elenco di entità recuperate dai server durante il filtraggio dei risultati.

Considera il seguente snippet di codice che recupera un gruppo di annunci in base al suo ID. Supponiamo che l'ID campagna principale sia noto.

Approccio alla programmazione Snippet di codice
Filtrare per ID campagna e gruppo di annunci (consigliato)
var adGroup = AdsApp.adGroups()
    .withIds([12345])
    .withCondition('CampaignId="54678"')
    .get()
    .next();
Filtrare per ID gruppo di annunci solo (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 con un ID principale (CampaignId="54678") rende il codice più efficiente limitando l'elenco di entità che il server deve iterare quando filtra i risultati.

Utilizza le etichette quando esistono troppe condizioni di filtro

Quando hai troppe condizioni di filtro, è consigliabile creare un'etichetta per le entità elaborate e utilizzarla per filtrare le entità.

Prendi in considerazione il seguente snippet di codice che recupera un elenco di campagne in base al 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 (non consigliato)
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 un codice più complesso man mano che aumenta il numero di condizioni nel selettore. Inoltre, risulta più facile applicare l'etichetta a una nuova entità che non 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 è l'esecuzione di un report per un elenco di entità. A questo scopo, gli sviluppatori di solito creano una query AWQL molto lunga che filtri gli ID entità con una clausola IN. Questo approccio funziona bene quando il numero di entità è limitato. Tuttavia, con l'aumento della lunghezza della query, le prestazioni dello script peggiorano per due motivi:

  • Una query più lunga richiede più tempo per l'analisi.
  • Ogni ID aggiunto a una clausola IN è una condizione aggiuntiva da valutare e, di conseguenza, richiede più tempo.

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

Approccio alla programmazione Snippet di codice
Applicare un'etichetta e filtrare per ID etichetta (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() + '"');
Crea una query lunga utilizzando una clausola IN (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 in gruppo

Quando apporti modifiche a un'entità Google Ads, gli script Google Ads non eseguono la modifica immediatamente. Cerca invece di combinare più modifiche in batch, in modo da poter inviare una singola richiesta con più modifiche. Questo approccio velocizza gli script e riduce il carico sui server Google Ads. Tuttavia, esistono alcuni pattern di codice che costringono gli script Google Ads a scaricare frequentemente il proprio batch di operazioni, determinando una lenta esecuzione dello script.

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

Approccio alla programmazione Snippet di codice
Tenere traccia degli 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());
}
Recuperare gli elementi aggiornati in un ciclo di attività (non consigliato)
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() impone agli script Google Ads di eliminare l'operazione setCpc() ed eseguire una sola operazione alla volta. Il primo approccio, sebbene simile al secondo, abbia il vantaggio aggiuntivo di supportare il batch poiché la chiamata getCpc() viene eseguita in un loop separato da quello in cui viene chiamato setCpc().

Se possibile, utilizza gli strumenti di creazione

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

Prendi in considerazione i seguenti snippet di codice:

Approccio alla programmazione Snippet di codice
Utilizzare gli strumenti di creazione (consigliato)
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'ulteriore operazione di selezione che richiede il recupero della parola chiave. Inoltre, anche i metodi di creazione sono obsoleti.

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

Prendi in considerazione 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
Tenere traccia degli 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 ciclo di attività (non consigliato)
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() nello stesso loop che crea l'operazione, costringendo gli script Google Ads a eseguire un'operazione alla volta. Il primo approccio, sebbene simile, consente il batch poiché chiamiamo operator.getResult() in un loop diverso da quello in cui è stato creato.

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

Un'attività comune degli sviluppatori è eseguire i report e aggiornare le proprietà delle entità (ad esempio, offerte per parole chiave) in base ai valori del rendimento attuali. Quando devi aggiornare un numero elevato di entità, i caricamenti collettivi tendono a migliorare le prestazioni. Ad esempio, prendi in considerazione i seguenti script che aumentano il CPC massimo delle parole chiave per cui TopImpressionPercentage > 0.4 nell'ultimo mese:

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

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();
Seleziona e aggiorna 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);
  }
}

Mentre il secondo approccio offre un rendimento abbastanza buono, il primo è preferibile in questo caso,

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

  • I caricamenti collettivi hanno limiti più elevati, sia in termini di numero di entità da aggiornare, sia in termini di tempo complessivo di esecuzione.

Raggruppa i caricamenti collettivi per campagna

Quando crei i caricamenti collettivi, prova a raggruppare le operazioni in base alla campagna principale. Ciò aumenta l'efficienza e diminuisce la possibilità di modifiche in conflitto / errori di contemporaneità.

Considera due attività di caricamento collettivo in esecuzione in parallelo. Una mette in pausa gli annunci di un gruppo di annunci, l'altra regola le offerte per parola chiave. Anche se le operazioni non sono correlate, le operazioni potrebbero essere applicate a entità nello stesso gruppo di annunci (o a due gruppi di annunci diversi nella stessa campagna). In tal caso, il sistema bloccherà l'entità principale (la campagna o il gruppo di annunci condiviso), causando il blocco delle attività di caricamento collettivo l'una sull'altra.

Gli script Google Ads possono ottimizzare l'esecuzione nell'ambito di una singola attività di caricamento collettivo, pertanto 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 operino su un elenco di campagne che si escludono a vicenda e sulle relative entità secondarie, per ottimizzare il rendimento.

Report

Utilizzare i report per recuperare le statistiche

Quando vuoi recuperare grandi quantità di entità e le relative statistiche, spesso è meglio utilizzare i report anziché i metodi standard di AdsApp. È preferibile utilizzare i report per i seguenti motivi:

  • I report offrono un rendimento migliore per le 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);
  }
Utilizza iteratori AdsApp (sconsigliato)
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 delle parole chiave e recupera le statistiche un'entità alla volta. In questo caso, i report funzionano più velocemente poiché recuperano tutti i dati in una singola chiamata e li trasmettono in streaming secondo necessità. Inoltre, le parole chiave recuperate nel secondo approccio vengono conteggiate nella quota dello script per il numero di entità recuperate tramite una chiamata get().

Utilizza la ricerca anziché il report

Il metodo di report è stato creato per l'infrastruttura precedente e genererà risultati in formato flat anche se utilizzi GAQL. Ciò significa che deve trasformare i risultati della query in modo che corrispondano al vecchio stile, il che non è supportato per tutti i campi e aggiunge overhead a ogni chiamata.

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

Da GAQL ad AWQL preferito

Sebbene AWQL sia ancora supportato nelle query dei report e nelle chiamate withCondition, viene eseguito tramite un livello di traduzione che non ha piena compatibilità con AWQL reale. Per avere il controllo completo sulle tue query, assicurati di utilizzare GAQL.

Se vuoi tradurre query AWQL esistenti, puoi usare lo strumento di migrazione delle query.

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 tu li esegua o meno. Usa sempre filtri specifici per ridurre al minimo il set di risultati il più possibile in base al tuo caso d'uso.

Ad esempio, supponiamo che tu voglia trovare gruppi di annunci con offerte che non rientrano in un determinato intervallo. Sarebbe più veloce creare due query distinte, una per le offerte al di sotto della soglia inferiore e un'altra per le offerte superiori alla soglia superiore, anziché 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);
}
Filtrare i dati per query generica (non consigliato)
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 per l'account amministratore Google Ads (Centro clienti)

Preferisco eseguire inParallelo rispetto all'esecuzione seriale

Quando scrivi script per gli account amministratore, se possibile usa executeInParallel() anziché l'esecuzione seriale. 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 nostra pagina sui limiti per ulteriori dettagli.

Fogli di lavoro

Utilizzare le operazioni in gruppo durante l'aggiornamento dei fogli di lavoro

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

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

Approccio alla programmazione Snippet di codice
Aggiornare un intervallo di celle in una singola chiamata (consigliato)
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);
Aggiorna una cella alla volta (opzione non consigliata)
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 cerca di ottimizzare il secondo snippet di codice memorizzando nella cache i valori, il rendimento è scadente rispetto al primo snippet a causa del numero di chiamate API effettuate.