Frontend
PWA
``
Definición y Propósito
Una PWA (Progressive Web App) es una aplicación web que emplea capacidades modernas del navegador para ofrecer experiencias similares a las aplicaciones nativas, manteniendo la accesibilidad universal de la web.
Preserva el despliegue vía URL, pero añade capacidades offline, instalación, rendimiento mejorado y acceso parcial a APIs del dispositivo.
Enlaces base:
- PWA (aplicación web progresiva) Requisitos Mínimos Appy Pie
- Progressive web apps MDN-Progressive_web_apps
Características Fundamentales (core)
- Progresiva
- Funciona en cualquier navegador y mejora con capacidades disponibles.
- Responsiva
- Adaptable a cualquier tamaño de pantalla y densidad.
- App-like
- Se comporta como una app nativa: sin chrome del navegador, navegabilidad fluida, transiciones.
- Conectividad resiliente
- Funciona offline o con mala red usando Service Workers.
- Actualizable
- Descarga actualizaciones en segundo plano.
- Segura (HTTPS)
- Requiere contexto seguro para la mayoría de APIs y para registrar el Service Worker.
- Descubrible
- El
manifest.jsonpermite a los buscadores identificar la app.
- El
- Instalable
- Permite añadir al home screen y ejecutarse en standalone.
- Linkable
- Accesible por URL sin instalaciones.
Componentes Esenciales de una PWA
- Service Worker
- Script que corre en segundo plano y gestiona:
- Caché offline.
- Estrategias de fetch.
- Sincronización en segundo plano.
- Push notifications.
- Es el corazón de la experiencia offline y de rendimiento.
- Script que corre en segundo plano y gestiona:
- Web App Manifest
- Archivo JSON que define:
- Nombre, descripciones.
- Iconos.
display,theme_color,background_color.- Scope y start_url.
- Archivo JSON que define:
- HTTPS
- Obligatorio para poder registrar service workers y usar la mayoría de APIs modernas.
- Estrategias de Caché
cache-first,network-first,stale-while-revalidate,network-only,cache-only.- Cada ruta o recurso puede tener una estrategia específica según su criticidad.
Arquitectura Básica
- Capa de presentación
- HTML/CSS/JS, frameworks (React, Svelte, Lit, Solid, Vue…).
- Capa de runtime (SW)
- Intercepta requests y coordina cachés.
- Capa de contenido
- Servidor HTTP, endpoints, APIs REST/GraphQL, WebSockets, Assets.
Requisitos Mínimos (normativos)
- Servir la app vía HTTPS.
- Incluir un manifest.json válido.
- Registrar un Service Worker funcional.
- Debe existir un evento fetch operativo.
- Debe proporcionar iconos en varias resoluciones.
- Debe mostrar comportamiento offline mínimo (aunque sea una pantalla fallback).
- Debe respetar performance básico (carga inicial razonable, evitar bloqueo del main thread).
Ventajas Clave
- Distribución sin tiendas de apps.
- Actualizaciones sin fricción.
- Tamaño reducido y mayores tasas de conversión.
- Comodidad para SEO, deep linking y compartir.
- Ahorro de costes: un código para web y “app”.
Limitaciones
- Soporte desigual entre navegadores (especialmente ciertas APIs en iOS).
- Acceso limitado a APIs del dispositivo comparado con apps nativas.
- Restricciones en background execution.
- Menos control sobre instalación comparado con tiendas nativas.
APIs Relacionadas (nivel 2025)
- Web Push
- Soporte más estable en iOS desde 2024.
- Background Sync / Periodic Sync
- Sincronización confiable cuando vuelve la red.
- File System Access API
- Acceso estructurado al sistema de archivos.
- Badging API
- Badges en el icono instalado.
- Screen Wake Lock API
- Evitar que la pantalla se apague.
- Web Share / Web Share Target
- Compartir desde y hacia la PWA.
- Media Session API
- Control multimedia desde SO.
- Credential Management / WebAuthn
- Autenticación moderna y segura.
- Background Fetch API
- Descargas largas fuera de la interfaz.
Mejores Prácticas
- Cargar JavaScript dividido (code-splitting).
- Reducir render blocking.
- Usar
async/defer. - Imágenes optimizadas (AVIF, WebP).
- Pre-caché de assets críticos.
- Caché diferenciada por tipo de recurso.
- Control estricto de versiones del SW.
- Logs mínimos dentro del Service Worker.
Manifest.json (ejemplo)
{
"name": "Mi PWA",
"short_name": "PWA",
"start_url": "/",
"display": "standalone",
"background_color": "#ffffff",
"theme_color": "#0d6efd",
"icons": [
{
"src": "/icons/icon-192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/icons/icon-512.png",
"sizes": "512x512",
"type": "image/png"
}
]
}
`
Registro del Service Worker (ejemplo)
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js')
.then(() => console.log('SW registrado'))
.catch(err => console.error('Error SW', err));
}
Service Worker Básico (ejemplo)
self.addEventListener('install', event => {
event.waitUntil(
caches.open('v1').then(cache => cache.addAll([
'/',
'/index.html',
'/styles.css',
'/app.js'
]))
);
});
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request).then(resp => resp || fetch(event.request))
);
});
Estrategias de Caché (ejemplos)
Cache First
event.respondWith(
caches.match(event.request).then(cacheRes => {
return cacheRes || fetch(event.request);
})
);
Network First
event.respondWith(
fetch(event.request)
.then(networkRes => {
caches.open('dynamic').then(cache => cache.put(event.request, networkRes.clone()));
return networkRes;
})
.catch(() => caches.match(event.request))
);
Stale While Revalidate
event.respondWith(
caches.match(event.request).then(cacheRes => {
const fetchPromise = fetch(event.request).then(networkRes => {
caches.open('dynamic').then(cache => cache.put(event.request, networkRes.clone()));
return networkRes;
});
return cacheRes || fetchPromise;
})
);
Testing y Auditorías
- Lighthouse / PageSpeed
- Auditar performance, PWA y accesibilidad.
- Workbox DevTools
- Monitorización de estrategias de caché.
- Chrome Application Panel
- Ver SW, manifest, storage y cachés.
Patrón de Arquitectura recomendado
- App SPA/MPA híbrida con precarga selectiva.
- Workbox para gestionar caché y rutas.
- Contenido crítico prerenderizado o server-side rendering.
- Actualización suave del Service Worker (
skipWaitingcontrolado +clientsClaimopcional). - Notificación de nueva versión al usuario.
Guía de despliegue
- Forzar HTTPS (Nginx/Cloudflare).
- Versión del SW vinculada al bundle (hash).
- purge de iconos viejos.
manifest.jsonaccesible en/manifest.json.service-worker.jsen la raíz para scope completo (o ajustar el scope explícitamente).- Verificar
display: standaloney tamaños de iconos.
PWA — Conceptos Avanzados y Arquitectura (2025)
Objetivo de esta nota
Extender la información previa incorporando conceptos avanzados, patrones arquitectónicos modernos y nuevas APIs sin repetir lo ya documentado.
Nuevos Conceptos Clave (2025)
- Islas de Interactividad (Islands Architecture) para PWAs
- Técnica donde solo partes interactivas de la página hidratan en el cliente, mejorando rendimiento.
- Ideal para PWAs con SSR + reactividad granular.
- Prerendering + Streaming SSR
- El servidor envía HTML por streaming para First Paint ultra rápido.
- Encaja con PWAs que quieren SEO y rendimiento extremo.
- Edge Rendering (CDN Functions)
- Generación de HTML en el borde (Cloudflare, Vercel, Netlify).
- Reduce TTFB global.
- App Shell Moderno
- Shell mínimo renderizado instantáneamente.
- Contenido dinámico cargado progresivamente.
- Se combina con Service Worker + prerender.
- PWA como MPA híbrida
- Varias páginas HTML con Service Worker como “pegamento”.
- Más rápido para SEO, navegación real entre páginas, sin hidratar todo.
- Instant Navigation
- Navegación precargada por heurísticas (hover, viewport).
- Usa Navigation API, prerendering y caching inteligente.
Nuevas Capacidades UX (2024–2025)
- Window Controls Overlay para PWAs instaladas
- Permite integrar controles nativos en el título de la ventana.
- URL Protocol Handlers
- La PWA puede abrir enlaces personalizados
myapp://.
- La PWA puede abrir enlaces personalizados
- Tab Management API (soporte parcial)
- Coordina múltiples pestañas de la misma PWA.
- Idle Detection API
- Detecta cuándo el usuario está ausente para sincronizaciones silenciosas.
- Launch Handler
- Control total sobre cómo se abre la PWA instalada (nueva ventana, tab existente, restauración de sesión).
Patrones de Caché Avanzados
- Rutas mixtas con Workbox Routing
- Estrategias distintas según:
- tipo de recurso (HTML, CSS, imágenes, API JSON)
- prioridad
- red disponible (Network Information API)
- Estrategias distintas según:
- Cache Warming
- Precalentamiento de cachés antes de que el usuario necesite recursos.
- Cache Versioning por Módulos
- En vez de un caché global, crear cachés por dominio funcional:
cache-html-vXcache-api-vXcache-assets-vX
- Acelera activación del SW y limpieza más simple.
- En vez de un caché global, crear cachés por dominio funcional:
- Partial Responses Cache
- Cachear respuestas parciales (streaming) para contenido reutilizable.
Nuevos Patrones de Actualización (Upgrade Flow)
- Soft-Update con UI Friendly Prompt
- El SW notifica la actualización al cliente mediante
postMessage. - La UI muestra un prompt elegante que:
- informa
- permite “Actualizar ahora”
- permite “Recordar más tarde”
- El SW notifica la actualización al cliente mediante
- Dual-SW Strategy
- Un SW activo + un SW en staging probando rutas sin afectar usuarios.
- Rollback Automático
- Detectar fallos tras activar nueva versión y restaurar versión previa desde caché segura.
Arquitectura de Datos en PWAs Avanzadas
- IndexedDB + WASM para procesamiento offline
- Análisis de datos local sin servidor.
- Replicación offline → online
- Aplicaciones que sincronizan datos como si fueran apps nativas (Notion, Figma, Obsidian modelos PWA).
- CRDTs (Conflict-free Replicated Data Types)
- Sincronización colaborativa en tiempo real sin conflictos.
- Útil para editores, notas, productividad.
- Storage Buckets (Origin Private File System)
- Organización por buckets persistentes con cuotas altas.
- Persistencia Permanente
- Solicitud de almacenamiento persistente evitando el borrado automático del navegador.
APIs Especializadas (2025)
- Local Font Access API
- Acceso a fuentes locales instaladas.
- Bluetooth / WebHID / WebUSB
- Conexión directa con hardware externo.
- Web NFC
- Comunicación con etiquetas NFC.
- Contact Picker API
- Selección de contactos del dispositivo.
- Payment Request API (avanzada)
- Pagos integrados con proveedores nativos.
- Digital Credentials / Passkeys PWA
- Autenticación de alto nivel para apps sin password.
- Launch Queue API
- Gestión de archivos abiertos mediante la PWA instalada.
Seguridad y Privacidad
- COOP / COEP / CORP
- Aislamiento contra ataques de cross-origin resource sharing.
- Sandboxing del SW
- Separación de ámbitos: no acceso al DOM.
- Restricciones de lectura cruzada en Storage
- Cada origen tiene su espacio aislado.
- Secure Context Only APIs
- La mayoría de APIs avanzadas requieren HTTPS y permisos explícitos.
Auditorías ampliadas
- Web Vitals NWB (Next Web Benchmarks)
- Métricas modernas: INP, TTFB, CLS, Smoothness.
- Real User Monitoring (RUM)
- Instrumentación directo en la PWA para medir latencia real.
- Tracing en Edge Logs
- Permite detectar problemas en serverless/edge que afectan a la PWA.
Nuevas Herramientas del Ecosistema PWA
- Workbox v7+
- Mejor routing, estrategias predefinidas, background sync y precaching declarativo.
- VitePWA / @vite-pwa/plugin
- Generación automática de manifest, SW, precache.
- SvelteKit / Next.js / Astro con PWA opt-in
- Integración nativa para generar SW + manifest.
- PWABuilder (2025)
- Empaquetado a tiendas (Microsoft Store, Play Store Web Apps, Meta Quest Web Apps).
- WebContainer + PWA
- Correr entornos de desarrollo dentro de una PWA offline.
Casos de Uso Avanzados
- PWA como IDE offline
- PWA como cliente de sincronización
- PWA como lector offline masivo (PDFs, docs, multimedia)
- PWA industriales
- Conexión a maquinaria vía WebHID/USB/Bluetooth.
- PWAs instaladas como aplicaciones de escritorio
- Con Window Controls Overlay + File Handling.
Servicio Worker Avanzado — Ejemplo Modular
import { registerRoute } from 'workbox-routing'
import { NetworkFirst, StaleWhileRevalidate, CacheFirst } from 'workbox-strategies'
import { ExpirationPlugin } from 'workbox-expiration'
// HTML → Network First para contenido fresco
registerRoute(
({ request }) => request.destination === 'document',
new NetworkFirst({
cacheName: 'html',
networkTimeoutSeconds: 3
})
)
// CSS/JS → Stale-While-Revalidate
registerRoute(
({ request }) => request.destination === 'script' || request.destination === 'style',
new StaleWhileRevalidate({
cacheName: 'static-assets'
})
)
// Imágenes → Cache First + expiración
registerRoute(
({ request }) => request.destination === 'image',
new CacheFirst({
cacheName: 'images',
plugins: [
new ExpirationPlugin({
maxEntries: 100,
maxAgeSeconds: 60 * 60 * 24 * 30
})
]
})
)
`
Manifest Avanzado (Web App Manifest Level 2)
{
"name": "PWA Avanzada",
"short_name": "PWA-Adv",
"start_url": "/",
"display": "standalone",
"categories": ["productivity", "utilities"],
"description": "PWA moderna con capacidades avanzadas",
"launch_handler": {
"client_mode": "focus-existing"
},
"file_handlers": [
{
"action": "/open-file",
"accept": {
"text/plain": [".txt"],
"application/json": [".json"]
}
}
],
"protocol_handlers": [
{
"protocol": "myapp",
"url": "/handler?url=%s"
}
]
}
¿Te gusta este contenido? Suscríbete vía RSS