Pular para o conteúdo
~/.primo-academy.sh
☰ Aulas · Edge Deploy Frontend: build, runtime, Cloudflare Workers, Vercel Edge, image opt, preview envs, atomic deploys · 0/7
Recomendado: essencial

Vercel Edge: Edge runtime, ISR, on-demand revalidation

2 min de leitura

fonte

Voce fez deploy no Cloudflare Workers. Vercel tem a outra abordagem pra edge: integracao nativa com Next.js, ISR (revalidacao incremental), e on-demand revalidation. Esse no cobre Vercel Edge: o runtime, como configurar ISR, on-demand revalidation, e quando Vercel e' melhor escolha que Cloudflare.

Vercel e' mais usado pra Next.js: Git push → build automatico → deploy. ISR e' o diferencial: SSG + revalidacao on-demand = conteudo estatico rapido + updates sem rebuild.

Voce sai de "Workers e' edge" pra "Vercel tem edge + ISR + Next.js integrado".

O essencial 🟢

Vercel: o que e' e quando usar.

Vercel e' plataforma de deploy com integracao nativa em Next.js: git push → build → URL em segundos. Edge runtime = V8 isolate (mesmo modelo do Cloudflare Workers), mas integrado com Next.js, Vercel Functions (Node runtime), Vercel KV/Postgres/Blob (storage).

Use Vercel quando: Next.js, integracao Git, preview por PR, ISR nativo. Use Cloudflare quando: mais controle, V8 isolate puro, custo baixo, R2/KV/D1.

Next.js com ISR - o "SSG com update".

// app/products/[id]/page.tsx
export const revalidate = 3600;  // 1h
// ou revalidate = false (static, sem update)
// ou revalidate = 0 (dynamic, sempre renderiza)

export default async function ProductPage({ params }: { params: { id: string } }) {
  const product = await fetch(`https://api.example.com/products/${params.id}`)
    .then((r) => r.json());
  return <div>{product.name}</div>;
}

revalidate = tempo (segundos) ate a pagina ser revalidada no proximo request. SSG-like performance + ISR-like updates. Default em Next.js 14+ e' 0 (dynamic), use revalidate pra ISR.

On-demand revalidation - "atualiza agora, sem esperar 1h".

// app/api/revalidate/route.ts
import { revalidatePath, revalidateTag } from "next/cache";
import { NextResponse } from "next/server";

export async function POST(request: Request) {
  const { path, tag, secret } = await request.json();

  if (secret !== process.env.REVALIDATE_SECRET) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  if (path) revalidatePath(path);
  if (tag) revalidateTag(tag);

  return NextResponse.json({ revalidated: true });
}

Use: CMS publica novo conteudo → POST /api/revalidate?path=/blog/novo-post → pagina atualiza imediatamente.

revalidateTag - revalidacao granular.

// app/products/[id]/page.tsx
export default async function ProductPage({ params }: { params: { id: string } }) {
  const product = await fetch(`https://api.example.com/products/${params.id}`, {
    next: { tags: [`product-${params.id}`] },
  }).then((r) => r.json());
  return <div>{product.name}</div>;
}

// app/api/revalidate/route.ts
revalidateTag(`product-${params.id}`);  // revalida so essa pagina

Use tags pra revalidar grupo de paginas (ex: todas paginas de produto de uma categoria).

Vercel Edge Functions - codigo em edge.

// middleware.ts (roda em edge)
import { NextResponse } from "next/server";

export const config = {
  matcher: ["/api/:path*", "/((?!_next|.*\\..*).*)"],
};

export default async function middleware(request: Request) {
  const country = request.headers.get("x-vercel-ip-country") || "US";
  const url = new URL(request.url);

  // Geo-redirect
  if (country === "BR" && !url.pathname.startsWith("/br")) {
    return NextResponse.redirect(new URL(`/br${url.pathname}`, request.url));
  }

  // Auth check
  const token = request.cookies.get("session");
  if (!token && url.pathname.startsWith("/dashboard")) {
    return NextResponse.redirect(new URL("/login", request.url));
  }

  return NextResponse.next();
}

middleware.ts roda em toda request antes de chegar na rota. Edge runtime = < 5ms cold start. Use pra: auth, geo-redirect, A/B test, rate limit.

Vercel Functions (Node runtime).

// app/api/checkout/route.ts
import { NextResponse } from "next/server";

export async function POST(request: Request) {
  // Roda em Node.js (NAO edge)
  // CPU/memoria completos, sem limitacao
  const { cartId, payment } = await request.json();

  // ... logica pesada (payment, DB queries) ...

  return NextResponse.json({ success: true });
}

Use Node runtime pra: payment, heavy computation, Node APIs (fs, crypto). Edge runtime pra: auth check, A/B test, geo, light logic.

Config de runtime.

// Edge (default em middleware)
export const runtime = "edge";  // V8 isolate

// Node
export const runtime = "nodejs";  // Node.js (Vercel serverless)

Vercel KV (Redis-like).

import { kv } from "@vercel/kv";

// SET
await kv.set("user:123", { name: "Ana" });
await kv.set("user:123", value, { ex: 3600 });  // 1h TTL

// GET
const user = await kv.get("user:123");

// INCR (atomic counter)
await kv.incr("counter:page-views");

Use Vercel KV pra: session, rate limit, feature flag, cache.

Vercel Postgres.

import { sql } from "@vercel/postgres";

const { rows } = await sql`SELECT * FROM users WHERE id = ${userId}`;

Postgres serverless, 1 connection por request, scale automatica.

Vercel Blob (object storage).

import { put } from "@vercel/blob";

const { url } = await put("uploads/image.png", imageBuffer, {
  access: "public",
});

Use pra uploads, imagens, files.

Edge runtime vs Node runtime - quando usar cada.

CasoRuntime
Auth checkEdge
Geo-redirectEdge
A/B testEdge
Rate limitEdge
Light API (read, transform)Edge
PaymentNode
ML inferenceNode
WebSocket longoNode
File upload grandeNode
Node APIs (fs, child_process)Node

Edge = latencia + scale global. Node = CPU/memoria completo.

Preview deploys por PR.

# Vercel detecta PR, faz build, gera URL
# https://feat-novo-checkout-meuapp.vercel.app
# Cada PR tem URL unica

PM/tester/QA revisa visual sem checkout local. Vercel faz isso por default. Integra com GitHub PR comments: bot posta URL no PR.

Configurando ISR com Next.js 14+.

// app/blog/page.tsx
export const revalidate = 60;  // revalidar a cada 60s

// ou on-demand via API
// app/api/revalidate/route.ts
import { revalidatePath } from "next/cache";

export async function POST(req: Request) {
  const { secret, path } = await req.json();
  if (secret !== process.env.REVALIDATE_SECRET) {
    return new Response("Unauthorized", { status: 401 });
  }
  revalidatePath(path);
  return Response.json({ revalidated: true });
}

On-demand revalidation = CMS publica → POST revalida → conteudo novo no edge.

Custo de Vercel.

  • Hobby: free, 100GB bandwidth.
  • Pro: $20/seat, 1TB bandwidth.
  • Enterprise: custom.
  • Edge Functions: 500K invocations free, $2/M depois.
  • ISR: incluido.
  • KV: 30K req/dia free.
  • Postgres: 256MB free, 60h compute.

Em 2026, Vercel e' caro pra alto volume. Use Cloudflare pra $ e Vercel pra DX (Next.js).

Aprofundamento 🟡

Vercel Analytics - RUM built-in.

// app/layout.tsx
import { Analytics } from "@vercel/analytics/react";

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        {children}
        <Analytics />
      </body>
    </html>
  );
}

Vercel Analytics mede Web Vitals reais de users em prod. Free ate 100K page views/dia.

Vercel Speed Insights - similar, mais focado em performance.

Edge Config - feature flags em edge com < 1ms latency.

import { get } from "@vercel/edge-config";

const flag = await get("newCheckout");
// 0-1ms (cached at edge)

Use pra: feature flags, A/B tests, geo-targeting. < 1ms vs 50ms (KV).

ISR e revalidatePath vs revalidateTag. revalidatePath = revalida 1 path especifico. revalidateTag = revalida todas paginas com aquela tag. Use tags pra granularidade (categoria, autor, etc).

Streaming SSR com Suspense.

// app/product/[id]/page.tsx
import { Suspense } from "react";

export default function ProductPage({ params }: { params: { id: string } }) {
  return (
    <div>
      <h1>Product</h1>
      <Suspense fallback={<Skeleton />}>
        <ProductDetails id={params.id} />  {/* server component async */}
      </Suspense>
    </div>
  );
}

async function ProductDetails({ id }: { id: string }) {
  const product = await fetch(`https://api.example.com/products/${id}`).then((r) => r.json());
  return <div>{product.name}</div>;
}

Streaming SSR = HTML streamed em chunks (TTFB rapido) + Suspense pula partes lentas. App e' interativo enquanto dados chegam.

Server Actions (Next.js 14+).

// app/products/actions.ts
"use server";

export async function addToCart(productId: string) {
  // Server-side mutation
  await db.cart.add(userId, productId);
  revalidatePath("/cart");
}

Server Actions = mutations sem API route. Rodam em server, NAO em edge.

next/image automatic optimization.

import Image from "next/image";

<Image src="/hero.jpg" alt="Hero" width={1200} height={600} priority />

Next.js automaticamente: gera WebP/AVIF, lazy loads, gera srcset responsivo. Cobre image-optimization no proximo no.

Differential serving.

// next.config.js
module.exports = {
  experimental: {
    workerThreads: false,
    cpus: 1,
  },
};

Build gera diferentes bundles para Edge (minimo) e Node (full). Edge bundle = < 1MB (rapido), Node bundle = full.

Leitura recomendada:

Dica: o erro mais comum em Vercel e' misturar edge e Node runtime sem pensar. Edge = rapido mas limitado, Node = completo mas lento. Use edge pra auth, geo, A/B test (latencia < 50ms). Use Node pra payment, ML, file upload (CPU/memoria). middleware.ts e' edge by default; route handlers sao Node by default. Configure export const runtime = "edge" explicitamente. Mix inteligente = melhor DX + melhor performance.

No proximo no, vamos image optimization: Next/Image, Cloudflare Images, formato moderno (WebP, AVIF), e lazy loading pra LCP rapido.

// Quiz

O que e' ISR (Incremental Static Regeneration) e como ele combina o melhor de SSG e SSR?

Escolha uma alternativa

// recursos

// avaliação da trilha

—
ainda sem avaliações