Introducción

Las Aplicaciones Web Progresivas (PWAs) son aplicaciones web que utilizan tecnologías modernas para ofrecer una experiencia similar a las aplicaciones nativas. Los Service Workers son una de las tecnologías clave que permiten a las PWAs funcionar sin conexión, recibir notificaciones push y mejorar el rendimiento.

¿Qué es un Service Worker?

Un Service Worker es un script que el navegador ejecuta en segundo plano, separado de la página web. Permite interceptar y controlar las solicitudes de red, almacenar recursos en caché y manejar notificaciones push.

Características de las PWAs

  1. Responsivas: Funcionan en cualquier dispositivo y tamaño de pantalla.
  2. Conectividad Independiente: Pueden funcionar sin conexión o con conexiones de baja calidad.
  3. Actualizables: Siempre están actualizadas gracias a los Service Workers.
  4. Seguras: Se sirven a través de HTTPS para prevenir ataques de seguridad.
  5. Reenganchables: Pueden enviar notificaciones push para reenganchar a los usuarios.
  6. Instalables: Pueden ser añadidas a la pantalla de inicio del dispositivo sin necesidad de una tienda de aplicaciones.

Configuración de un Service Worker

Registro del Service Worker

Para utilizar un Service Worker, primero debes registrarlo en tu aplicación web. Esto se hace en el archivo JavaScript principal de tu aplicación.

if ('serviceWorker' in navigator) {
  window.addEventListener('load', () => {
    navigator.serviceWorker.register('/service-worker.js')
      .then(registration => {
        console.log('Service Worker registrado con éxito:', registration);
      })
      .catch(error => {
        console.log('Error al registrar el Service Worker:', error);
      });
  });
}

Instalación del Service Worker

El archivo service-worker.js contiene el código del Service Worker. Durante la fase de instalación, puedes almacenar en caché los recursos necesarios para que tu aplicación funcione sin conexión.

const CACHE_NAME = 'my-cache-v1';
const urlsToCache = [
  '/',
  '/styles/main.css',
  '/script/main.js'
];

self.addEventListener('install', event => {
  event.waitUntil(
    caches.open(CACHE_NAME)
      .then(cache => {
        console.log('Abriendo caché');
        return cache.addAll(urlsToCache);
      })
  );
});

Activación del Service Worker

Después de la instalación, el Service Worker se activa y puede gestionar las solicitudes de red.

self.addEventListener('activate', event => {
  const cacheWhitelist = [CACHE_NAME];
  event.waitUntil(
    caches.keys().then(cacheNames => {
      return Promise.all(
        cacheNames.map(cacheName => {
          if (cacheWhitelist.indexOf(cacheName) === -1) {
            return caches.delete(cacheName);
          }
        })
      );
    })
  );
});

Intercepción de Solicitudes de Red

El Service Worker puede interceptar las solicitudes de red y responder con recursos almacenados en caché.

self.addEventListener('fetch', event => {
  event.respondWith(
    caches.match(event.request)
      .then(response => {
        if (response) {
          return response;
        }
        return fetch(event.request);
      })
  );
});

Ejercicio Práctico

Ejercicio 1: Registro y Caché de Recursos

  1. Objetivo: Registrar un Service Worker y almacenar en caché los recursos de la aplicación.
  2. Instrucciones:
    • Crea un archivo service-worker.js en la raíz de tu proyecto.
    • Registra el Service Worker en tu archivo JavaScript principal.
    • En el archivo service-worker.js, almacena en caché los recursos necesarios durante la fase de instalación.

Solución:

// Archivo principal (e.g., main.js)
if ('serviceWorker' in navigator) {
  window.addEventListener('load', () => {
    navigator.serviceWorker.register('/service-worker.js')
      .then(registration => {
        console.log('Service Worker registrado con éxito:', registration);
      })
      .catch(error => {
        console.log('Error al registrar el Service Worker:', error);
      });
  });
}

// Archivo service-worker.js
const CACHE_NAME = 'my-cache-v1';
const urlsToCache = [
  '/',
  '/styles/main.css',
  '/script/main.js'
];

self.addEventListener('install', event => {
  event.waitUntil(
    caches.open(CACHE_NAME)
      .then(cache => {
        console.log('Abriendo caché');
        return cache.addAll(urlsToCache);
      })
  );
});

self.addEventListener('fetch', event => {
  event.respondWith(
    caches.match(event.request)
      .then(response => {
        if (response) {
          return response;
        }
        return fetch(event.request);
      })
  );
});

Ejercicio 2: Actualización del Caché

  1. Objetivo: Actualizar el caché cuando se despliega una nueva versión de la aplicación.
  2. Instrucciones:
    • Modifica el archivo service-worker.js para eliminar cachés antiguos durante la fase de activación.

Solución:

const CACHE_NAME = 'my-cache-v2'; // Cambia el nombre del caché para actualizarlo
const urlsToCache = [
  '/',
  '/styles/main.css',
  '/script/main.js'
];

self.addEventListener('install', event => {
  event.waitUntil(
    caches.open(CACHE_NAME)
      .then(cache => {
        console.log('Abriendo caché');
        return cache.addAll(urlsToCache);
      })
  );
});

self.addEventListener('activate', event => {
  const cacheWhitelist = [CACHE_NAME];
  event.waitUntil(
    caches.keys().then(cacheNames => {
      return Promise.all(
        cacheNames.map(cacheName => {
          if (cacheWhitelist.indexOf(cacheName) === -1) {
            return caches.delete(cacheName);
          }
        })
      );
    })
  );
});

self.addEventListener('fetch', event => {
  event.respondWith(
    caches.match(event.request)
      .then(response => {
        if (response) {
          return response;
        }
        return fetch(event.request);
      })
  );
});

Conclusión

Los Service Workers son una herramienta poderosa para mejorar la experiencia del usuario en aplicaciones web, permitiendo funcionalidades como el funcionamiento sin conexión y las notificaciones push. Las PWAs combinan lo mejor de las aplicaciones web y nativas, ofreciendo una experiencia rica y responsiva. Con la práctica y la implementación de estos conceptos, podrás crear aplicaciones web modernas y eficientes.

En el próximo módulo, exploraremos cómo utilizar la API Fetch y AJAX para realizar solicitudes de red asíncronas.

JavaScript: De Principiante a Avanzado

Módulo 1: Introducción a JavaScript

Módulo 2: Estructuras de Control

Módulo 3: Funciones

Módulo 4: Objetos y Arrays

Módulo 5: Objetos y Funciones Avanzadas

Módulo 6: El Modelo de Objetos del Documento (DOM)

Módulo 7: APIs del Navegador y Temas Avanzados

Módulo 8: Pruebas y Depuración

Módulo 9: Rendimiento y Optimización

Módulo 10: Frameworks y Librerías de JavaScript

Módulo 11: Proyecto Final

© Copyright 2024. Todos los derechos reservados