Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Pour améliorer les performances de vos scripts et celles de la plateforme, consultez et suivez les meilleures pratiques décrites ci-dessous.
Utilisation des sélecteurs
Utiliser des filtres
Utilisez les filtres d’un sélecteur au lieu de filtrer les entités vous-même. Les sélecteurs vous permettent de filtrer par ID et conditions. Par exemple, vous pouvez filtrer par les performances d’une entité (campagne de retour avec un CPC moyen supérieur à 10), son status (campagnes mises en pause), le nom de l’objet parent de l’entité, etc.
Avantages de l’utilisation de filtres :
Limite le nombre d’entités que le sélecteur renvoie aux seules entités dont vous avez besoin.
Permet au script de s’exécuter plus rapidement (moins d’entités à retourner et à traiter)
Réduit le risque d’atteindre les limites de lecture d’entité (voir Limites d’exécution de script).
Procédure correcte
var adGroups = AdsApp.adGroups()
.withCondition('Status = PAUSED')
.get();
while (adGroups.hasNext()) {
var adGroup = adGroups.next();
// Do something with paused ad group.
}
Mauvaise façon
var adGroups = AdsApp.adGroups().get();
while (adGroups.hasNext()) {
var adGroup = adGroups.next();
if (adGroup.isPaused() == true) {
// Do something with paused ad group.
}
}
Ne parcourez pas la hiérarchie des entités
Si vous souhaitez obtenir les entités enfants d’une entité ou l’entité parente de l’entité, ne traversez pas la hiérarchie des entités pour les obtenir.
Pour obtenir des entités enfants, utilisez la collection de l’entité enfant au niveau souhaité.
Procédure correcte
// Get all ads.
var ads = AdsApp.ads().get();
while (ads.hasNext()) {
var ad = ads.next();
// Do something with ad.
}
Ou, si vous souhaitez des annonces d’une campagne spécifique :
// Get all ads in the campaign, 'mycampaign'.
var ads = AdsApp.ads()
.withCondition("CampaignName = 'mycampaign'")
.get();
while (ads.hasNext()) {
var ad = ads.next();
// Do something with ad.
}
Vous pouvez également obtenir les annonces d’une campagne, si vous disposez de l’objet de la campagne :
// Get all ads in the campaign.
var ads = campaign.ads().get();
while (ads.hasNext()) {
var ad = ads.next();
// Do something with ad.
}
Mauvaise façon
var campaigns = AdsApp.campaigns().get();
while (campaigns.hasNext()) {
var adGroups = campaigns.next().adGroups().get();
while (adGroups.hasNext()) {
var ads = adGroups.next().ads().get();
while (ads.hasNext()) {
var ad = ads.next();
// Do something with ad.
}
}
}
Il en va de même si vous souhaitez obtenir le parent d’une entité. Au lieu de parcourir la hiérarchie pour obtenir le parent, utilisez la méthode d’accesseur parent de l’entité enfant.
Procédure correcte
// Get all ads.
var ads = AdsApp.ads()
.withCondition('Clicks > 5')
.forDateRange('LAST_7_DAYS')
.get();
while (ads.hasNext()) {
var ad = ads.next();
// Do something with campaign and adGroup.
var adGroup = ad.adGroup();
var campaign = ad.campaign();
}
Mauvaise façon
var campaigns = AdsApp.campaigns().get();
while (campaigns.hasNext()) {
var campaign = campaigns.next();
var adGroups = campaign.adGroups().get();
while (adGroups.hasNext()) {
var adGroup = adGroups.next();
var ads = adGroup.ads().get();
while (ads.hasNext()) {
var ad = ads.next();
if ('<some condition is met>') {
// Do something with campaign and adGroup.
}
}
}
}
Utiliser les ID d’entité si possible
L’utilisation d’ID pour filtrer les entités offre les meilleures performances.
Ce
var adGroups = AdsApp.adGroups()
.withIds(["123456"])
.get();
while (adGroups.hasNext()) {
var adGroup = adGroups.next();
// Do something with adGroup.
}
Offre de meilleures performances
var adGroups = AdsApp.adGroups()
.withCondition("Name = 'myadgroup'")
.get();
while (adGroups.hasNext()) {
var adGroup = adGroups.next();
// Do something with adGroup.
}
Évitez les boucles étroites avec des sélecteurs et un nombre inutile de gets.
Évitez les boucles avec les requêtes get qui obtiennent une seule entité. Par exemple, supposons que vous exécutez un rapport de performances sur les mots clés et que vous souhaitez mettre à jour les mots clés dans le rapport. Au lieu d’obtenir une ligne du rapport, d’obtenir le mot clé, puis de le mettre à jour, vous devez créer une liste des ID de mot clé à mesure que vous parcourez chaque ligne du rapport. Ensuite, transmettez la liste des ID au sélecteur pour obtenir tous les mots-clés dans une seule requête get. Vous pouvez ensuite parcourir la liste des mots clés et les mettre à jour.
Procédure correcte
var report = AdsApp.report('<report query goes here>');
var rows = report.rows();
var idLists = []; // an array where each element contains an array of IDs.
var idList = []; // array of IDs that's limited to maxCount.
var maxCount = 10000;
while (rows.hasNext()) {
var row = rows.next();
if (idList.length < maxCount) {
idList.push(row['id']);
}
else {
idLists.push(idList);
idList = [];
}
}
for (idList of idLists) {
var keywords = AdsApp.keywords()
.withIds(idList)
.get();
while (keywords.hasNext()) {
var keyword = keywords.next();
// update the keyword
}
}
Mauvaise façon
var report = AdsApp.report('<report query goes here>');
var rows = report.rows();
while (rows.hasNext()) {
var row = rows.next();
var keyword = AdsApp.keywords()
.withIds([row['id']])
.get()
.next();
// update the keyword
}
N’incluez la méthode forDateRange que si vous envisagez d’appeler la méthode getStats de l’entité
L’appel d’une forDateRange méthode de sélecteur permet au sélecteur d’obtenir les données de performance de l’entité. L’obtention des données de performances d’une entité est coûteuse. Ne les obtenez donc que si vous envisagez d’appeler la méthode de getStats l’entité et d’utiliser les données.
La plage de dates que vous spécifiez pour une entité ne s’applique pas aux entités parent ou enfant auxquelles vous accédez à partir de cette entité. Par exemple, si vous obtenez un groupe d’annonces, puis sa campagne parente et essayez d’accéder aux métriques de performances de la campagne, l’appel échoue.
L’appel campaignStats.getReturnOnAdSpend() dans l’exemple suivant échoue, car la plage de dates s’applique au groupe d’annonces et non à la campagne.
var myAdGroups = AdsApp.adGroups().
.withCondition("CampaignName CONTAINS 'gen'")
.forDateRange("LAST_7_DAYS")
.get();
while (myAdGroups.hasNext()) {
var adGroup = myAdGroups.next();
var campaign = adGroup.getCampaign();
var campaignStats = campaign.getStats();
var campaignROAS = campaignStats.getReturnOnAdSpend();
}
Pour que cela fonctionne, vous devez créer un sélecteur pour la campagne.
var myAdGroups = AdsApp.adGroups().
.withCondition("CampaignName CONTAINS 'gen'")
.forDateRange("LAST_7_DAYS")
.get();
while (myAdGroups.hasNext()) {
var adGroup = myAdGroups.next();
var campaign = AdsApp.campaigns()
.withIds([adGroup.getCampaign().getId()])
.forDateRange("LAST_7_DAYS")
.get()
.next();
var campaignStats = campaign.getStats();
var campaignROAS = campaignStats.getReturnOnAdSpend();
}
Ne modifiez pas la propriété d’une entité utilisée comme condition dans le sélecteur
Les itérateurs réduisent la sollicitation de la mémoire en ne chargeant qu’un seul élément à la fois plutôt que l’ensemble complet des éléments. Pour cette raison, la modification d’une propriété que vous avez utilisée comme condition dans le sélecteur peut entraîner un comportement inattendu.
Procédure correcte
var adGroups = [];
var iterator = AdsApp.adGroups()
.withCondition('Status = ENABLED')
.get();
while (iterator.hasNext()) {
adGroups.push(iterator.next());
}
for (var adGroup of adGroups) {
adGroup.pause();
}
Mauvaise façon
var adGroups = AdsApp.adGroups()
.withCondition('Status = ENABLED')
.get();
while (adGroups.hasNext()) {
var adGroup = adGroups.next();
adGroup.pause();
}
Mise à jour par lot
Afin d’améliorer les performances, les processus Scripts génèrent des requêtes par lots. Si vous appelez la méthode d’opération d’une demande de génération, cela force les scripts à traiter immédiatement les demandes de génération en file d’attente, ce qui annule tout gain de performances. Si vous créez plusieurs entités, n’exécutez pas les méthodes d’opération dans la même boucle que celle utilisée pour construire l’entité. Cela entraîne des performances médiocres, car une seule entité à la fois est traitée. Au lieu de cela, créez un tableau des opérations et traitez-les après la boucle de génération.
Procédure correcte
// An array to hold the operations, so you
// can process them after all the entities are queued.
var operations = [];
// Create all the new entities.
for (var i = 0; i < keywords.length; i++) {
var keywordOperation = AdsApp.adGroups().get().next()
.newKeywordBuilder()
.withText(keywords[i])
.build();
operations.push(keywordOperation);
}
// Now call the operation method so the build requests
// get processed in batches.
for (var i = 0; i < operations.length; i++) {
var newKeyword = operations[i].getResult();
}
Mauvaise façon
for (var i = 0; i < keywords.length; i++) {
var keywordOperation = AdsApp.adGroups().get().next() // Get the first ad group
.newKeywordBuilder() // Add the keyword to the ad group
.withText(keywords[i])
.build();
// Don't get results in the same loop that creates
// the entity because Scripts then only processes one
// entity at a time.
var newKeyword = keywordOperation.getResult();
}
Il en va de même si vous mettez à jour une entité, puis obtenez la même propriété que celle que vous avez mise à jour. Actions déconseillées :
var bidAmount = 1.2;
while (keywords.hasNext()) {
var keyword = keywords.next();
keyword.bidding().setCpc(bidAmount);
if (keyword.bidding().getCpc() != bidAmount) {
Logger.log(`Failed to update bid amount for keyword, ${keyword.getText()} (${keyword.getId()})`);
}
}
Utiliser le mot clé yield lors de l’obtention de grands ensembles d’entités
La récupération d’un grand nombre d’entités et leur chargement dans une seule liste que vous traitez en boucle présentent quelques inconvénients :
Selon la taille de la demande, il peut falloir un certain nombre de requêtes back-end pour extraire toutes les entités avant le démarrage de la boucle. Si vous ne les traitez pas toutes, le temps et la puissance de calcul utilisés pour obtenir les entités non traitées sont perdus. Par exemple, si vous récupérez 10 000 mots-clés et que la boucle s’interrompt après avoir traité seulement 2 000 mots-clés, le temps et la puissance de calcul utilisés pour obtenir les 8 000 mots-clés restants sont perdus.
La création de la liste nécessite davantage de mémoire pour contenir toutes les entités en même temps.
Pour résoudre ces problèmes, utilisez le mot clé yield, qui permet à votre script de récupérer des entités à la demande ou, dans un certain sens, de les récupérer « paresseusement » uniquement lorsqu’elles sont nécessaires. Cela signifie que votre script n’effectue pas plus d’appels qu’il n’en a besoin pour le moment et ne fait pas circuler de grandes listes d’objets.
Cet exemple inclut la journalisation pour illustrer le flux de contrôle lors de l’utilisation du mot clé rendement.
function main() {
const keywords = getKeywords();
//@ts-ignore <-- suppresses iterator error
for (const keyword of keywords) {
Logger.log("in for loop\n\n");
}
}
// Note that you must use the yield keyword in a generator function - see the
// '*' at the end of the function keyword.
function* getKeywords() {
const keywords = AdsApp.keywords()
.withCondition("Status = ENABLED")
.withCondition("CombinedApprovalStatus = APPROVED")
.withLimit(10)
.get();
Logger.log(`total keywords in account: ${keywords.totalNumEntities()} \n\n`);
while (keywords.hasNext()) {
Logger.log("before next()\n\n");
yield keywords.next();
Logger.log("after next\n\n");
}
}
Modèle d’appel pour éviter les limites d’entités
Il existe une limite au nombre d’entités que les scripts peuvent renvoyer pour un compte. Si la demande renvoie plus que cette limite, Scripts génère une erreur avec le message : Il y a trop d’entités. L’exemple suivant montre le modèle d’appel que vous devez utiliser lors de l’obtention d’un grand nombre d’entités. L’exemple tente d’abord d’extraire tous les mots clés au niveau du compte. Si cela échoue, il tente d’effectuer plusieurs appels pour récupérer des mots clés par campagne, car il y a généralement moins d’entités au niveau de la campagne. Vous pouvez généralement continuer ce modèle jusqu’au niveau du groupe d’annonces si nécessaire.
Pour plus d’informations sur l’utilisation du mot clé rendement, voir Utiliser le mot clé rendement lors de l’obtention de grands ensembles d’entités.
function* getEntities() {
const applyConditions = _ => _
.withCondition('CampaignStatus = ENABLED')
.withCondition('AdGroupStatus = ENABLED')
.withCondition('Status = ENABLED')
.withCondition("CombinedApprovalStatus = DISAPPROVED");
try {
// Get the account's keywords.
const keywords = applyConditions(AdsApp.keywords()).get();
while (keywords.hasNext()) {
yield keywords.next();
}
} catch (e) {
if (!e.message.startsWith('There are too many entities')) {
throw e;
}
// If there are too many keywords at the account level,
// get keywords by campaigns under the account.
const campaigns = AdsApp.campaigns().get();
while (campaigns.hasNext()) {
const campaign = campaigns.next();
const keywords = applyConditions(campaign.keywords()).get();
while (keywords.hasNext()) {
yield keywords.next();
}
}
}
}