McMaster-fast (rápido como McMaster)
Haz que otros sitios se sientan como mcmaster.com: la primera pintura en decenas de milisegundos, la siguiente página antes de que la barra de direcciones se actualice.
El stack no importa. McMaster hace esto con ASP.NET, YUI y un ScriptCombiner. Lo que importa son el orden y la cantidad de solicitudes. La moda de los frameworks no importa.
Lo que realmente hacen
Observado en el sitio en vivo (2026-09-13) más el desglose de Wes Bos (notas de klinke.studio):
| Capa | Lo que McMaster hace | Por qué se siente instantáneo |
|---|---|---|
| Primer byte | HTML renderizado en servidor. El navegador pinta antes del JS. FCP ~64 ms, TTFB ~19 ms en un shell cálido. | El usuario ve una página, no un spinner esperando un bundle. |
| Shell | #ShellLayout_Cntnr + #MainContent. El encabezado/carrito permanecen montados. history.pushState. | El clic en una categoría mantiene el mismo nodo de encabezado e intercambia el contenido en 35 ms. |
| Predecir | El hover/intención obtiene el siguiente HTML antes del clic. | El clic es un acierto de caché + intercambio de DOM. |
| Visita repetida | Service worker (cache first) para navegaciones GET (no PDF). La caché mantiene / después de la primera carga. | El HTML de origen es ~200 ms (mc-turn); el SW lo sirve localmente. |
| Cascada | dns-prefetch para hosts de imágenes. preload para fuentes woff2, logo, sprites LCP, JS/CSS de página, ShellDynamic.aspx. | El navegador comienza a descargar fuentes/LCP antes de descubrirlos en CSS. |
| CSS | ~32 KB de CSS común inline en <style> en <head>. El resto mediante un combinador específico de página. | El primer layout no necesita ninguna solicitud adicional de CSS. |
| JS | Bundles de ScriptCombiner específicos de página (?files=…). Asíncronos. Los WebParts se cargan después de la pintura. | La página de catálogo no descarga código del checkout. |
| Assets | URLs versionadas (/mv1789156784/, ?ver=). Cache-Control: public,immutable,max-age=31536000. Host de imágenes images1.mcmaster.com. Sprites para cuadrículas de mosaicos. | Caché de un año, sin baile de invalidación, pocas solicitudes. |
| Estabilidad | Cajas reservadas / sprites. CLS medido: 0. | Sin reflow mientras llegan las imágenes. |
| Peso | Analíticas propias (/trk/). Sin anuncios. CSP bloqueado a *.mcmaster.com. | La página es el producto. |
Los documentos HTML en sí mismos tienen Cache-Control: no-cache y x-check-cacheable: NO en Akamai. No copies "CDN-cache all HTML". Ellos almacenan en caché el shell en el navegador y archivos estáticos inmutables en el borde.
Escalera de prioridades
Detente en el primer peldaño que logre que la página tenga un LCP por debajo de ~200 ms en caché cálida. No instales Workbox, un pipeline de sprites y Reglas de Especulación en un solo PR.
- Envía HTML que el navegador pueda pintar. SSR o HTML estático. Sin renderizado solo del cliente para la primera vista. Elimina el JS que construye la primera pantalla.
- Desbloquea la primera pintura. Pon inline solo el CSS sobre el pliegue (o una hoja bloqueante pequeña).
preloadla imagen LCP y las fuentes woff2 (crossorigin).width/height(o aspect-ratio en CSS) en cada imagen. - Archivos estáticos inmutables. Hash o consulta de versión.
Cache-Control: public, immutable, max-age=31536000. - Chrome persistente + intercambio de contenido. Layout compartido. La siguiente navegación reemplaza un nodo de contenido y hace
pushState. No remontes el encabezado. - Prefetch por intención. Especulación del siguiente documento al hacer hover / al entrar en viewport. Pon un límite. Nunca hagas prefetch del checkout, APIs de búsqueda o HTML autenticado.
- Service worker de navegación (opcional). Cache first para navegaciones GET del shell/página principal pública. Limpia al desplegar. Invalida desde la página, no con un SW ingenioso. Sáltalo si el sitio es mayoritariamente privado.
- JavaScript específico de página. División por rutas. Aplaza las analíticas hasta que el navegador esté inactivo. Elimina etiquetas de terceros que no sean el producto.
- Sprites / host de imágenes solo si tienes docenas de iconos pequeños en una misma vista. HTTP/2 + unas pocas imágenes comprimidas es suficiente por debajo de eso.
Flujo de trabajo del agente
Cuando se te pida hacer que un sitio sea rápido de esta manera:
- Traza la primera carga real y una navegación dentro de la aplicación (red + lo que pinta). Nombra el elemento LCP actual y el JS que lo bloquea.
- Aplica el peldaño más bajo de la escalera que falte. Un cambio por pase a menos que el usuario haya pedido una revisión completa.
- Prefiere las características de plataforma ya presentes en el repositorio (Next
<Link>,next/font, layouts de App Router) sobre nuevas librerías. - Después de un pase, deja una comprobación: números de LCP / FCP, o una pequeña aserción de que el nodo shell se reutiliza en una navegación del cliente.
- Lee techniques.md para la receta exacta del peldaño que estás implementando. Lee recipes.md para las equivalencias en Next.js / vanilla / SPA existente.
Reglas estrictas
- HTML es el producto. JS es una mejora opcional.
- El prefetch es una pista, no un rastreador. Solo documentos GET del mismo origen.
- El HTML personalizado debe ser
no-storeo solo SW con un TTL corto. Nunca pongas HTML del carrito/cuenta en una caché CDN compartida. - No agregues un service worker que intercepte todos los assets. Solo documentos de navegación, igualando el
ServiceWorkerJS.aspxde McMaster. - No copies YUI, sprites ni ASP.NET. Copia el orden de operaciones.
- No "modernices" una página HTML rápida convirtiéndola en un SPA del cliente como solución.
- Los scripts de terceros (anuncios, gestores de etiquetas, chat) se presumen culpables. Mantenlos fuera de la primera pintura o elimínalos.
- Marca los atajos con
ponytail:cuando te saltes un peldaño de bajo valor.
Listo cuando
- Primera visita: el HTML se pinta antes de que se ejecute cualquier bundle de la aplicación. LCP es un elemento enviado por el servidor, no renderizado por el cliente.
- Siguiente clic: el chrome permanece montado; solo se intercambia la región de contenido.
- Visita repetida a la página principal/shell: se sirve localmente o desde la caché de memoria.
- Las fuentes y la imagen LCP están en los primeros 1–2 viajes de ida y vuelta, no se descubren después del CSS.
- CLS se mantiene cerca de 0 en las páginas que tocaste.