> ## Documentation Index
> Fetch the complete documentation index at: https://www.helius.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Optimisation du RPC Solana : Pratiques de Performance & Coût

> Optimisez les performances du RPC Solana, réduisez les coûts et améliorez la fiabilité. Optimisation des transactions, modèles de récupération de données et guide des meilleures pratiques.

Optimiser l'utilisation du RPC peut améliorer significativement les performances, réduire les coûts et enrichir l'expérience utilisateur. Ce guide couvre des techniques éprouvées pour des interactions efficaces avec le RPC Solana.

## Démarrage rapide

<CardGroup cols={2}>
  <Card title="Optimisation des Transactions" icon="bolt" href="#optimisation-des-transactions">
    Optimisez les unités de calcul, les frais prioritaires et l'envoi de transactions
  </Card>

  <Card title="Récupération de Données" icon="database" href="#optimisation-de-la-récupération-des-données">
    Modèles efficaces pour récupérer les données des comptes et des programmes
  </Card>

  <Card title="Surveillance en Temps Réel" icon="chart-line" href="#surveillance-en-temps-réel">
    Abonnements WebSocket et optimisation des données en streaming
  </Card>

  <Card title="Meilleures Pratiques" icon="shield-check" href="#meilleures-pratiques">
    Conseils de performance et gestion des ressources
  </Card>
</CardGroup>

## Optimisation des Transactions

### Gestion des Unités de Calcul

**1. Simuler pour déterminer l'utilisation réelle :**

```typescript theme={"system"}
const testTransaction = new VersionedTransaction(/* your transaction */);
const simulation = await connection.simulateTransaction(testTransaction, {
  replaceRecentBlockhash: true,
  sigVerify: false
});
const unitsConsumed = simulation.value.unitsConsumed;
```

**2. Définir des limites appropriées avec marge :**

```typescript theme={"system"}
const computeUnitLimit = Math.ceil(unitsConsumed * 1.1);
const computeUnitIx = ComputeBudgetProgram.setComputeUnitLimit({ 
  units: computeUnitLimit 
});
instructions.unshift(computeUnitIx); // Add at beginning
```

### Optimisation des Frais Prioritaires

**1. Obtenez des estimations de frais dynamiques :**

```typescript theme={"system"}
const response = await fetch(`https://mainnet.helius-rpc.com/?api-key=${API_KEY}`, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    method: 'getPriorityFeeEstimate',
    params: [{
      accountKeys: ['11111111111111111111111111111112'], // System Program
      options: { recommended: true }
    }]
  })
});
const { priorityFeeEstimate } = await response.json().result;
```

**2. Appliquez le frais prioritaire :**

```typescript theme={"system"}
const priorityFeeIx = ComputeBudgetProgram.setComputeUnitPrice({ 
  microLamports: priorityFeeEstimate 
});
instructions.unshift(priorityFeeIx);
```

### Meilleures Pratiques pour l'Envoi de Transactions

<Tabs>
  <Tab title="Approche Standard">
    ```typescript theme={"system"}
    // Serialize and encode
    const serializedTx = transaction.serialize();
    const signature = await connection.sendRawTransaction(serializedTx, {
      skipPreflight: true, // Saves ~100ms
      maxRetries: 0 // Handle retries manually
    });
    ```
  </Tab>

  <Tab title="Avec Confirmation">
    ```typescript theme={"system"}
    // Send and confirm with custom logic
    const signature = await connection.sendRawTransaction(serializedTx);

    // Monitor confirmation
    const confirmation = await connection.confirmTransaction({
      signature,
      blockhash: latestBlockhash.blockhash,
      lastValidBlockHeight: latestBlockhash.lastValidBlockHeight
    });
    ```
  </Tab>
</Tabs>

## Optimisation de la Récupération des Données

### Méthodes de Pagination Améliorées (V2)

**Pour les requêtes de données à grande échelle, utilisez les nouvelles méthodes V2 avec pagination basée sur les curseurs :**

<Card title="⚡ Boost de Performance" icon="rocket" color="#E84125">
  `getProgramAccountsV2` et `getTokenAccountsByOwnerV2` offrent des améliorations de performance significatives pour les applications gérant de grands ensembles de données :

  * **Limites configurables** : 1 à 10 000 comptes par requête
  * **Pagination basée sur les curseurs** : Évite les délais d'attente sur les grandes requêtes
  * **Mises à jour incrémentielles** : Utilisez `changedSinceSlot` pour la synchronisation en temps réel
  * **Meilleure utilisation de la mémoire** : Streamer les données au lieu de tout charger à la fois
</Card>

**Exemple : Interrogation de comptes de programme efficace**

```typescript theme={"system"}
// ❌ Old approach - could timeout with large datasets
const allAccounts = await connection.getProgramAccounts(programId, {
  encoding: 'base64',
  filters: [{ dataSize: 165 }]
});

// ✅ New approach - paginated with better performance
let allAccounts = [];
let paginationKey = null;

do {
  const response = await fetch(`https://mainnet.helius-rpc.com/?api-key=${API_KEY}`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      jsonrpc: '2.0',
      id: '1',
      method: 'getProgramAccountsV2',
      params: [
        programId,
        {
          encoding: 'base64',
          filters: [{ dataSize: 165 }],
          limit: 5000,
          ...(paginationKey && { paginationKey })
        }
      ]
    })
  });
  
  const data = await response.json();
  allAccounts.push(...data.result.accounts);
  paginationKey = data.result.paginationKey;
} while (paginationKey);
```

**Mises à jour incrémentielles pour les applications en temps réel :**

```typescript theme={"system"}
// Get only accounts modified since a specific slot
const incrementalUpdate = await fetch(`https://mainnet.helius-rpc.com/?api-key=${API_KEY}`, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    jsonrpc: '2.0',
    id: '1',
    method: 'getProgramAccountsV2',
    params: [
      programId,
      {
        encoding: 'jsonParsed',
        limit: 1000,
        changedSinceSlot: lastProcessedSlot // Only get recent changes
      }
    ]
  })
});
```

## Optimisation de la Récupération des Données

### Requêtes de Comptes Efficaces

<Tabs>
  <Tab title="Compte Unique">
    ```typescript theme={"system"}
    // Use dataSlice to reduce payload size
    const accountInfo = await connection.getAccountInfo(pubkey, {
      encoding: 'base64',
      dataSlice: { offset: 0, length: 100 }, // Only get needed data
      commitment: 'confirmed'
    });
    ```
  </Tab>

  <Tab title="Comptes Multiples">
    ```typescript theme={"system"}
    // Batch multiple account queries
    const accounts = await connection.getMultipleAccountsInfo([
      pubkey1, pubkey2, pubkey3
    ], {
      encoding: 'base64',
      commitment: 'confirmed'
    });
    ```
  </Tab>

  <Tab title="Comptes de Programme">
    ```typescript theme={"system"}
    // Use filters to reduce data transfer
    const accounts = await connection.getProgramAccounts(programId, {
      filters: [
        { dataSize: 165 }, // Token account size
        { memcmp: { offset: 0, bytes: mintAddress }}
      ],
      encoding: 'jsonParsed'
    });
    ```
  </Tab>
</Tabs>

### Recherches de Solde de Jetons

<CodeGroup>
  ```typescript ❌ Inefficient theme={"system"}
  // Don't do this - requires N+1 RPC calls
  const tokenAccounts = await connection.getTokenAccountsByOwner(owner, {
    programId: TOKEN_PROGRAM_ID
  });
  const balances = await Promise.all(
    tokenAccounts.value.map(acc => 
      connection.getTokenAccountBalance(acc.pubkey)
    )
  );
  // ~500ms + (100ms * N accounts)
  ```

  ```typescript ✅ Optimized theme={"system"}
  // Single call with parsed data
  const tokenAccounts = await connection.getTokenAccountsByOwner(owner, {
    programId: TOKEN_PROGRAM_ID
  }, { encoding: 'jsonParsed' });

  const balances = tokenAccounts.value.map(acc => ({
    mint: acc.account.data.parsed.info.mint,
    amount: acc.account.data.parsed.info.tokenAmount.uiAmount
  }));
  // ~500ms total - 95% reduction for large wallets
  ```
</CodeGroup>

### Historique des Transactions

Pour l'historique complet des adresses, utilisez [`getTransactionsForAddress`](/docs/fr/rpc/gettransactionsforaddress) — une méthode exclusive Helius qui renvoie des données de transactions complètes, y compris l'activité du compte de jetons associé, en un seul appel :

<CodeGroup>
  ```typescript ❌ Inefficient theme={"system"}
  // Avoid sequential transaction fetching
  const signatures = await connection.getSignaturesForAddress(address, { limit: 100 });
  const transactions = await Promise.all(
    signatures.map(sig => connection.getTransaction(sig.signature))
  );
  // ~1s + (200ms * 100 txs) = ~21s
  // Also note: getSignaturesForAddress doesn't include token account transactions
  ```

  ```typescript ✅ Fast (Helius Exclusive) theme={"system"}
  // Use getTransactionsForAddress for full history including token accounts
  const response = await fetch(`https://mainnet.helius-rpc.com/?api-key=${API_KEY}`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      jsonrpc: '2.0',
      id: 1,
      method: 'getTransactionsForAddress',
      params: [
        address,
        {
          transactionDetails: 'full',
          limit: 100,
          filters: { tokenAccounts: 'balanceChanged' }
        }
      ]
    })
  });
  // ~100ms total - includes complete token history in one call
  ```
</CodeGroup>

### Historique des Transferts

Lorsque vous avez uniquement besoin de mouvements de jetons ou de SOL — paiements, activité de portefeuille, rapprochement de solde — utilisez [`getTransfersByAddress`](/docs/fr/rpc/gettransfersbyaddress) (exclusif Helius, nécessite un [plan Developer](/docs/fr/billing/plans) ou supérieur). Il renvoie des objets de transfert analysés et lisibles par l'homme avec les propriétaires, les mint, les montants et les décimales déjà résolus, vous évitant ainsi de devoir analyser les transactions :

```typescript theme={"system"}
// Parsed USDC transfers received by a wallet - no manual parsing needed
const response = await fetch(`https://mainnet.helius-rpc.com/?api-key=${API_KEY}`, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    jsonrpc: '2.0',
    id: 1,
    method: 'getTransfersByAddress',
    params: [
      address, // Wallet owner address, not a token account
      {
        mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', // USDC
        direction: 'in',
        limit: 100
      }
    ]
  })
});
// Each transfer includes parsed sender, recipient, amount, decimals, and uiAmount
```

Règle générale : utilisez `getTransactionsForAddress` lorsque vous avez besoin de charges de transaction complètes ou d'activités non liées aux transferts, et `getTransfersByAddress` lorsque vous avez besoin d'enregistrements de transferts clairs pour les registres et le suivi des paiements.

## Surveillance en Temps Réel

### Abonnements aux Comptes

<CodeGroup>
  ```typescript ❌ Polling theme={"system"}
  // Avoid polling - wastes resources
  setInterval(async () => {
    const accountInfo = await connection.getAccountInfo(pubkey);
    // Process updates...
  }, 1000);
  ```

  ```typescript ✅ WebSocket theme={"system"}
  // Use WebSocket subscriptions for real-time updates
  const subscriptionId = connection.onAccountChange(
    pubkey,
    (accountInfo, context) => {
      // Handle real-time updates
      console.log('Account updated:', accountInfo);
    },
    'confirmed',
    { encoding: 'base64', dataSlice: { offset: 0, length: 100 }}
  );
  ```
</CodeGroup>

### Surveillance des Comptes de Programme

```typescript theme={"system"}
// Monitor specific program accounts with filters
connection.onProgramAccountChange(
  programId,
  (accountInfo, context) => {
    // Handle program account changes
  },
  'confirmed',
  {
    filters: [
      { dataSize: 1024 },
      { memcmp: { offset: 0, bytes: ACCOUNT_DISCRIMINATOR }}
    ],
    encoding: 'base64'
  }
);
```

### Surveillance des Transactions

```typescript theme={"system"}
// Subscribe to transaction logs for real-time monitoring
const ws = new WebSocket(`wss://mainnet.helius-rpc.com/?api-key=${API_KEY}`);

ws.on('open', () => {
  ws.send(JSON.stringify({
    jsonrpc: '2.0',
    id: 1,
    method: 'logsSubscribe',
    params: [
      { mentions: [programId] },
      { commitment: 'confirmed' }
    ]
  }));
});

ws.on('message', (data) => {
  const message = JSON.parse(data);
  if (message.params) {
    const signature = message.params.result.value.signature;
    // Process transaction signature
  }
});
```

## Modèles Avancés

### Logique de Réessai Intelligent

```typescript theme={"system"}
class RetryManager {
  private backoff = new ExponentialBackoff({
    min: 100,
    max: 5000,
    factor: 2,
    jitter: 0.2
  });

  async executeWithRetry<T>(operation: () => Promise<T>): Promise<T> {
    while (true) {
      try {
        return await operation();
      } catch (error) {
        if (error.message.includes('429')) {
          // Rate limit - wait and retry
          await this.backoff.delay();
          continue;
        }
        throw error;
      }
    }
  }
}
```

### Traitement Efficace de la Mémoire

```typescript theme={"system"}
// Process large datasets in chunks
function chunk<T>(array: T[], size: number): T[][] {
  return Array.from({ length: Math.ceil(array.length / size) }, (_, i) =>
    array.slice(i * size, i * size + size)
  );
}

// Process program accounts in batches
const allAccounts = await connection.getProgramAccounts(programId, {
  dataSlice: { offset: 0, length: 32 }
});

const chunks = chunk(allAccounts, 100);
for (const batch of chunks) {
  const detailedAccounts = await connection.getMultipleAccountsInfo(
    batch.map(acc => acc.pubkey)
  );
  // Process batch...
}
```

### Pooling de Connexions

```typescript theme={"system"}
class ConnectionPool {
  private connections: Connection[] = [];
  private currentIndex = 0;

  constructor(rpcUrls: string[]) {
    this.connections = rpcUrls.map(url => new Connection(url));
  }

  getConnection(): Connection {
    const connection = this.connections[this.currentIndex];
    this.currentIndex = (this.currentIndex + 1) % this.connections.length;
    return connection;
  }
}

const pool = new ConnectionPool([
  'https://mainnet.helius-rpc.com/?api-key=YOUR_API_KEY',
  'https://mainnet-backup.helius-rpc.com/?api-key=YOUR_API_KEY'
]);
```

## Surveillance de la Performance

### Suivre l'Utilisation du RPC

```typescript theme={"system"}
class RPCMonitor {
  private metrics = {
    calls: 0,
    errors: 0,
    totalLatency: 0
  };

  async monitoredCall<T>(operation: () => Promise<T>): Promise<T> {
    const start = Date.now();
    this.metrics.calls++;
    
    try {
      const result = await operation();
      this.metrics.totalLatency += Date.now() - start;
      return result;
    } catch (error) {
      this.metrics.errors++;
      throw error;
    }
  }

  getStats() {
    return {
      ...this.metrics,
      averageLatency: this.metrics.totalLatency / this.metrics.calls,
      errorRate: this.metrics.errors / this.metrics.calls
    };
  }
}
```

## Meilleures Pratiques

### Niveaux d'Engagement

<Tabs>
  <Tab title="processed">
    * **Utilisation pour** : Abonnements WebSocket, mises à jour en temps réel
    * **Latence** : \~400ms
    * **Fiabilité** : Bon pour la plupart des applications
  </Tab>

  <Tab title="confirmed">
    * **Utilisation pour** : Requêtes générales, informations sur les comptes
    * **Latence** : \~1s
    * **Fiabilité** : Recommandé pour la plupart des cas d'utilisation
  </Tab>

  <Tab title="finalized">
    * **Utilisation pour** : Règlement final, opérations irréversibles
    * **Latence** : \~32s
    * **Fiabilité** : Certitude maximale
  </Tab>
</Tabs>

### Gestion des Ressources

<CheckboxList>
  * Utilisez `dataSlice` pour limiter la taille des charges utiles
  * Implémentez un filtrage côté serveur avec `memcmp` et `dataSize`
  * Regrouper les opérations pour réduire les allers-retours
  * Mettre en cache les résultats pour éviter les appels redondants
  * Fermez les abonnements WebSocket une fois terminé
  * Implémentez des disjoncteurs pour la gestion des erreurs
</CheckboxList>

### Gestion des Erreurs

```typescript theme={"system"}
// Implement robust error handling
async function robustRPCCall<T>(operation: () => Promise<T>): Promise<T> {
  try {
    return await operation();
  } catch (error) {
    if (error.code === -32602) {
      // Invalid params - fix request
      throw new Error('Invalid RPC parameters');
    } else if (error.code === -32005) {
      // Node behind - retry with different node
      throw new Error('Node synchronization issue');
    } else if (error.message.includes('429')) {
      // Rate limit - implement backoff
      throw new Error('Rate limited');
    }
    throw error;
  }
}
```

## Pièges Courants à Éviter

<Warning>
  **Évitez ces erreurs fréquentes :**

  * Sondage au lieu d'utiliser les abonnements WebSocket
  * Récupération de données de compte complètes alors que seules des données partielles sont nécessaires
  * Ne pas utiliser d'opérations groupées pour plusieurs requêtes
  * Ignorer les limites de taux et ne pas implémenter de logique de réessai adéquate
  * Utiliser l'engagement `finalized` alors que `confirmed` est suffisant
  * Ne pas fermer les abonnements, entraînant des fuites de mémoire
</Warning>

## Méthodes Associées

Les techniques d'optimisation dans ce guide font référence aux méthodes WebSocket et RPC suivantes :

<CardGroup cols={2}>
  <Card title="getTransactionsForAddress" href="/docs/fr/rpc/gettransactionsforaddress">
    Historique complet des transactions avec filtrage, tri et prise en charge des comptes de jetons (exclusif Helius)
  </Card>

  <Card title="getTransfersByAddress" href="/docs/fr/rpc/gettransfersbyaddress">
    Historique des transferts de jetons et SOL analysés pour les paiements et le rapprochement (exclusif Helius)
  </Card>

  <Card title="getTransaction" href="/docs/fr/api-reference/rpc/http/gettransaction">
    Récupérer tous les détails d'une transaction par signature
  </Card>

  <Card title="getProgramAccounts" href="/docs/fr/api-reference/rpc/http/getprogramaccounts">
    Récupérer tous les comptes possédés par un programme
  </Card>

  <Card title="getTokenAccountsByOwner" href="/docs/fr/api-reference/rpc/http/gettokenaccountsbyowner">
    Obtenir les comptes de jetons pour un portefeuille
  </Card>

  <Card title="getMultipleAccountsInfo" href="/docs/fr/api-reference/rpc/http/getmultipleaccounts">
    Récupérer en lot les détails de plusieurs comptes
  </Card>

  <Card title="getAccountInfo" href="/docs/fr/api-reference/rpc/http/getaccountinfo">
    Obtenir des informations sur un seul compte
  </Card>

  <Card title="accountSubscribe" href="/docs/fr/api-reference/rpc/websocket/accountsubscribe">
    S'abonner aux changements de compte via WebSocket
  </Card>

  <Card title="programSubscribe" href="/docs/fr/api-reference/rpc/websocket/programsubscribe">
    S'abonner aux changements des comptes de programme via WebSocket
  </Card>

  <Card title="logsSubscribe" href="/docs/fr/api-reference/rpc/websocket/logssubscribe">
    S'abonner aux journaux de transactions via WebSocket
  </Card>
</CardGroup>

## Résumé

En mettant en œuvre ces techniques d'optimisation, vous pouvez atteindre :

* **Réduction de 60-90 %** du volume des appels API
* **Latence considérablement réduite** pour les opérations en temps réel
* **Réduction de l'utilisation de la bande passante** grâce à des requêtes ciblées
* **Meilleure résilience aux erreurs** avec une logique de réessai intelligente
* **Réduction des coûts opérationnels** grâce à une utilisation efficace des ressources

<Card title="Prochaines Étapes" icon="arrow-right">
  Prêt à mettre en œuvre ces optimisations ? Consultez notre [Guide d'Optimisation des Transactions](/docs/fr/sending-transactions/optimizing-transactions) pour les meilleures pratiques spécifiques aux transactions.
</Card>
