Advanced (Actualizado: 2/6/2026)

Optimización de fuentes web con Claude Code

Guía práctica para optimizar fuentes web con Claude Code: preload, font-display, subsetting, CLS/LCP y verificación.

Optimización de fuentes web con Claude Code

La optimización de fuentes es un problema de renderizado

Las fuentes web suelen tratarse como una decisión de marca, pero en producción también son una decisión de rendimiento. Una fuente lenta puede dejar el texto invisible, cambiar el ancho de un titular después de que el usuario empezó a leer, mover un botón de compra o empeorar el LCP. LCP significa Largest Contentful Paint: el tiempo hasta que se pinta el elemento de contenido más grande del primer viewport. CLS significa Cumulative Layout Shift: movimiento inesperado del layout durante la carga.

En idiomas con muchos caracteres, como japonés, chino o coreano, el problema es todavía más visible. Un solo archivo de fuente puede pesar más que todo el CSS crítico. Por eso Claude Code no debe recibir una orden vaga como “optimiza las fuentes”. Necesita una estrategia: qué fuente es crítica, qué archivo se precarga, qué texto puede usar una fuente del sistema, cómo se evita CLS y cómo se verifica con datos.

Esta guía usa un sitio Astro como ejemplo. Cubre estrategia de carga, preload, preconnect, font-display, fuentes variables, subsetting, self-host frente a proveedores externos, riesgos de CLS/LCP, revisiones estilo Lighthouse y WebPageTest, y prompts seguros para implementar con Claude Code. Para los detalles del navegador, usa la documentación oficial de MDN sobrefont-display yrel="preload". Para la visión general, consulta web.dev sobremejores prácticas de fuentes, optimización de web fonts yWeb Vitals.

Define la estrategia antes de tocar código

El primer paso es decidir qué texto merece presupuesto de red en el primer viewport. Si todo se marca como crítico, nada es realmente crítico. En un blog, el cuerpo puede empezar con fuentes del sistema y reservar la fuente de marca para titulares. En un panel SaaS, una fuente variable latina puede cubrir etiquetas, tablas y botones. En una landing page, el titular del hero y la imagen compiten por el LCP, así que no conviene precargar todos los pesos.

Caso de usoEstrategia recomendadaMotivoFallo común
Blog multilingüeCuerpo con fuente del sistema, titulares con fuente web subsetEl contenido se lee aunque la fuente tardeLa fuente decorativa termina aplicada al cuerpo
Dashboard SaaSFuente variable self-host para UIUn archivo cubre varios pesosSe incluyen cursivas, ejes o idiomas no usados
Landing pagePreload solo del WOFF2 usado por el titular LCPEl mensaje principal aparece antesTodos los pesos compiten con la imagen hero
Icon font heredadaSustituir por SVG o librería de iconosElimina una petición de fuenteSe rompe CSS con pseudo-elementos

Para decidir el orden de impacto, revisa también laguía de optimización de imágenes con Claude Code, porque imagen hero y fuente de titular suelen competir. Si el objetivo es mejorar todo el sitio, conecta este trabajo con laoptimización de performance con Claude Code.

Implementa preload y preconnect en Astro

preload es una pista fuerte para el navegador. Úsala solo para uno o dos archivos WOFF2 que se usen realmente en el primer viewport. No precargues todos los pesos ni todas las variantes idiomáticas. Si las fuentes están en tu propio origen, normalmente no necesitas preconnect. Si usas Google Fonts u otro proveedor, sí puede tener sentido preconectar con el dominio de CSS y el dominio de archivos de fuente.

---
// src/layouts/BaseLayout.astro
const criticalFonts = [
  { href: "/fonts/inter-var-latin.woff2", type: "font/woff2" },
  { href: "/fonts/noto-sans-jp-latin-kana.woff2", type: "font/woff2" },
];

const usesGoogleFonts = false;
---

<html lang="es">
  <head>
    {criticalFonts.map((font) => (
      <link rel="preload" href={font.href} as="font" type={font.type} crossorigin />
    ))}

    {usesGoogleFonts && <link rel="preconnect" href="https://fonts.googleapis.com" />}
    {usesGoogleFonts && <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />}

    <link rel="stylesheet" href="/styles/fonts.css" />
  </head>
  <body>
    <slot />
  </body>
</html>

Después de generar el HTML, comprueba tres cosas. El href del preload debe coincidir con el src de @font-face. La etiqueta debe tener as="font", type="font/woff2" y crossorigin. Además, la fuente precargada debe usarse pronto. Si Chrome indica que se precargó un recurso no utilizado, quita esa pista.

Usa font-display sin crear CLS

font-display: swap muestra primero una fuente de reserva y luego cambia a la fuente web cuando llega. Es útil para evitar texto invisible, pero puede mover el layout si las métricas no coinciden. font-display: optional puede ser mejor para texto no crítico en redes lentas, porque el navegador puede conservar la fuente de reserva.

/* public/styles/fonts.css */
@font-face {
  font-family: "InterVariable";
  src: url("/fonts/inter-var-latin.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "NotoSansJPSubset";
  src: url("/fonts/noto-sans-jp-latin-kana.woff2") format("woff2");
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+3000-30FF, U+FF00-FFEF;
}

@font-face {
  font-family: "InterFallback";
  src: local("Arial");
  size-adjust: 107%;
  ascent-override: 90%;
  descent-override: 22%;
  line-gap-override: 0%;
}

:root {
  --font-ui: "InterVariable", "InterFallback", system-ui, sans-serif;
  --font-ja: "NotoSansJPSubset", "Hiragino Sans", "Yu Gothic", sans-serif;
}

body {
  font-family: var(--font-ui);
}

article {
  font-family: var(--font-ja);
}

El descriptorunicode-range permite aplicar una fuente solo a ciertos caracteres. No reduce el archivo por sí solo. Para reducir bytes, necesitas generar un WOFF2 más pequeño.

Reduce bytes con fuentes variables y subsetting

Una fuente variable puede sustituir varios archivos estáticos cuando necesitas muchos pesos. Aun así, no siempre es más ligera. Si trae muchos ejes, cursivas y rangos de idioma que no usas, puede seguir siendo costosa. Pide a Claude Code que audite pesos reales, familias usadas y rutas CSS antes de cambiar la implementación.

El subsetting consiste en crear un archivo de fuente con solo los caracteres necesarios. Funciona muy bien para navegación, titulares hero, etiquetas fijas y CTA. Es más delicado para artículos, porque cada publicación nueva puede introducir caracteres no incluidos.

# Create a WOFF2 subset with Latin, punctuation, kana, and full-width forms.
python -m pip install "fonttools[woff]"
mkdir -p public/fonts

pyftsubset ./vendor-fonts/NotoSansJP-Regular.ttf \
  --output-file=./public/fonts/noto-sans-jp-latin-kana.woff2 \
  --flavor=woff2 \
  --layout-features='*' \
  --unicodes="U+0000-00FF,U+3000-30FF,U+FF00-FFEF"

Este ejemplo no cubre la mayoría de kanji. Sirve para navegación y titulares, no para un cuerpo de artículo japonés completo. Si quieres cubrir el cuerpo, extrae caracteres reales desde los MDX y usa --text-file, o genera un subset separado. También revisa la licencia: algunas fuentes permiten self-host, otras no permiten modificación o redistribución.

Self-host o proveedor externo

Self-host significa servir los archivos desde tu propio dominio. Ganas control sobre URLs, cache, fingerprints, preload y subsetting. A cambio, debes gestionar licencia, actualizaciones y scripts. Un proveedor externo como Google Fonts es rápido para empezar, pero añade conexiones externas y una petición CSS antes del archivo de fuente.

CriterioSelf-hostTercero
Conexión inicialMismo origenDNS, TLS, CSS externo y origen de fuente
CacheControl completoDepende del proveedor
PreloadApunta al WOFF2 exactoEl CSS puede decidir la URL
SubsettingFlexibleDepende de la API
OperaciónMás responsabilidadMás cómodo, más dependencia

Para páginas sensibles a conversión, suele ser mejor self-host para fuentes críticas y carga diferida para fuentes decorativas. En prototipos, un proveedor externo está bien si cargas solo pesos usados, usas display=swap y evitas duplicar la misma familia desde dos lugares.

Verifica con Lighthouse y una cascada estilo WebPageTest

Tras implementar, revisa el orden de red. Lighthouse da una señal de laboratorio sobre LCP, CLS y avisos de fuentes. Luego mira una cascada como harías en WebPageTest: HTML, CSS, fuente crítica, imagen hero y JavaScript. La fuente debe empezar pronto, pero no bloquear el CSS ni competir innecesariamente con el elemento LCP.

URL="https://example.com/"
npx --yes lighthouse "$URL" \
  --only-categories=performance \
  --chrome-flags="--headless" \
  --output=json \
  --output-path=./lighthouse-fonts.json

node -e "const r=require('./lighthouse-fonts.json'); for (const id of ['largest-contentful-paint','cumulative-layout-shift','font-display']) console.log(id, r.audits[id]?.displayValue ?? r.audits[id]?.score ?? 'n/a')"

Revisa estos puntos: solo una o dos fuentes críticas empiezan temprano; no hay aviso de preload no usado; la visita repetida usa cache; el titular y el CTA no se mueven durante el swap; no queda CSS de Google Fonts si ya migraste a self-host; no se descarga el mismo WOFF2 dos veces.

Los fallos típicos son concretos. Se precarga una negrita que no aparece en el primer viewport. El subset elimina signos de puntuación, dígitos de ancho completo o caracteres largos. El equipo añade font-display: swap pero no ajusta métricas de fallback. La fuente de iconos sigue cargándose aunque los iconos ya se migraron a SVG.

Prompts seguros para Claude Code

Divide el trabajo en auditoría, implementación y verificación. Empieza sin permitir edición.

Audit web font loading in this Astro site. Do not edit files yet.

Find:
- @font-face, Google Fonts, Fontsource, and CSS import locations
- Font files used above the fold
- preload and preconnect hints that are missing or unnecessary
- CLS or LCP risks caused by font swapping
- Candidates for self-hosting, variable fonts, and subsetting

Return:
- A prioritized table of changes
- Files that should be edited and files that must not be touched
- Verification commands and residual risks

Luego limita el alcance de implementación.

Implement web font optimization only in these files:
- src/layouts/BaseLayout.astro
- public/styles/fonts.css
- generated files under public/fonts/

Acceptance criteria:
- Preload only WOFF2 files used in the first viewport
- Do not add preconnect when fonts are self-hosted
- Every @font-face has a deliberate font-display value
- Fallback metrics are adjusted to reduce CLS
- Existing routes, article slugs, hero images, and unrelated content are untouched

Verification:
- npm run build
- node scripts/check-code-fences.mjs
- Lighthouse check for LCP, CLS, and font-display
- Report what could not be verified

Resultado práctico y CTA

En el flujo de Masa, la instrucción específica funcionó mejor que la genérica. “Precarga solo la fuente del titular LCP, deja el cuerpo legible con fuentes del sistema y reporta riesgo de CLS” produjo cambios pequeños y revisables. En una página japonesa, un subset latino y kana hizo más estable el primer viewport, pero cubrir todo el cuerpo exigió extracción de caracteres. La verificación más útil fue una cascada móvil lenta y una revisión manual del titular y del CTA durante el cambio de fuente.

Para llevar esto a un equipo, documenta reglas de fuentes en CLAUDE.md. Empieza con lachuleta gratuita para comandos seguros, usa lasplantillas de productos para prompts repetibles y considera laformación de Claude Code si quieres mejorar Core Web Vitals, calidad editorial y CTA de monetización al mismo tiempo.

Autochequeo antes de publicar: el artículo incluye más de tres casos de uso, ejemplos Astro/CSS/bash copiables, enlaces oficiales a MDN y web.dev, enlaces internos, errores concretos, CTA natural y nota de verificación práctica.

#Claude Code #fuentes web #Core Web Vitals #Astro #performance
Gratis

PDF gratis: cheatsheet de Claude Code

Introduce tu email y descarga una hoja con comandos, hábitos de revisión y flujos seguros.

Cuidamos tus datos y no enviamos spam.

Masa

Sobre el autor

Masa

Ingeniero enfocado en workflows prácticos con Claude Code.