Les équipes adoptent Pages car le flux git push avec construction automatique et déploiement instantané est véritablement plus simple que de créer un pipeline CI à partir de zéro. C'est un réel avantage, pas du marketing. Le problème apparaît lorsque le projet grandit et que vous commencez à atteindre des limites que Pages ne peut pas résoudre : déclencheurs cron, plusieurs travailleurs avec des responsabilités distinctes, mise en scène avec des liaisons différentes. À ce stade, la migration vers Workers semble évidente, mais le véritable coût est rarement calculé avant de commencer.
Les véritables déclencheurs de la migration
Le déclencheur le plus courant est le déclencheur cron. Pages ne prend pas en charge cron de manière native. Si vous avez besoin d'une tâche qui s'exécute périodiquement (traitement des paiements, synchronisation des données externes, génération de rapports planifiés), vous disposez déjà d'un Worker distinct qui s'exécute parallèlement à votre projet Pages. À mesure que le nombre de travailleurs satellites augmente, l’équipe commence à se demander s’il ne serait pas plus logique de tout regrouper dans les travailleurs.
Le deuxième déclencheur est la fragmentation du déploiement. Un projet Pages est une unité de déploiement monolithique : frontend, fonctions, le tout ensemble. Lorsque vous souhaitez répartir les responsabilités entre des Workers spécialisés (un pour l'API publique, un pour le traitement interne, un pour les webhooks), Pages n'offre pas cette granularité. Le déploiement d'une modification dans le gestionnaire de webhooks déclenche une reconstruction de l'intégralité du frontend.
La troisième est la mise en scène avec parité de production. Les pages disposent d'environnements de production et d'aperçu, mais elles n'ont pas d'environnements nommés avec des liaisons complètement différentes. Si vous souhaitez une base de données intermédiaire D1 complètement distincte de celle de production, avec des variables d'environnement différentes et peut-être même un modèle KV différent, la solution dans Pages consiste à créer un projet Pages distinct et à gérer la synchronisation manuellement. Dans Workers, c'est en wrangler.toml avec les blocs [env.staging] et [env.production].
Ce que vous perdez lorsque vous quittez Pages
Avant de migrer, le calcul correct consiste à répertorier les offres Pages que vous devrez remplacer.
Le pipeline de build est l’élément le plus sous-estimé. Pages se connecte au référentiel, détecte le framework, exécute la build et télécharge les ressources. Dans Workers, vous assumez cette responsabilité : posséder CI/CD (GitHub Actions, GitLab CI, peu importe), créer un script et télécharger des actifs sur R2 si vous avez toujours besoin de servir des fichiers statiques.
Les déploiements en aperçu par branche constituent le deuxième élément. Pages génère automatiquement une URL d'aperçu pour chaque branche : push, URL disponible, commentaire sur PR. La réplication de cela dans Workers nécessite du travail : un script CI qui détecte le nom de la branche, se déploie avec un nom de Worker dérivé de la branche (minha-api-pr-247) et commente l'URL dans le PR via l'API GitHub. Cela fonctionne, mais c'est du code infra que vous écrivez et maintenez.
Le troisième élément est le CDN pour les actifs statiques. C’est le plus coûteux à ignorer.
Le compte des actifs statiques
Dans Pages, les ressources statiques (HTML, CSS, JS, images) sont servies directement à partir du CDN Cloudflare sans déclencher le runtime Workers. Chaque demande d'actif statique coûte 0 $ par demande, quel que soit le volume.
Dans Workers, vous n’avez pas cette primitive nativement. Pour servir les actifs, vous avez besoin de R2 (stockage d'objets) et d'une logique dans le Worker qui recherche l'actif correct, applique les en-têtes de cache et renvoie le contenu. Chaque requête qui transite par le runtime compte comme un appel de Worker.
Le plan payant pour les travailleurs comprend 10 millions de demandes par mois et facture 0,30 $ par million au-delà. Un site web avec 100 millions de requêtes mensuelles, dont 90 millions pour des actifs statiques : sur Pages, le coût de la requête est de 0$. Dans Workers, il y a 90 millions d'invocations au-dessus du forfait inclus, soit 27 $/mois pour ce seul delta, augmentant linéairement avec le trafic.
Pour un site web avec 500 millions de requêtes mensuelles avec 85% d'actifs statiques : la différence s'élève à plus de 120$/mois. Le coût du forfait Pages pro est de 20 $/mois. Dans ce scénario, migrer vers Workers est une décision qui augmente les coûts opérationnels en échange de flexibilité.
Le wrangler.toml pour servir les actifs R2
Si la migration a du sens malgré le coût, le modèle correct pour servir les actifs statiques dans Workers utilise R2 avec l'API Cache :
# wrangler.toml name = "meu-site" main = "src/index.ts" compatibility_date = "2024-09-24" [[r2_buckets]] binding = "ASSETS" bucket_name = "meu-site-assets" [[routes]] pattern = "meusite.com/*" zone_name = "meusite.com"
// src/index.ts export default { async fetch(request: Request, env: Env): Promise<Response> { const cache = caches.default; const cached = await cache.match(request); if (cached) return cached; const url = new URL(request.url); const key = url.pathname.slice(1) || "index.html"; const object = await env.ASSETS.get(key); if (!object) { return new Response("Not Found", { status: 404 }); } const response = new Response(object.body, { headers: { "Content-Type": object.httpMetadata?.contentType ?? "application/octet-stream", "Cache-Control": "public, max-age=31536000, immutable", }, }); await cache.put(request, response.clone()); return response; }, };
Cela reproduit le comportement CDN de Pages, mais vous payez pour chaque échec de cache (première requête par fichier par Cloudflare PoP). Le CDN Pages dispose de cette couche de mise en cache sans frais supplémentaires par requête.
Comment migrer sans temps d'arrêt
La séquence la moins risquée : tout d’abord, maintenir le projet Pages en cours d’exécution. Créez de nouveaux Workers en parallèle. Configurez les routes qui envoient le trafic aux nouveaux Workers pour des chemins spécifiques (en commençant par ceux qui présentent le risque le plus faible, tels que les webhooks ou les routes d'administration). Validez le comportement en production avec du trafic réel avant de déplacer les chemins principaux. Ensuite seulement, désactivez les fonctions Pages correspondantes.
Pour le frontend, ne migrez pas les ressources Pages vers R2 tant que vous n'êtes pas sûr que le coût supplémentaire est conforme au budget du projet. Dans de nombreux cas, l'architecture hybride (Pages pour le frontend et les actifs, Workers pour les tâches asynchrones et les services spécialisés) est moins chère et tout aussi flexible qu'une migration complète.
Ce que la migration résout réellement
Déclencheurs Cron, plusieurs Workers avec routage granulaire, staging avec des environnements complètement isolés : tels sont les vrais problèmes qui justifient la migration. Si vous migrez pour une autre raison, il vaut la peine de vérifier que vous n'échangez pas une limitation contre un coût plus élevé.
La flexibilité des travailleurs a un prix opérationnel concret : vous assumez le pipeline CI, le déploiement préliminaire et le coût de service des actifs statiques. Pour les services backend purs sans actifs significatifs, ce coût est faible. Pour les applications avec une interface lourde et un volume de trafic statique élevé, cela peut être substantiel.
A lire aussi
- Cloudflare Workers vs Pages : la différence qui compte avant de choisir
- Ce que font seuls les travailleurs, ce que font seuls les pages et où les deux se rencontrent -Workers et Pages : déploiement, routage et ce que cache chaque modèle
- Fonctions Pages : quand utiliser à la place de purs Workers
- Quand les objets durables ne sont pas la bonne réponse
- DNS proxy vs DNS uniquement : ce qui change et quand chaque mode a du sens
