Convertir a un trabajador de servicios: un estudio de caso

 

 

 

  • ¡Registro!
  • Diseño de arquitectura de componentes de interfaz de usuario y tokens, con Nathan Curtis

  • Índice
    1. ¿Qué es un trabajador de servicios?
    2. Algunos conceptos básicos de trabajadores de servicios
      1. Registrar a un trabajador de servicios
      2. Ciclo de vida y eventos del trabajador de servicio
      3. La API basada en promesas del trabajador del servicio
      4. Otras necesidades de los trabajadores de servicios
    3. Registro, instalación y activación de un trabajador de servicio
      1. Registrar a nuestro trabajador de servicio
      2. Almacenamiento previo en caché de activos estáticos durante la instalación
    4. Confusiones de consola
      1. Registro obsoleto
      2. Un error cuando todo va bien
    5. Lo que hemos logrado hasta ahora
    6. Manejo de recuperación con trabajadores de servicio
      1. ¿Deberíamos encargarnos de esta recuperación?
      2. ¿Por qué no utilizar promesas?
      3. Criterios para solicitudes válidas
      4. ¿Por qué incluirse en la lista blanca?
    7. Escribir el controlador de recuperación
      1. 1. ¿Qué tipo de recurso se solicita?
      2. 2. Responder a la búsqueda
      3. ¡Cuidado con Async!
    8. Contenido HTML: implementación de una estrategia centrada en la red
      1. 1. Intente buscar en la red
      2. 2. Intente recuperar desde la caché
      3. 3. Proporcionar un recurso alternativo sin conexión

    Los trabajadores de servicios hacen muchas cosas diferentes; Hay innumerables formas de aprovechar sus poderes. En este artículo, Lyza Danger Gardner explica qué es un trabajador de servicio y cómo crear uno propio registrándolo, instalándolo y activándolo sin ningún problema. Decidió crear un trabajador de servicio simple para su sitio web que refleje aproximadamente las funciones (proporcionar una experiencia alternativa fuera de línea personalizada, hacer que el sitio web funcione sin conexión y aumentar el rendimiento en línea al reducir las solicitudes de red para ciertos activos) que la obsoleta API de caché de aplicaciones solía proporcionar.

     

    No faltan entusiasmo ni entusiasmo por la incipiente API de trabajador de servicio , que ahora se incluye en algunos navegadores populares . Hay libros de cocina y publicaciones de blogs, fragmentos de código y herramientas. Pero encuentro que cuando quiero aprender a fondo un nuevo concepto web, lo ideal suele ser arremangarme, sumergirme y construir algo desde cero.

    Los golpes y magulladuras, trampas y errores que encontré esta vez tienen beneficios: ahora entiendo mucho mejor a los trabajadores de servicios y, con un poco de suerte, puedo ayudarlos a evitar algunos de los dolores de cabeza que encontré al trabajar con la nueva API.

    Los trabajadores de servicios hacen muchas cosas diferentes ; Hay innumerables formas de aprovechar sus poderes. Decidí crear un trabajador de servicio simple para mi sitio web (estático, sin complicaciones) que refleje aproximadamente las características que solía proporcionar la obsoleta API de caché de aplicaciones, es decir:

    • hacer que el sitio web funcione sin conexión,
    • aumentar el rendimiento en línea al reducir las solicitudes de red para ciertos activos,
    • Proporcionar una experiencia alternativa fuera de línea personalizada.

    Antes de comenzar, me gustaría agradecer a dos personas cuyo trabajo hizo esto posible. En primer lugar, estoy enormemente en deuda con Jeremy Keith por la implementación de los trabajadores de servicio en su propio sitio web, que sirvió como punto de partida para mi propio código. Me inspiré en su publicación reciente que describe sus experiencias actuales como trabajador de servicios. De hecho, mi trabajo es tan derivado que no habría escrito sobre él de no ser por la exhortación de Jeremy en una publicación anterior :

     

    "Entonces, si decide jugar con Service Workers, comparta su experiencia".

    En segundo lugar, muchas gracias a Jake Archibald por su excelente revisión técnica y comentarios. ¡Siempre es agradable cuando uno de los creadores y evangelistas de la especificación del trabajador de servicio puede aclararlo!

    ¿Qué es un trabajador de servicios?

    Un trabajador de servicio es un script que se interpone entre su sitio web y la red , brindándole, entre otras cosas, la capacidad de interceptar solicitudes de red y responder a ellas de diferentes maneras.

    Para que su sitio web o aplicación funcione, el navegador recupera sus activos, como páginas HTML, JavaScript, imágenes y fuentes. En el pasado, la gestión de esto era principalmente prerrogativa del navegador. Si el navegador no pudiera acceder a la red, probablemente verías el mensaje "Oye, estás desconectado". Había técnicas que se podían utilizar para fomentar el almacenamiento en caché local de activos, pero el navegador a menudo tenía la última palabra.

    Esta no fue una gran experiencia para los usuarios que estaban desconectados y dejó a los desarrolladores web con poco control sobre el almacenamiento en caché del navegador.

    Cue Application Cache (o AppCache), cuya llegada hace varios años parecía prometedora. Aparentemente, le permite dictar cómo se deben manejar los diferentes activos, para que su sitio web o aplicación pueda funcionar sin conexión. Sin embargo, la sintaxis aparentemente simple de AppCache contradecía su naturaleza confusa subyacente y su falta de flexibilidad .

    La incipiente API de trabajador de servicio puede hacer lo que hizo AppCache y mucho más. Pero al principio parece un poco intimidante. Las especificaciones generan una lectura pesada y abstracta, y numerosas API están subordinadas a ellas o relacionadas de alguna otra manera: cache, fetch, etc. Los trabajadores de servicios abarcan muchas funciones: notificaciones automáticas y, pronto, sincronización en segundo plano. Comparado con AppCache, parece... complicado.

    Mientras que AppCache (que, por cierto, está desapareciendo ) fue fácil de aprender pero terrible en cada momento posterior (en mi opinión), los trabajadores de servicios son más bien una inversión cognitiva inicial, pero son potentes y útiles, y puedes Generalmente sal de un problema si rompes cosas.

     

    Algunos conceptos básicos de trabajadores de servicios

    Un trabajador de servicio es un archivo que contiene algo de JavaScript. En ese archivo puedes escribir JavaScript como lo conoces y te encanta, con algunas cosas importantes a tener en cuenta.

    Los scripts de los trabajadores del servicio se ejecutan en un hilo separado en el navegador de las páginas que controlan. Hay formas de comunicarse entre trabajadores y páginas, pero se ejecutan en un ámbito separado . Eso significa que no tendrás acceso al DOM de esas páginas, por ejemplo. Visualizo a un trabajador de servicio ejecutándose en una pestaña separada de la página a la que afecta; Esto no es del todo exacto, pero es una metáfora aproximada y útil para no caer en la confusión.

    JavaScript en un trabajador de servicio no debe bloquearse. Necesita utilizar API asincrónicas. Por ejemplo, no se puede utilizar localStorageen un trabajador de servicio ( localStoragees una API sincrónica). Curiosamente, incluso sabiendo esto, corrí el riesgo de violarlo, como veremos.

    Registrar a un trabajador de servicios

    Usted hace que un trabajador de servicio entre en vigor registrándolo. Este registro se realiza desde fuera del trabajador del servicio, mediante otra página o script en su sitio web. En mi sitio web, site.jsse incluye un script global en cada página HTML. Registro a mi trabajador de servicio desde allí.

    Cuando registra a un trabajador de servicios, (opcionalmente) también le indica a qué ámbito debe aplicarse. Puede indicarle a un trabajador de servicio que solo maneje cosas de parte de su sitio web (por ejemplo, ’/blog/’) o puede registrarlo para todo su sitio web ( ’/’) como lo hago yo.

    Ciclo de vida y eventos del trabajador de servicio

    Un trabajador de servicios realiza la mayor parte de su trabajo escuchando eventos relevantes y respondiendo a ellos de manera útil . Se desencadenan diferentes eventos en diferentes puntos del ciclo de vida de un trabajador de servicios.

    Una vez que el trabajador del servicio se ha registrado y descargado, se instala en segundo plano. Su trabajador de servicio puede escuchar el installevento y realizar tareas apropiadas para esta etapa.

    En nuestro caso, queremos aprovechar el installestado para almacenar en caché previamente un conjunto de recursos que sabemos que querremos disponibles sin conexión más adelante.

    installUna vez finalizada la etapa, se activa el trabajador de servicio . Eso significa que el trabajador del servicio ahora tiene el control de las cosas dentro de él scopey puede hacer lo suyo. El activateevento no es demasiado emocionante para un nuevo trabajador de servicio, pero veremos qué tan útil es al actualizar un trabajador de servicio con una nueva versión.

    El momento exacto en que se produce la activación depende de si se trata de un trabajador de servicio nuevo o de una versión actualizada de un trabajador de servicio preexistente. Si el navegador no tiene registrada una versión anterior de un trabajador de servicio determinado, la activación se producirá inmediatamente después de que se complete la instalación.

     

    Una vez que se completen la instalación y activación, no volverán a ocurrir hasta que se descargue y registre una versión actualizada del trabajador del servicio.

    Más allá de la instalación y activación, nos centraremos principalmente en el fetchevento de hoy para que nuestro trabajador de servicio sea útil. Pero hay varios eventos útiles más allá de eso: eventos de sincronización y eventos de notificación , por ejemplo.

    Para obtener crédito adicional o diversión de ocio, puede leer más sobre las interfaces que implementan los trabajadores de servicios . Es mediante la implementación de estas interfaces que los trabajadores del servicio obtienen la mayor parte de sus eventos y gran parte de su funcionalidad extendida.

    La API basada en promesas del trabajador del servicio

    La API del trabajador de servicio hace un uso intensivo de Promises. Una promesa representa el resultado final de una operación asincrónica, incluso si el valor real no se conocerá hasta que la operación se complete en algún momento en el futuro.

    getAnAnswerToADifficultQuestionSomewhereFarAway() .then(answer = { console.log('I got the ${answer}!'); }) .catch(reason = { console.log('I tried to figure it out but couldn't because ${reason}');});

    La getAnAnswer…función devuelve un valor Promiseque (esperamos) eventualmente será cumplido o resuelto por lo que answerestamos buscando. Luego, eso answerse puede alimentar a cualquier thenfunción de controlador encadenada o, en el lamentable caso de que no se logre su objetivo, se Promisepuede rechazar (a menudo con una razón) y catchlas funciones de controlador pueden encargarse de estas situaciones.

    Hay más promesas, pero intentaré que los ejemplos aquí sean sencillos (o al menos comentados). Le insto a que realice una lectura informativa si es nuevo en las promesas.

    Nota : utilizo ciertas funciones ECMAScript6 (o ES2015) en el código de muestra para trabajadores de servicios porque los navegadores que admiten trabajadores de servicios también admiten estas funciones. Específicamente aquí, estoy usando funciones de flecha y cadenas de plantilla .

    Otras necesidades de los trabajadores de servicios

    Además, tenga en cuenta que los trabajadores del servicio requieren HTTPS para funcionar. Hay una excepción importante y útil a esta regla: los trabajadores del servicio trabajan en localhostinsecure http, lo cual es un alivio porque configurar SSL local a veces es una tarea ardua.

    Dato curioso: este proyecto me obligó a hacer algo que había estado posponiendo por un tiempo: obtener y configurar SSL para el wwwsubdominio de mi sitio web. Esto es algo que insto a la gente a considerar hacer porque casi todas las cosas nuevas y divertidas que llegarán al navegador en el futuro requerirán el uso de SSL.

    Todo el material que reuniremos funciona hoy en Chrome (yo uso la versión 47). En cualquier momento se enviará Firefox 44 y será compatible con los trabajadores del servicio. ¿Está preparado el trabajador de servicios? proporciona información granular sobre el soporte en diferentes navegadores.

     

    Registro, instalación y activación de un trabajador de servicio

    Ahora que nos hemos ocupado de algo de teoría, podemos comenzar a armar nuestro trabajador de servicio.

    Para instalar y activar nuestro trabajador de servicio, queremos escuchar installeventos activatey actuar en consecuencia.

    Podemos comenzar con un archivo vacío para nuestro trabajador de servicio y agregar un par de archivos eventListeners. En serviceWorker.js:

    self.addEventListener('install', event = { // Do install stuff});self.addEventListener('activate', event = { // Do activate stuff: This will come later on.});

    Registrar a nuestro trabajador de servicio

    Ahora necesitamos decirle a las páginas de nuestro sitio web que utilicen el trabajador de servicio. Giantess Videos and comics

    Recuerde, este registro se realiza desde fuera del trabajador del servicio; en mi caso, desde un script ( /js/site.js) que se incluye en cada página de mi sitio web.

    En mi site.js:

    if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/serviceWorker.js', { scope: '/' });}

    Almacenamiento previo en caché de activos estáticos durante la instalación

    Quiero utilizar la etapa de instalación para almacenar en caché previamente algunos recursos en mi sitio web.

    • Al almacenar en caché previamente algunos recursos estáticos (imágenes, CSS, JavaScript) que utilizan muchas páginas de mi sitio web, puedo acelerar los tiempos de carga sacándolos de la caché, en lugar de recuperarlos de la red en cargas de páginas posteriores.
    • Al almacenar en caché previamente una página alternativa sin conexión, puedo mostrar una buena página cuando no puedo cumplir con una solicitud de página porque el usuario está sin conexión.

    Los pasos para hacer esto son:

    1. Dígale al installevento que espere y que no se complete hasta que haya hecho lo que tengo que hacer usando event.waitUntil.
    2. Abra el archivo apropiado cachey pegue los activos estáticos en él usando Cache.addAll. En el lenguaje progresivo de las aplicaciones web , estos activos constituyen mi "shell de aplicación".

    En /serviceWorker.js, expandamos el installcontrolador:

    self.addEventListener('install', event = { function onInstall () { return caches.open('static') .then(cache = cache.addAll([ '/images/lyza.gif', '/js/site.js', '/css/styles.css', '/offline/', '/' ]) ); } event.waitUntil(onInstall(event));});

    El trabajador de servicio implementa la CacheStorageinterfaz , lo que hace que la cachespropiedad esté disponible globalmente en nuestro trabajador de servicio. Existen varios métodos útiles caches, por ejemplo, openy delete.

    Puede ver Promisescómo funciona aquí: caches.opendevuelve una Promiseresolución a un cacheobjeto una vez que ha abierto exitosamente el staticcaché; addAlltambién devuelve un mensaje Promiseque se resuelve cuando todos los elementos que se le pasaron se han guardado en la memoria caché.

     

    Le digo eventque espere hasta que la Promisefunción devuelta por mi controlador se resuelva correctamente. Entonces podremos estar seguros de que todos esos elementos previos al caché se ordenarán antes de que se complete la instalación.

    Confusiones de consola

    Registro obsoleto

    Posiblemente no sea un error, pero ciertamente una confusión : si usted console.loges un trabajador del servicio, Chrome continuará mostrando (en lugar de borrar) esos mensajes de registro en solicitudes de páginas posteriores. Esto puede hacer que parezca que los eventos se activan demasiadas veces o que el código se ejecuta una y otra vez.

    Por ejemplo, agreguemos una logdeclaración a nuestro installcontrolador:

    self.addEventListener('install', event = { // … as before console.log('installing');});

    Un error cuando todo va bien

    Otra cosa extraña es que una vez que se instala y activa un trabajador de servicio, las cargas posteriores de cualquier página dentro de su alcance siempre causarán un único error en la consola . Pensé que estaba haciendo algo mal.

    Lo que hemos logrado hasta ahora

    El trabajador del servicio maneja el installevento y almacena en caché algunos activos estáticos. Si utilizara este trabajador de servicio y lo registrara, de hecho almacenaría en caché previamente los activos indicados, pero aún no podría aprovecharlos sin conexión.

    El contenido de serviceWorker.js está en GitHub .

    Manejo de recuperación con trabajadores de servicio

    Hasta ahora, nuestro trabajador de servicio tiene un controlador desarrollado installpero no hace nada más que eso. La magia de nuestro trabajador de servicio realmente sucederá cuando fetchse desencadenen los eventos.

    Podemos responder a las recuperaciones de diferentes maneras. Al utilizar diferentes estrategias de red , podemos decirle al navegador que siempre intente recuperar ciertos activos de la red (asegurándonos de que el contenido clave esté actualizado), mientras favorece las copias en caché para los activos estáticos, lo que realmente reduce la carga útil de nuestra página. También podemos proporcionar un buen respaldo fuera de línea si todo lo demás falla.

    Cada vez que un navegador quiere recuperar un activo que está dentro del alcance de este trabajador de servicio, podemos saberlo, sí, agregando un eventListenerin serviceWorker.js:

    self.addEventListener('fetch', event = { // … Perhaps respond to this fetch in a useful way?});

    Nuevamente, cada recuperación que caiga dentro del alcance de este trabajador de servicio (es decir, ruta) activará este evento: páginas HTML, scripts, imágenes, CSS, lo que sea. Podemos manejar selectivamente la forma en que el navegador responde a cualquiera de estas recuperaciones.

    ¿Deberíamos encargarnos de esta recuperación?

    Cuando fetchocurre un evento para un activo, lo primero que quiero determinar es si este trabajador del servicio debería interferir con la recuperación del recurso determinado. De lo contrario, no debería hacer nada y dejar que el navegador mantenga su comportamiento predeterminado.

     

    Terminaremos con una lógica básica como esta en serviceWorker.js:

    self.addEventListener('fetch', event = { function shouldHandleFetch (event, opts) { // Should we handle this fetch? } function onFetch (event, opts) { // … TBD: Respond to the fetch } if (shouldHandleFetch(event, config)) { onFetch(event, config); }});

    La shouldHandleFetchfunción evalúa una solicitud determinada para determinar si debemos proporcionar una respuesta o dejar que el navegador haga valer su manejo predeterminado.

    ¿Por qué no utilizar promesas?

    Para mantener la predilección de los trabajadores de servicios por las promesas, la primera versión de mi fetchcontrolador de eventos tenía este aspecto:

    self.addEventListener('fetch', event = { function shouldHandleFetch (event, opts) { } function onFetch (event, opts) { } shouldHandleFetch(event, config) .then(onFetch(event, config)) .catch(…);});

    Parece lógico, pero estaba cometiendo un par de errores de novato con las promesas. Juro que sentí un olor a código incluso al principio, pero fue Jake quien me aclaró mis errores. (Lección: como siempre, si el código parece incorrecto, probablemente lo sea).

    Los rechazos de promesas no deben usarse para indicar: "Recibí una respuesta que no me gustó". En cambio, los rechazos deberían indicar: "Ah, mierda, algo salió mal al intentar obtener la respuesta". Es decir, los rechazos deberían ser excepcionales .

    Criterios para solicitudes válidas

    Bien, volvamos a determinar si una solicitud de recuperación determinada es aplicable para mi trabajador de servicio. Mis criterios específicos del sitio son los siguientes:

    1. La URL solicitada debe representar algo que quiero almacenar en caché o a lo que quiero responder. Su ruta debe coincidir con una Regular Expressionde rutas válidas.
    2. El método HTTP de la solicitud debe ser GET.
    3. La solicitud debe ser para un recurso de mi origen ( lyza.com).

    Si alguna de las criteriapruebas da como resultado false, no debemos manejar esta solicitud. En serviceWorker.js:

    function shouldHandleFetch (event, opts) { var request = event.request; var url = new URL(request.url); var criteria = { matchesPathPattern: !!(opts.cachePathPattern.exec(url.pathname), isGETRequest : request.method === 'GET', isFromMyOrigin : url.origin === self.location.origin }; // Create a new array with just the keys from criteria that have // failing (i.e. false) values. var failingCriteria = Object.keys(criteria) .filter(criteriaKey = !criteria[criteriaKey]); // If that failing array has any length, one or more tests failed. return !failingCriteria.length;}

    Por supuesto, los criterios aquí son míos y variarán de un sitio a otro. event.requestes un Requestobjeto que tiene todo tipo de datos que puede consultar para evaluar cómo le gustaría que se comportara su controlador de recuperación.

     

    Nota trivial: si notó la incursión de config, pasó optsa las funciones del controlador, bien identificado. Factoricé algunos configvalores reutilizables y creé un configobjeto en el alcance de nivel superior del trabajador del servicio:

    var config = { staticCacheItems: [ '/images/lyza.gif', '/css/styles.css', '/js/site.js', '/offline/', '/' ], cachePathPattern: /^/(?:(20[0-9]{2}|about|blog|css|images|js)/(.+)?)?$/};

    ¿Por qué incluirse en la lista blanca?

    Quizás se pregunte por qué solo almaceno en caché elementos con rutas que coinciden con esta expresión regular:

    /^/(?:(20[0-9]{2}|about|blog|css|images|js)/(.+)?)?$/

    … en lugar de almacenar en caché cualquier cosa que provenga de mi propio origen. Un par de razones:

    • No quiero almacenar en caché al trabajador del servicio.
    • Cuando desarrollo mi sitio web localmente, algunas solicitudes generadas son para cosas que no quiero almacenar en caché. Por ejemplo, uso browserSync, que inicia un montón de solicitudes relacionadas en mi entorno de desarrollo. ¡No quiero almacenar en caché esas cosas! Parecía complicado y desafiante tratar de pensar en todo lo que no me gustaría almacenar en caché (sin mencionar que era un poco extraño tener que deletrearlo en la configuración de mi trabajador de servicio). Por tanto, un enfoque de lista blanca parecía más natural.

    Escribir el controlador de recuperación

    Ahora estamos listos para pasar fetchlas solicitudes aplicables a un controlador. La onFetchfunción necesita determinar:

    1. qué tipo de recurso se solicita,
    2. y cómo debo cumplir con esta solicitud.

    1. ¿Qué tipo de recurso se solicita?

    Puedo mirar el HTTP Acceptencabezado para obtener una pista sobre qué tipo de activo se solicita. Esto me ayuda a descubrir cómo quiero manejarlo.

    function onFetch (event, opts) { var request = event.request; var acceptHeader = request.headers.get('Accept'); var resourceType = 'static'; var cacheKey; if (acceptHeader.indexOf('text/html') !== -1) { resourceType = 'content'; } else if (acceptHeader.indexOf('image') !== -1) { resourceType = 'image'; } // {String} [static|image|content] cacheKey = resourceType; // … now do something}

    Para mantenerme organizado, quiero colocar diferentes tipos de recursos en diferentes cachés. Esto me permitirá administrar esos cachés más adelante. Estas claves de caché Stringson arbitrarias: puedes llamar a tus cachés como quieras; la API de caché no tiene opiniones.

    2. Responder a la búsqueda

    Lo siguiente que debe onFetchhacer es ir respondToal fetchevento con un inteligente Response.

    function onFetch (event, opts) { // 1. Determine what kind of asset this is… (above). if (resourceType === 'content') { // Use a network-first strategy. event.respondWith( fetch(request) .then(response = addToCache(cacheKey, request, response)) .catch(() = fetchFromCache(event)) .catch(() = offlineResponse(opts)) ); } else { // Use a cache-first strategy. event.respondWith( fetchFromCache(event) .catch(() = fetch(request)) .then(response = addToCache(cacheKey, request, response)) .catch(() = offlineResponse(resourceType, opts)) ); }}

    ¡Cuidado con Async!

    En nuestro caso, shouldHandleFetchno hace nada asincrónico y tampoco lo hace onFetchhasta el punto de event.respondWith. Si algo asincrónico hubiera sucedido antes de eso, estaríamos en problemas. event.respondWithdebe llamarse entre la fetchactivación del evento y el control que regresa al navegador. Lo mismo ocurre con event.waitUntil. Básicamente, si estás manejando un evento, haz algo inmediatamente (sincrónicamente) o dile al navegador que espere hasta que termines las cosas asincrónicas.

     

    Contenido HTML: implementación de una estrategia centrada en la red

    Responder a fetchlas solicitudes implica implementar una estrategia de red adecuada. Veamos más de cerca la forma en que respondemos a las solicitudes de contenido HTML ( resourceType === ‘content’).

    if (resourceType === 'content') { // Respond with a network-first strategy. event.respondWith( fetch(request) .then(response = addToCache(cacheKey, request, response)) .catch(() = fetchFromCache(event)) .catch(() = offlineResponse(opts)) );}

    La forma en que cumplimos con las solicitudes de contenido aquí es una estrategia que da prioridad a la red. Debido a que el contenido HTML es la principal preocupación de mi sitio web y cambia con frecuencia, siempre trato de obtener documentos HTML nuevos de la red.

    Analicemos esto.

    1. Intente buscar en la red

    fetch(request) .then(response = addToCache(cacheKey, request, response))

    Si la solicitud de red tiene éxito (es decir, la promesa se resuelve), continúe y guarde una copia del documento HTML en el caché apropiado ( content). Esto se llama almacenamiento en caché de lectura directa :

    function addToCache (cacheKey, request, response) { if (response.ok) { var copy = response.clone(); caches.open(cacheKey).then( cache = { cache.put(request, copy); }); return response; }}

    Las respuestas se pueden utilizar sólo una vez .

    Necesitamos hacer dos cosas con lo que responsetenemos:

    • cachéalo,
    • responder al evento con él (es decir, devolverlo).

    Pero Responselos objetos sólo pueden usarse una vez. Al clonarlo, podemos crear una copia para uso del caché:

    var copy = response.clone();

    No almacene en caché las malas respuestas. No cometas el mismo error que yo. La primera versión de mi código no tenía este condicional:

    if (response.ok)

    ¡Es increíble terminar con 404 u otras malas respuestas en el caché! Solo almacena en caché las respuestas felices.

    2. Intente recuperar desde la caché

    Si la recuperación del activo de la red tiene éxito, habremos terminado. Sin embargo, si no es así, es posible que estemos desconectados o que nuestra red esté comprometida. Intente recuperar una copia del HTML previamente almacenada en caché desde la caché:

    fetch(request) .then(response = addToCache(cacheKey, request, response)) .catch(() = fetchFromCache(event))

    Aquí está la fetchFromCachefunción:

    function fetchFromCache (event) { return caches.match(event.request).then(response = { if (!response) { // A synchronous error that will kick off the catch handler throw Error('${event.request.url} not found in cache'); } return response; });}

    Nota: No indique con qué caché desea verificar caches.match; Compruébalos todos a la vez.

    3. Proporcionar un recurso alternativo sin conexión

    Si hemos llegado hasta aquí pero no hay nada en el caché con el que podamos responder, devuelva un respaldo fuera de línea apropiado, si es posible. Para páginas HTML, esta es la página almacenada en caché desde /offline/. Es una página con un formato razonablemente bueno que le dice al usuario que está desconectado y que no podemos cumplir con lo que busca.

    fetch(request) .then(response = addToCache(cacheKey, request, response)) .catch(() = fetchFromCache(event)) .catch(() = offlineResponse(opts)) 




    Tal vez te puede interesar:

    1. ¿Deberían abrirse los enlaces en ventanas nuevas?
    2. 24 excelentes tutoriales de AJAX
    3. 70 técnicas nuevas y útiles de AJAX y JavaScript
    4. Más de 45 excelentes recursos y repositorios de fragmentos de código

    Convertir a un trabajador de servicios: un estudio de caso

    Convertir a un trabajador de servicios: un estudio de caso

    ¡Registro! Diseño de arquitectura de componentes de interfaz de usuario y tokens, con Nathan Curtis Índice

    programar

    es

    https://aprendeprogramando.es/static/images/programar-convertir-a-un-trabajador-de-servicios-un-estudio-de-caso-882-0.jpg

    2024-05-20

     

    Convertir a un trabajador de servicios: un estudio de caso
    Convertir a un trabajador de servicios: un estudio de caso

    Si crees que alguno de los contenidos (texto, imagenes o multimedia) en esta página infringe tus derechos relativos a propiedad intelectual, marcas registradas o cualquier otro de tus derechos, por favor ponte en contacto con nosotros en el mail [email protected] y retiraremos este contenido inmediatamente

     

     

    Top 20