Depurar Progressive Web Apps (PWAs): guía práctica y completa

Última actualización: 26/08/2025
Autor: Isaac
    El panel Application concentra manifiesto, service workers, cachés y almacenamiento,Controlar el ciclo de vida del SW y las estrategias de caché evita contenido obsoleto,Prueba en dispositivos reales y usa depuración remota para validar instalación,Cuida cuota, IndexedDB, rendimiento y monitorización para una PWA robusta

Depurar Progressive Web Apps PWAs Las Progressive Web Apps (PWA) combinan lo mejor de la web con sensaciones de app nativa: instalación, trabajo sin conexión, notificaciones y más. Depurarlas, eso sí, tiene sus truquillos, porque entran en juego service workers, estrategias de caché y APIs poco habituales en sitios web tradicionales.

La buena noticia es que los navegadores modernos nos dan todo lo necesario para verles las tripas: el panel Application de DevTools, emuladores, depuración remota y utilidades para manifiesto, cachés y almacenamiento. Vamos a recorrerlo todo paso a paso, con técnicas prácticas y recomendaciones para no perderse en el proceso.

Panel Application: el centro de operaciones para PWAs

El panel Application de DevTools es la navaja suiza específica para PWAs: desde aquí inspeccionas el manifiesto, controlas los service workers, miras las cachés y gestionas el almacenamiento. Es el punto de partida para inspeccionar, modificar y depurar los elementos clave que hacen especial a una PWA.

Sus secciones más relevantes para PWAs son: Manifest (para revisar el manifiesto y su instalabilidad), Service Workers (para ciclo de vida, simulaciones y estado), Cache Storage (para ver recursos cacheados) y Storage/Clear storage (para borrar registros y datos de un plumazo). En navegadores Chromium, además, puedes emular modo sin conexión y eventos clave desde aquí.

Consejo rápido: si estás probando cambios frecuentes y el service worker te juega malas pasadas, usa las opciones de Update on reload y Bypass for network para forzar actualizaciones o ignorar la caché temporalmente durante la depuración.

Herramientas Application DevTools PWA

Manifiesto web: instalación, presentación y comprobaciones finas

El manifiesto de la app web define cómo se presenta la PWA: nombre, short_name, iconos, start_url, display, colores y demás. Si lo clavas, los usuarios podrán instalar la app en Windows (Inicio), macOS (Aplicaciones) o en la pantalla de inicio de Android e iOS.

En Application > Manifest verás el estado del manifiesto, sus campos organizados en bloques de Identidad y Presentación, y la lista de Iconos con sus máscaras para comprobar áreas seguras en iconos maskable. También se muestran secciones de Protocol Handlers para probar el registro de controladores de URL, Shortcut #N con los atajos definidos y Screenshot #N para revisar capturas usadas en un diálogo de instalación enriquecido.

Instalabilidad y errores: si hay problemas (por ejemplo, un icono que no carga), aparecerá una sección de Installability con el detalle. Mantén abierta la Consola cuando dispares la instalación; te dirá en tiempo real si algo impide el flujo.

Probar la instalación en escritorio es directo con el botón Instalar en la barra de direcciones, aunque el flujo móvil real lo puedes testear con depuración remota en un dispositivo Android o iOS. En Chrome desktop, si puedes añadirla, lo normal es que en móvil también funcione.

Manifiesto PWA y comprobaciones

Service Workers: ciclo de vida, simulaciones y errores difíciles

  • Los service workers son el corazón de la PWA: se ejecutan en segundo plano, interceptan peticiones, habilitan caché, notificaciones push, sincronización en background y el modo sin conexión. Depurarlos bien es la diferencia entre una PWA ágil y una que se queda anticuada o se rompe al primer fallo.
  • Application > Service Workers es el mando central: verás el registro activo en el origen actual, su ámbito, fuente (con enlace a código), estado e identificador del worker en ejecución. Puedes pararlo o arrancarlo manualmente para simular reinicios y cazar errores por malas suposiciones de estado global.
  • Interruptores clave: Offline (pone la pestaña sin conexión, igual que en Network), Update on reload (fuerza actualización en cada carga), Bypass for network (ignora SW y va a red), y acciones como Update, Push (cosquillas push sin payload), Sync (simula eventos de sync) o Unregister (borra el registro actual). Si hay fallos, verás una insignia de Errores con acceso directo a la Consola.
  • Ver todos los registros: en Chromium, el enlace para ver todo te lleva a chrome://serviceworker-internals/?devtools, donde puedes inspeccionar en profundidad. En Edge hay opciones equivalentes y detalles de clientes y foco para saltar a la pestaña asociada.
  Qué es C:\Windows\System32\config\system y cómo solucionarlo si está dañado

Depurar service workers y ciclo de vida

Cachés, cuota y almacenamiento: evita sorpresas con los límites

  • Cache Storage muestra, en modo solo lectura, los recursos guardados con la Cache API por tu SW. Ojo, la primera vez que abres una caché y añades un recurso, DevTools puede no detectarlo al instante: recarga la página para verlo listado.
  • Uso de cuota y respuestas opacas: algunas respuestas aparecerán como «opaque» (CORS no habilitado, origen distinto, CDN). Para impedir filtrado de información, los navegadores aplican padding al tamaño reportado; en Chrome/Edge, cualquier respuesta opaca cacheada aporta un mínimo de ~7 MB al cómputo de almacenamiento. Esto puede disparar una QuotaExceeded antes de lo esperado si abusas de opacas.
  • Clear storage te permite anular el registro del service worker y limpiar todas las cachés y almacenamientos con un clic. Es mano de santo cuando quieres un estado limpio y asegurar que las siguientes pruebas no arrastran residuos.
  • Storage centraliza Local/Session Storage, IndexedDB, cookies, cuota y un botón de borrar datos. Úsalo para revisar tablas de IndexedDB, el estado de Web Storage y medir el total ocupado por tu PWA en el dispositivo.

Instalación, atajos, capturas y protocolos

  • Atajos de app (Shortcuts) acercan acciones frecuentes desde el icono instalado. En la pestaña Manifest verás cada Shortcut #N con sus datos; añade solo los que el usuario realmente usa para no sobrecargar el menú.
  • Capturas (Screenshots) enriquecen el diálogo de instalación. Revísalas en Screenshot #N para confirmar formatos, textos y que representen bien tu flujo de valor en la primera impresión.
  • Protocol Handlers registran tu PWA para manejar enlaces con un esquema propio (por ejemplo, web+algo). En Application > Manifest puedes probar un protocolo introduciendo una URL y dejando que la PWA la procese si está registrada.
  • Diagnóstico de instalación en Chromium: en Android, abre about:webapk para ver apps instaladas por WebAPK y solicitar actualizaciones; en escritorio, tienes about:apps (lista amigable) y about:app-service-internals (vista de depuración) para revisar estado y actualizaciones.

Ciclo de desarrollo: probar cambios y no pelear con la caché

  • Iteración rápida: durante el desarrollo, lo más veloz es entrar por la URL local (por ejemplo, http:\/\/localhost:8080) y recargar con F5. Cuando un SW ya cachea estáticos, puede que tus cambios no se reflejen: usa Empty cache and hard reload (clic derecho en el botón Recargar) o marca Bypass for network en Service Workers.
  • Manifiesto y reinstalación: si cambias el manifiesto, instala la PWA para validar criterios de instalabilidad. Si vuelves a modificar el manifiesto, desinstálala y reinstálala para verificar todos los cambios de forma fiable.
  • Depuración de código del SW: en Sources puedes cambiar al contexto del worker para poner breakpoints y seguir la ejecución del hilo de service worker de forma independiente a la página. Es clave para cazar errores de ciclo de vida.
  • Servicios en segundo plano: en Chromium, Application > Background Services te permite grabar eventos de push, sync y similares por encima de la API de SW para ver lo que sucede en background sin ventana activa.
  Solución: las videollamadas de WhatsApp no se activan en el iPhone

Pruebas en dispositivos, emuladores y depuración remota

  • Device Mode en DevTools permite simular tamaños de pantalla, UA y red. Útil para diseño responsivo y condiciones de red, pero no cubre del todo instalación, display-mode y atajos. Para eso, mejor ir a dispositivos o simuladores.
  • Apple Simulator (macOS con Xcode) te deja probar en iPhones y iPads reales a nivel de motor, con Safari móvil y el Web.app de PWAs. Atajos útiles: Command-Shift-H (inicio), Control-Command-Shift-H (App Switcher) y rotación con Command-Right/Left. Usar localhost ahí apunta al localhost del Mac, lo cual resulta muy cómodo.
  • Android Emulator (Android Studio) con imágenes que incluyen Play Services permite instalar Chrome y otros navegadores desde Play Store o mediante APK. Ojo, cada AVD puede ocupar 5 GB o más, y su localhost no es el de tu PC: para URLs locales, configura port forwarding desde Chromium DevTools.
  • Depuración remota: los principales navegadores soportan inspección remota. En WebKit, el Remote Inspector para Safari y PWAs instaladas en iOS/iPadOS; en Chromium, Remote Debugging para Chrome, Edge o Samsung Internet; y Firefox Remote Debugging para Android. Conecta por USB, activa la depuración y verás las páginas y apps para inspeccionar.
  • PWAs instaladas en Android se pueden depurar con las herramientas remotas de Chromium; verás el contexto de la app y podrás abrir DevTools como si fuera una pestaña, lo cual es ideal para diagnosticar problemas de instalación o SW en WebAPK.

Safari y Firefox: qué esperar en sus herramientas

Safari tiene soporte más limitado para PWA: no hay inspector de estado del SW, vista de caché ni herramientas del manifiesto e instalabilidad en iOS/iPadOS. Sí puedes abrir un inspector del SW en ejecución con Develop > Service Workers (Consola, Sources y Network). Extensiones como Service Worker Detector ayudan a suplir carencias.

Firefox soporta service workers en todas las plataformas y manifiesto para instalación en Android. En Developer Tools > Application > Service Workers puedes ver el registro, estado y anularlo, y en Application > Manifest revisar valores. En Storage gestionas IndexedDB y Cache Storage sin problemas.

Estrategias de caché, offline y actualización de contenido

Problema típico: contenido obsoleto por una estrategia cache-first mal planteada. Para recursos que cambian a menudo, valora network-first o cache-then-network, y reserva cache-first para estáticos realmente inmutables.

  Google Fi vs Canadian Carriers Comparability

Ejemplo network-first (adaptado): self.addEventListener('fetch', (event) => {\n event.respondWith(\n caches.match(event.request).then((cached) => {\n return cached || fetch(event.request).then((networkResponse) => {\n return caches.open('dynamic-cache').then((cache) => {\n cache.put(event.request, networkResponse.clone());\n return networkResponse;\n });\n });\n })\n );\n});

Offline con página de reserva: cachea una offline.html en install y úsala como fallback cuando falle fetch. Así el usuario ve un mensaje útil en vez de una pantalla en blanco. self.addEventListener('install', (event) => {\n event.waitUntil(\n caches.open('static-cache').then((cache) => cache.addAll(['/offline.html']))\n );\n});\nself.addEventListener('fetch', (event) => {\n event.respondWith(\n fetch(event.request).catch(() => caches.match('/offline.html'))\n );\n});

Actualizar el SW sin fricción: usa self.skipWaiting() en install y plantea una UX para recargar cuando haya versión nueva. Así evitas que usuarios queden con versiones antiguas hasta cerrar todas las pestañas. self.addEventListener('install', (event) => {\n self.skipWaiting();\n});

Push, Background Sync y tareas en segundo plano

Push Notifications: desde Application > Service Workers puedes emular un push sin payload para validar la UI. Asegúrate de definir icon, actions y data para enriquecer la notificación. self.addEventListener('push', (event) => {\n const options = {\n body: 'Tienes novedades',\n icon: '/images/icon.png',\n actions: [{ action: 'open', title: 'Abrir' }, { action: 'dismiss', title: 'Cerrar' }]\n };\n event.waitUntil(self.registration.showNotification('Actualización disponible', options));\n});

Permisos: solicita notificaciones en el momento adecuado y gestiona bien el «denied» sin insistir. Ofrece alternativas in-app para no molestar al usuario si no quiere notificaciones.

Background Sync: cola operaciones cuando no hay red y reintenta al reconectar. Útil para formularios offline o colas de subida. self.addEventListener('sync', (event) => {\n if (event.tag === 'sync-data') {\n event.waitUntil(syncData());\n }\n});\nfunction syncData() {\n return fetch('/api/sync', {\n method: 'POST',\n body: JSON.stringify(offlineQueue),\n headers: { 'Content-Type': 'application/json' }\n });\n}

Background Services en Chromium graban eventos en segundo plano (push, sync, etc.) para ver qué ocurre cuando no hay ventana. Es perfecto para auditar flujos que no dependen del foco de la página.

Datos grandes: IndexedDB, rendimiento y memoria

Cache Storage para estáticos y recursos críticos; para datasets grandes o contenido del usuario, vete a IndexedDB. Es asíncrono, resistente y evita topes de cuota por respuestas opacas. Organiza stores con claves claras para lecturas rápidas y fiables.

Ejemplo mínimo IndexedDB: let db;\nconst req = indexedDB.open('PWA-Data', 1);\nreq.onupgradeneeded = (e) => e.target.result.createObjectStore('dataStore');\nreq.onsuccess = (e) => { db = e.target.result; };\nfunction storeData(key, data) {\n const tx = db.transaction('dataStore', 'readwrite');\n tx.objectStore('dataStore').put(data, key);\n}

Optimiza performance: comprime imágenes, minifica CSS/JS, divide bundles (splitChunks), aplaza cargas no críticas y recorta scripts de terceros. Herramientas como Webpack facilitan empaquetado inteligente. optimization: { splitChunks: { chunks: 'all' }, minimize: true }

Memoria: vigila fugas con la pestaña Memory de DevTools; elimina listeners no usados y evita retener objetos enormes en memoria. Un simple removeEventListener a tiempo te ahorra degradaciones y cuelgues en dispositivos modestos.

Deja un comentario