Skip to Content
React Native14. Qualité14.5 Sentry & perf

Chapitre 14.5 — Sentry & la performance

Où on en est : dernière pièce de la qualité. En release, plus de RedBox (ch. 12.2) — les erreurs meurent en silence chez l’utilisateur. Sentry rallume la lumière. Et pour clore : la synthèse perf du cours — les vrais leviers, dans l’ordre.

⏱️ TL;DR@sentry/react-native capte crashs JS ET natifs en production, avec stack traces désobfusquées (source maps uploadées par le plugin — et par npx sentry-expo-upload-sourcemaps après chaque OTA !). Config minimale + enrichissement (breadcrumbs, contexte de session), plan gratuit largement suffisant. Côté perf : la checklist finale du cours — mesurer d’abord (le profiler), les 5 leviers qui comptent, et l’anti-liste de ce qui n’en vaut pas la peine.

🎯 Objectifs

  • Installer Sentry (config plugin, DSN, source maps — le circuit complet).
  • Enrichir les rapports : contexte, breadcrumbs, la capture manuelle utile.
  • Réviser la doctrine Data Safety (ch. 13.3) après l’ajout.
  • Mémoriser la checklist perf définitive du cours.

Sentry : l’installation

npx expo install @sentry/react-native
// app.config.ts — le config plugin (upload des source maps aux builds) plugins: [ ['@sentry/react-native/expo', { organization: 'alex', project: 'drill' }], ],
// app/_layout.tsx — l'init, AVANT tout le reste import * as Sentry from '@sentry/react-native' Sentry.init({ dsn: 'https://…@…ingest.sentry.io/…', // public par nature (ch. 7.1 — pas un secret) enabled: !__DEV__, // silence en dev : la RedBox suffit tracesSampleRate: 0, // le tracing perf : plus tard, peut-être sendDefaultPii: false, // pas de données perso — cohérence ADR 0001 }) export default Sentry.wrap(RootLayout) // l'error boundary racine

C’est un module natif → rebuild (le réflexe du ch. 11.1 — et le bump de version du ch. 12.5). À partir de là : tout crash (JS non attrapé, natif, ANR) remonte au dashboard avec appareil, version, updateId — le quadruplet de l’écran À propos (ch. 12.6), collecté automatiquement.

Le point critique OTA : les stack traces de production sont minifiées — illisibles sans source maps. Le plugin les uploade aux BUILDS ; mais chaque eas update crée un NOUVEAU bundle :

eas update --channel preview -m "fix" npx sentry-expo-upload-sourcemaps dist # ← le compagnon OBLIGATOIRE de chaque update

L’oublier = des rapports en index.android.bundle:1:284737 — techniquement des crashs, pratiquement du bruit. Dans le rituel de release JS (ch. 12.6), la ligne s’ajoute.

Enrichir : le contexte qui rend un rapport actionnable

// lib/feedback des erreurs — les breadcrumbs métier Sentry.addBreadcrumb({ category: 'game', message: `session start: ${theme} x${count}` }) Sentry.setTag('screen', 'quiz') // La capture MANUELLE — pour les erreurs attrapées mais anormales : try { const file = themeFileSchema.parse(raw) } catch (e) { Sentry.captureException(e, { tags: { source: 'drill-questions', slug } }) throw e }

Le cas du catch mérite l’attention : notre pipeline zod (ch. 7.3) IGNORE proprement les questions invalides — parfait pour l’utilisateur, invisible pour vous. captureException dans la branche warning transforme le silence en signal : « le repo a poussé du JSON cassé » arrive dans VOTRE dashboard avant le premier rapport utilisateur. Les erreurs GÉRÉES mais ANORMALES sont les meilleures clientes de la capture manuelle.

La mise à jour Data Safety (promise au ch. 13.3, exercice 3) : Sentry = « collecte de journaux de plantage/diagnostic » à déclarer, sendDefaultPii: false + masquage IP dans les réglages projet Sentry pour rester minimal, et la privacy policy gagne une ligne. Le badge « aucune donnée » devient « diagnostics anonymes uniquement » — toujours excellent.

La synthèse perf du cours

Tout le cours a semé de la perf — la moisson tient en une liste ordonnée :

La règle zéro : mesurer avant d’agir. Le profiler React (ch. 2.4), le performance monitor (FPS des deux threads — ch. 2.2), adb logcat pour le natif. Une optimisation sans mesure est une superstition.

Les 5 leviers, par rendement décroissant :

  1. Les listes (ch. 3.4) : FlatList bien réglée (memo, keyExtractor, hauteurs stables) — le levier n°1 de toute app de contenu. FlashList si le profiler le réclame.
  2. Les animations sur le thread UI (P10) : Reanimated, jamais de re-render par frame.
  3. Le travail hors du render : SQL agrégé en base (ch. 8.3), calculs dans les stores/ lib, useMemo sur les dérivations coûteuses SEULEMENT (ch. 6.1).
  4. Le démarrage : splash borné par l’hydratation réelle (ch. 12.1), pas d’imports lourds top-level, Hermes fait le reste (ch. 1.2).
  5. Le réseau perçu : cache + offline-first (P7) — la « perf » que l’utilisateur sent le plus est celle du contenu déjà là.

L’anti-liste (ce qu’on ne fait PAS sans preuve) : memoïser chaque composant, « optimiser » des écrans statiques, remplacer FlatList par des solutions exotiques, inline-styles-phobia généralisée. Le ch. 6.1 l’a posé, le profiler l’arbitre.

💡 Pour un dev Next.js — Sentry : le même produit que sur vos projets web (mêmes dashboards, alertes, releases) — la config RN ajoute le natif et les source maps d’OTA. La perf : remplacez « Core Web Vitals » par « FPS des deux threads + démarrage + listes » et la démarche est identique — mesurer, viser le levier le plus gros, re-mesurer.

⚠️ Piège — Sentry attrapera vos erreurs… et celles que vous ne vouliez pas voir : les premiers jours, le dashboard peut bruire d’erreurs réseau banales (timeouts du métro — le transport, pas le bundler). Réglez le bruit à la source : ne capturez PAS les HttpError attendues (elles sont GÉRÉES — ch. 7.4, c’est un état d’UI, pas un incident), filtrez par beforeSend si besoin. Un dashboard qui crie tout le temps finit ignoré — le silence sélectif est une feature.

✏️ Exercices

1. Installez Sentry, provoquez un crash de test en release (un bouton caché « À propos » long-press → throw new Error('sentry test')), et suivez-le jusqu’au dashboard désobfusqué.

✅ Solution

Init + rebuild + release locale → déclencher → le crash apparaît au dashboard en ~1 min avec la ligne EXACTE (source maps du build). Vérifier les métadonnées : version, updateId, modèle. Puis pousser une OTA modifiant le message, re-crasher SANS uploader les source maps → constater le charabia → uploader → lisible. La démonstration vaut mille rappels du rituel.

2. Implémentez le filtre anti-bruit : les HttpError de fetchJson ne remontent jamais, les erreurs zod du pipeline questions remontent avec le slug en tag.

✅ Solution

Dans Sentry.init : beforeSend: (event, hint) => hint.originalException instanceof HttpError ? null : event. Et le captureException ciblé du chapitre dans le catch zod (avec tags). Résultat : le réseau pourri du monde réel ne pollue pas ; la corruption de données (VOTRE responsabilité) alerte. Le dashboard devient un signal, pas un flux.

3. Le bilan perf final : profilez Drill 5 minutes (profiler React + perf monitor) et écrivez les 3 lignes de verdict : le plus lent constaté, le levier applicable, la mesure après correction (ou « rien à faire » — verdict honorable).

✅ Solution

Verdict typique attendu sur Drill : « (1) L’historique re-rend ses items au retour de partie — invalidation trop large : affiner les queryKeys. (2) Le premier rendu des thèmes attend le réseau à froid : le cache persisté (7.4) le masque dès la 2e ouverture — RAS. (3) FPS stables à 60/120 partout ailleurs — rien à faire. » L’exercice enseigne la conclusion la plus importante du chapitre : sur une app bien architecturée, le profiler conclut souvent « rien d’urgent » — et c’est le succès du cours entier, pas une déception.

🧠 Quiz

1. Pourquoi Sentry est-il indispensable dès qu’on distribue en release ?

Réponse

En release, plus de RedBox : les crashs sont silencieux chez l’utilisateur. Sentry capte JS + natif + ANR avec le contexte (version, updateId, appareil) — la seule visibilité.

2. Quel geste accompagne obligatoirement chaque eas update ?

Réponse

npx sentry-expo-upload-sourcemaps dist — chaque OTA crée un nouveau bundle : sans ses source maps, les stacks de prod sont du charabia minifié.

3. Quelles erreurs mérite la capture MANUELLE ?

Réponse

Les erreurs gérées mais anormales (le zod qui rejette une question du repo) : invisibles pour l’utilisateur, précieuses pour vous. Les erreurs attendues (HttpError réseau) sont filtrées — c’est un état d’UI, pas un incident.

4. Citez les 5 leviers perf dans l’ordre du rendement.

Réponse

Listes (FlatList réglée) → animations sur thread UI (Reanimated) → travail hors render (SQL, stores) → démarrage (splash/imports) → réseau perçu (cache offline-first). Et la règle zéro : mesurer d’abord.

5. Que déclare Drill au Data Safety après Sentry ?

Réponse

Collecte de journaux de plantage/diagnostic, anonymes (sendDefaultPii: false, IP masquée), non partagés à des fins publicitaires — et la privacy policy mise à jour.


👉 Partie suivante : Partie 15 — iOS & au-delà — ce qui changerait pour l’iPhone, le web, les modules natifs custom : les frontières du cours, cartographiées.