Está en la página 1de 35

Tabla

de contenido
Acerca de este manual 1.1
Bloque 1. Introducción 1.2
Capítulo 1 - Una nueva forma de ofrecer experiencias de usuario en la Web 1.2.1
Capítulo 2 - El manifiesto de nuestra aplicación 1.2.2
Capítulo 3 - Los patrones App Shell y PRPL 1.2.3
Bloque 2. Los Service Workers 1.3
Capítulo 4 - Conceptos básicos 1.3.1
Bloque 3. La API Caché 1.4
Bloque 4. Mejorando el rendimiento de tu WebApp 1.5
Bloque 5. Integrando otras APIs 1.6
Notificando cosas - Web Push Notifications API 1.6.1
Gestionando credenciales - Credential Managment API 1.6.2
Accediendo a tu dispositivo - Device APIs 1.6.3
Bloque 6. Detalles muy importantes a tener en cuenta 1.7
RWD & Mobile First 1.7.1
La accesibilidad 1.7.2
La seguridad 1.7.3

1
Acerca de este manual

Acerca de este manual


Este manual es una recopilación de posts extraídos del blog El Abismo de Null sobre el
desarrollo de aplicaciones

Antes de empezar

Estructura

Aviso importante

Comparte
La guía no se ha creado con ningún fin lucrativo. No se esperan aportaciones económicas,
ni se cuenta con ningún derecho de autor explícito.

Simplemente ha sido creada por un afán por compartir y evangelizar sobre esta gran
herramienta de trabajo.

Si te gusta lo que has leído y crees que puede aportar valor a otras personas, comparte.
Cambia, elimina o añade todo aquello que tú creas que aporta y hazla tuya.

Puedes compartir por cualquier red social, blog o podcasts que creas conveniente.

Tuitea

Descarga
El manual se encuentra disponible en la plataforma GitBook de manera pública. Están
habilitados los formatos en MARKDOWN, HTML, PDF, EPUB y MOBI para que puedas
disfrutar de ella desde cualquier tipo de dispositivo.

Aunque las 5 formas han sido probadas, puede ser que se me hayan pasado aquellos
detalles de maquetación o de visualización más específicos, por lo que de ser así, te
agradecería que me lo comentaras o que me enviaras una Pull Request con los cambios.

2
Acerca de este manual

Feedback
Estoy disponible en todo momento para que puedas decirme qué te ha parecido el manual y
estoy abierto a cualquier comentario sobre cómo mejorarlo.

Puedes hablar conmigo por twitter o escribirme algún comentario en mi blog, o escribirme
directamente un correo electrónico.

Te intentaré contestar en la mayor brevedad posible. Lo prometo.

Agradecimientos

3
Capítulo 1 - Una nueva forma de ofrecer experiencias de usuario en la Web

Capítulo 1 - Una nueva forma de ofrecer


experiencias de usuario en la Web
Hola de nuevo. Tengo esto un poco abandonado, pero estoy de vuelta :). Empieza una
nueva serie en El Abismo. Dejamos por unos meses VueJS para adentrarnos en lo que se
conoce como Progressive Web Apps.

Como siempre, mejor que no nos pongamos un número determinado de posts a esta serie y
nos centremos en dedicar el tiempo necesario a cada concepto que encontremos en esta
nueva filosofía de desarrollar aplicaciones Web.

Desde el principio de esta serie, podrás encontrar el posts en su manual de Gitbook


correspondiente: 'Desarrolla Progressive Web Apps', por si te es más cómodo leer la serie
de esta forma. Sin más preámbulo, empecemos.

¿Qué es?
Progressive Web App es un concepto creado por la gente de Google.

Para que una aplicación Web pueda ser considerada como Progressive Web App, tiene que
cumplir tres requisitos indispensables. Tiene que ser:

Rápida: todas las acciones que se lleven a cabo por el usuario se tienen que realizar
en unos tiempos considerables y que la experiencia fluya para conseguir no aburrir al
usuario con esperas.

Confiable: Que las operaciones que nuestro usuario haga sean seguras y que tenga
sensación de que lo son. Cada vez compramos y vendemos más por Internet, es
necesario que tanto usuario como negocio sientan que las transacciones que llevamos
acabo se hacen de una manera segura.

Atractiva: Que el sistema ayude a que el usuario se encuentre cómodo y en todo


momento sepa donde está, que el uso de una aplicación a otra no suponga una curva
de aprendizaje tan grande que haga que podamos perderle por el camino. Parece que
estos tres requisitos no son nada nuevo. Muchos de los requisitos que la gente de
negocio pone a sus productos ya intentan cumplir con estas tres máximas.

Entonces ¿Qué diferencia una aplicación Web normal de una Progressive Web App?

4
Capítulo 1 - Una nueva forma de ofrecer experiencias de usuario en la Web

La diferencia está en cómo llegamos a conseguir estos objetivos. Google ha creado un


término muy 'marketiniano' que al final no es más que una lista de requisitos que tenemos
que cumplir para crear mejores experiencias y conseguir que nuestros usuarios usen más
nuestra aplicación.

La diferencia se encuentra también en que hasta ahora, cumplir con estos requisitos en
dispositivos móviles por medio de tecnología Web, se hacia algo complicado. ¿Por qué?
Por estas razones:

Las aplicaciones Web móviles tienen fama de ser lentas. No es fama en realidad, es un
hecho. Todos los 'benchmark' que comparan aplicaciones móviles web con
aplicaciones nativas, acaban dejando en muy mala posición a los estándares, la API
del DOM y el propio JavaScript interpretado hacen bastante daño a este rendimiento.

Las aplicaciones Web cada vez son más fiables, pero es cierto que el que yo pueda
acceder a ella desde cualquier lugar de Internet hace que pierda esa seguridad que si
puedo encontrar en un Store de Android o Apple, por tanto, la manera en que usamos
la red nos ha dado problemas de seguridad que Google intenta solventar con estas
nuevas técnicas.

Además, las aplicaciones Web móviles tienen mala fama de ser poco atractivas. La
Web no nació para ser consumida desde dispositivos móviles y aunque ya existen
muchas técnicas para que las interfaces se comporten mejor en dispositivos móviles,
todavía existe mucha distancia en cuanto a usabilidad respecto a las nativas:
Notificaciones, accesos directos, acciones gestuales, son cosas que la Web estaba por
resolver y que Google está haciendo un empujón por mejorar.

Entonces... si nos encontramos con este panorama ¿Cómo Google nos ayuda?

Google nos ayuda a conseguir estos objetivos de muchas maneras diferentes:

Por ejemplo, se han encargado de desarrollar librerías específicas para que


implementar ciertas funcionalidades sea más sencillo. Google cuenta con frameworks
CSS Responsive que dan un 'look & feel' parecido al que tienen las aplicaciones
nativas de Android.

Se han encargado de crear guías de estilo o documentación que nos permita llegar a
conseguir todas las funcionalidades de su checklist. Uno de estos checklist lo podemos
encontrar aquí.

Están implementando en su navegador aquellas funcionalidades del estándar que


hasta ahora estaban suponiendo un deterioro de rendimiento y calidad. Dos ejemplos
muy claros son la posibilidad de usar Web Workers o Notificaciones desde un
navegador Web como Chrome.

5
Capítulo 1 - Una nueva forma de ofrecer experiencias de usuario en la Web

Han mejorado sus herramientas de desarrollo para que nos den pistas y métricas sobre
cómo estamos haciéndolo y cómo podremos mejorarlo. En un apartado posterior
explicaremos un poco más de esto.

Así que, como vemos, Google está muy interesado en que estas funcionalidades estén
implementadas en nuestros sistemas para que la experiencia de Android sea todavía mejor.
El cómo lo hagamos, dependerá de nosotros, pero contamos con herramientas para
lograrlo.

¿Cómo hago mi aplicación web progresiva?


Lo primero que tenemos que tener en cuenta es qué funcionalidades tenemos que incluir en
nuestra aplicación para conseguirlo. Si nos guiamos por el checklist de Google, para que
una aplicación sea considerada PWA, tiene que cumplir como mínimo con esto:

Sitio accesible por HTTPS.


Las pantallas son responsive en tablet y móvil.
Todas las URLS que tienen nuestra aplicación pueden ser cargadas de manera offline.
Se puede añadir al menú de inicio.
La primera carga es rápida hasta con 3G.
La aplicación funciona en todos los navegadores.
La transición entre pantallas no es bloqueante y fluye.
Cada pantalla tiene una URL.

No creo que haga falta explicar ahora cada uno de los requisitos porque parecen bastante
explicativos, pero...

¿Cómo conseguiremos añadir nuestra Web al menú de inicio? ¿Cómo toda la aplicación
podrá ser accesible de manera offline? ¿Cómo haremos para que nuestra aplicación sea
rápida incluso con 3G?

Estas son las preguntas que espero resolver en esta serie. Este primer post nos muestra el
qué y el por qué. El restos nos enseñarán el cómo.

¿Cuento con alguna herramienta en la que


apoyarme?
Hay muchas herramientas en las que nos apoyaremos para saber si estamos consiguiendo
que nuestra aplicación sea considerada como una PWA.

Lighthouse

6
Capítulo 1 - Una nueva forma de ofrecer experiencias de usuario en la Web

La mejor herramienta que han creado para mejorar nuestra aplicación es sin duda
Lighthouse. Esta herramienta nos permite analizar nuestra código y nos enumera aquellos
puntos en los que nuestra aplicación no está cumpliendo con los conceptos de PWA.

Lo que hace es analizar uno a uno los puntos clave de la ckecklist y darnos una serie de
consejos para que podamos mejorar.

Me gusta porque te muestra una serie de diagramas del estado en el que se encuentra. En
muchos casos no querremos que nuestra aplicación cumpla con el 100% de los requisitos,
pero si que cumpla con lo que nosotros entendemos como critico para nuestro negocio.

La herramienta puede ser usada como un plugin de Chrome o con comandos de la CLI de
NPM. El primer método es muy útil para analizar aplicaciones que ya están en producción o
de las que no tenemos acceso al código y la segunda puede venir muy bien para incluirla en
procesos de integración continua o testing automático (si la app no llega a unas métricas
mínimas, no se desplegará o se integrará, por ejemplo).

Chrome Developer Tools


Esta es la herramienta de toda la vida. Tan usable y útil como siempre, pero vitaminada.
Además de contar con emuladores para poder ver si nuestra aplicación es rápida y atractiva
en móviles, podremos comprobar y gestionar la metainformación de nuestra aplicación
(Esto es el manifest, hablaremos en el siguiente post de ello).

PageSpeep Insights
PageSpeed es una aplicación que nos permite obtener métricas a nivel de rendimiento.
Nuestras aplicaciones tienen que ser rápidas. Por tanto medir cómo son las transacciones,
animaciones, ejecuciones largas de JavaScript son alguno de los puntos claves de esta
herramienta.

Conclusión
Una cosa que me gusta de este nuevo concepto es que nada es bloqueante o crítico. El
término Progressive viene heredado de lo que se conoce en desarrollo Web como
'Enhancement Progressive' o Mejora Progresiva. Es decir, nuestro sistema siempre tiene
que cumplir con una serie de funcionalidades mínimas que sean usables y funcionales en
cualquier tipo de dispositivo y navegador.

Si un dispositivo tiene ventajas técnicas y podemos aprovecharnos de ellas para crear


mejores aplicaciones, hagámoslo. Eso sí, dando un soporte mínimo a navegadores y
dispositivos antiguos para que cualquier tipo de usuario pueda usar nuestra aplicación y sin

7
Capítulo 1 - Una nueva forma de ofrecer experiencias de usuario en la Web

que la inclusión de una funcionalidad suponga el bloqueo de otra.

Es importante tomarse el término Progressive Web App como esto. Si un dispositivo va a


permitir ciertas funcionalidades, intentemos desarrollarlas. Que su implementación nos va a
suponer más costo del beneficio que nos va a generar... pues quizá no sea el momento de
abarcarla y seguir nuestro trabajo por otra parte.

Hagamos el trabajo del checklist como algo opcional que nos pueda ayudar, pero no como
algo bloqueante que nos deje sin un número de usuarios que pueden ser importantes para
nosotros.

Nos leemos :)

8
Capítulo 2 - El manifiesto de nuestra aplicación

Capítulo 2 - El manifiesto de nuestra


aplicación
En el post anterior explicamos qué es lo que define a una PWA según Google, nos quitamos
un poco de fatiga al ver que el concepto no viene a revolucionar el desarrollo Web y
enumeramos una serie de funcionalidades que sí o sí una aplicación tiene que incluir para
ser considerada PWA.

Sin embargo, nos quedamos mucho en la teoría y lo abstracto, y no explicamos por dónde
tenemos que empezar para que nuestra aplicación empiece a cumplir con el ckecklist de
Google.

En el post de hoy, vamos a centrarnos en resolver uno de los requisitos que se nos pedía:

Nuestra aplicación se debe poder incluir en el menú de inicio del dispositivo

¿Cómo podemos hacer esto? Bastante más fácil de lo que a simple vista parece. Veamos:

¿Qué es el manifiesto?
Para que nuestra Web sea considerada por los navegadores como una PWA, lo primero
que tenemos que hacer es añadir un manifiesto en el proyecto. El manifiesto no es más que
un fichero de configuración accesible en todo momento por el navegador.

Que un navegador tenga las posibilidades de saber que nuestra aplicación es una PWA le
dará la posibilidad al usuario de poder incluir nuestra Web en el menú de inicio del
dispositivo.

Este fichero tiene formado JSON y por lo general suele ser nombrado como manifest.json ,
aunque podemos ponerle el nombre queramos. Suele encontrarse en la raíz de nuestro
proyecto, pero podemos situarlo dónde queramos mientras sea accesible por el navegador.

Dentro de este fichero indicamos diferente metainformación del proyecto que los
navegadores que soportan el uso de PWA sabrán interpretar. Por ahora Google Chrome
(tango en ordenador como en Android) es el navegador que más soporte tiene sobre este
fichero - lógico si pensamos que Google es quien esta promoviendo esta iniciativa.

Hasta ahora, toda esta metainformación, en una Web, solía indicarse por medio de meta-
tags en el head del fichero index.html o similares, pero me gusta que esta nueva forma

de añadir información a un proyecto. No ensucia tanto el marcado del HTML principal y todo
queda resumido en un fichero aparte.

9
Capítulo 2 - El manifiesto de nuestra aplicación

Ojalá que este fichero se convierta en el fichero de configuración de un proyecto de manera


estándar.

¿Cómo empiezo?
Como decimos, para indicar a los navegadores que nuestra aplicación es una PWA,
simplemente tenemos que añadir este fichero manifest.json en nuestro proyecto.

Para que el navegador sepa donde lo tenemos alojado, indicamos su ubicación con un link
en nuestro index.html o similar de la siguiente manera:

<link rel="manifest" href="/manifest.json">

De esta forma estamos indicando que nuestro manifiesto se encuentra en la raíz del
proyecto (o en la misma carpeta que el index.html) y que su nombre es manifest.json. A
partir de aquí, los navegadores interpretarán todo lo que hayamos indicado dentro de él.

Como este fichero contiene varias configuraciones de diferente índole y puede que sea
bastante engorroso en un primer momento, tenemos varias formas de crearlo:

Desde 0: Podemos crearlo a mano. La gente de Mozilla, en su MDN, tiene un fichero


de ejemplo con las propiedades más relevantes y una chuleta con el significado de
cada una de ellas.

Desde un generador: Este generador es una Web con interfaz de usuario que nos
permite generar el fichero de una forma más visual y explícita. Esta interfaz nos
generará el JSON que tenemos que copiar en nuestro manifest.json .

Desde snippet en Visual Studio Code: Existe una extensión de 'Visual Studio Code'
bastante buena que nos permite añadir código típico de una PWA de una forma más
sencilla. La extensión de Visual Studio Code se llama PWA Tools y está mantenida por
John Papa, desarrollador de Microsoft, muy prolífico en este tipo de contribuciones. Al
añadir esta extensión, lo único que tendremos que hacer es escribir pwa-manifest y
pulsas en Intro . A partir de ese momento tendremos un manifiesto tipo listo para ser
rellenado.

Desde la plantilla de un framework: Por ejemplo, vue-cli, ha creado una plantilla para
dar soporte a PWA. Si indicamos $ vue init pwa my-project , el proyecto my-project
ya contendrá un manifest.json listo para configurarse. Otros frameworks también
cuentan con sus propios generadores y sus plantillas de PWA predefinidas.

10
Capítulo 2 - El manifiesto de nuestra aplicación

¿Qué partes lo componen?


Pero ¿y qué cosas podemos configurar en el manifiesto? Si ejecutamos la extensión de
VSC (recuerda: pwa-manifest + Intro ) obtenemos un fichero como el siguiente:

{
"$schema": "http://json.schemastore.org/web-manifest",
"short_name": "12CharShortName",
"name": "Name",
"description": "description",
"scope": "/",
"icons": [
{
"src": "img2x.jpg",
"sizes": "96x96",
"type": "image/jpg"
},
{
"src": "img3x.jpg",
"sizes": "144x144",
"type": "image/jpg"
},
{
"src": "img4x.jpg",
"sizes": "192x192",
"type": "image/jpg"
},
{
"src": "img6x.jpg",
"sizes": "512x512",
"type": "image/jpg"
}
],
"background_color": "#EEE",
"theme_color": "#1565c0",
"start_url": "./?utm_source=web_app_manifest",
"display": "standalone",
"orientation": "any"
}

Hay más propiedades, pero las principales son estas. Expliquemos cada una a
continuación:

Validando el manifiesto
$schema: Indica el schema sobre el que se valida este JSON. Los schemas sirven
para 'tipar' los ficheros JSON. De esta forma podemos usar herramientas que se
encargan de comprobar si nuestro manifiesto está bien formado. Uno de estos

11
Capítulo 2 - El manifiesto de nuestra aplicación

validadores es JSON Schema Validator. Si seleccionamos el 'Schema Web Manifest' y


copiamos nuestro manifest.json, veremos si la estructura es correcta.

Indicando el inicio de la aplicación


start_url: Que indica dónde tiene que iniciarse una aplicación en particular.

Añadiendo iconos
Cuando el usuario ha decidido que una Web le interesa como aplicación, podrá ir a su
configuración en Chrome y pulsar 'Añadir a pantalla de inicio', esto añadirá un icono en el
menú de arranque. Para indicar a Chrome que icono y que texto tiene que mostrar, tenemos
dos propiedades:

icons: que es un array de objetos donde se indican las imágenes de nuestros iconos.
Si nos fijamos, indicamos diferentes densidades del icono para que Android decida cual
tiene que usar para cada dispositivo. Los configurados en nuestro 'manifest' son los
recomendados por defecto. Estas imágenes se pueden encontrar en la ruta que
decidamos mientras sean accesibles por el navegador. Hay una herramienta muy
buena para generar estos iconos llamada 'Android Asset Studio - Launcher icon
generator' que te permitirá crear todos los tamaños de tu icono favorito.

short_name: Es el texto que se mostrará debajo de nuestro icono en Android. Es


recomendable que no se indique un nombre mayor de 12 caracteres ya que Android
trunca a partir de este tamaño.

Añadiendo un SplashScreen o pantalla de bienvenida


Cuando pinchamos en este icono, Android nos permite lanzar una pantalla de inicio. Esta
pantalla de bienvenida es idónea para hacer esperar al usuario por si hay que cargar algo
por defecto, ya sea de una caché o de un sistema remoto, por eso podemos aprovechar
esta ventana para dar la bienvenida al usuario.

Para indicar esta pantalla, se usan 3 propiedades:

icons: Cómo se indicó antes es una colección de iconos con diferentes densidad y
tamaño. Lo que hará esta pantalla de bienvenida es usar el icono con mayor densidad.
Se recomienda por tanto indicar siempre el icono con tamaño 512x512 para crear una
buena experiencia al usuario.

name: Es el nombre de nuestra aplicación.

12
Capítulo 2 - El manifiesto de nuestra aplicación

background_color: Que es el color de fondo que se mostrará en esta pantalla de


Bienvenida.

Indicando el tipo de pantalla


Podemos indicar cómo una aplicación tiene que renderizarse en nuestro dispositivo con la
propiedad 'display'. tenemos 4 formas de mostrar la aplicación:

fullscreen: La aplicación usa toda la pantalla. No se muestra nada del navegador de


Chrome ni de la barra de notificaciones de Android.

standalone: La aplicación se muestra como una Aplicación Android, se ve la barra de


notificaciones de Android, pero no la barra del navegador de Chrome.

minimal-ui: Se muestra como la standalone, pero contiene algunos elementos de


navegación típicos de los navegadores. Es un mixto entre la standalone y browser.

browser: se muestra con la barra de navegación.

13
Capítulo 2 - El manifiesto de nuestra aplicación

Indicando la orientación inicial


Con la propiedad 'orientation' se indica la orientación de la aplicación. Podemos usar los
siguientes valores:

any
natural
landscape
landscape-primary
landscape-secondary
portrait
portrait-primary
portrait-secondary

¿Cómo puedo depurar este fichero?


Chrome ha pensado en ello y, como dijimos en el post anterior, han creado un apartado
nuevo en las 'Developer Tools'. Si tras pulsar F12 vamos a la pestaña 'Application',
comprobaremos que todas las opciones de nuestro manifest.json pueden ser consultadas
aquí.

14
Capítulo 2 - El manifiesto de nuestra aplicación

De esta forma podemos comprobar si estamos indicando todo correctamente para cuando
el usuario decida instalar la aplicación en su menú de arranque.

¿Cómo indico a los usuarios que pueden


instalar mi aplicación?
Como indicamos anteriormente, el usuario puede ser proactivo e intentar instalar nuestra
PWA por su cuenta yendo al menú de configuración de Chrome.

¿Qué pasa si queremos que otros usuarios que no conocen esta opción instalen nuestra
PWA? Estaría muy bien contar con algún tipo de banner o notificación que ayude al usuario.

Este banner es posible que salga de manera automática. Es Chrome quien se encarga de
mostrarlo al usuario. Para hacerlo solo tenemos que cumplir con estos criterios:

Contener un archivo de manifiesto de aplicación web con:


un short_name (usado en la pantalla de inicio);
un name (usado en el banner);
un ícono png de 192 x 192 (en las declaraciones del ícono se debe incluir un tipo
de mime image/png); una start_url que se carga.
Contener un service worker registrado en tu sitio (Todavía no hemos visto este punto).

15
Capítulo 2 - El manifiesto de nuestra aplicación

Transmitirse a través de HTTPS (un requisito para usar el service worker).


Recibir visitas al menos dos veces, con al menos cinco minutos de diferencia entre las
visitas.

Para comprobar que cumplimos con todo esto, 'Developer Tools' nos vuelve a ayudar. Hay
una opción que dice 'Add to homescreen'. Esta opción es la que simula la ejecución de este
banner en el ordenador. Si todo va correctamente, nos simulará el proceso.

Conclusión
El post es bastante sencillo, técnicamente seguimos si profundizar en los apartados que yo
entiendo clave como son los 'Service Worker' y el cacheo de datos offline, pero si es un
primer punto de partida.

Con esto, hacemos que nuestra aplicación pueda ser accedida por el usuario desde su
pantalla de inicio.

Si lo piensas fríamente añadir una Web al menú de arranque, se parece mucho a añadir un
'Acceso directo' o a añadir un favorito como siempre hemos hecho, pero si es verdad que el
poder indicar cosas como la orientación o el tipo de pantalla, ayuda mucho a dar un aspecto
más nativo a nuestra Web.

En el próximo capítulo, cerraremos esta introducción a PWA intentando cumplir con el


requisito:

La primera carga de nuestra aplicación es rápida hasta con 3G

Para ello, nos centraremos en explicar qué son el patrón 'App Shell' y el patrón PRPL.
Como veremos, estamos hartos de implementarlos en nuestras SPAs :).

Nos leemos :)

16
Capítulo 2 - El manifiesto de nuestra aplicación

17
Capítulo 3 - Los patrones App Shell y PRPL

Capítulo 3 - Los patrones App Shell y


PRPL
Hola de nuevo. Terminamos con este post la introducción a PWA. Por ahora, lo único que
PWA nos está aportando es un lenguaje nuevo y una manera de clasificar todo aquello que
un buen equipo front debería tener en cuenta en sus desarrollos.

Una cosa que me gusta de PWA y de lo que está haciendo Google es que está creando un
repositorio de funcionalidades transversales que muchas veces, desde negocio, no se dan
como importantes por no centrarse en el dominio, pero que pueden afectar mucho a que un
producto sea un éxito y que atraiga a más usuarios.

En el post de hoy nos centraremos en solucionar otro punto del checklist. En esta ocasión
solucionaremos este:

La primera carga de nuestra aplicación es rápida hasta con 3G

Para solucionarlo, necesitamos explicar qué son el modelo App Shell y el patrón PRPL. Dos
términos nuevos que explican algo que, quizá, no nos sea es tan nuevo :)

Veamos:

¿Qué es el modelo App Shell?


PWA está muy preocupado en que la experiencia de nuestra Web, en cualquier dispositivo,
sea la idónea. Si observamos en cómo ha aumentado el consumo de Internet desde el
dispositivo móviles en los últimos años, acertaremos si pensamos que es algo que le
preocupa mucho a Google.

Mejorar la experiencia de usuario de la Web en dispositivos móviles es algo prioritario ahora


mismo. Para ello, es importante que la experiencia sea lo más parecida a la de un aplicativo
nativo. Por tanto, pensemos en los elementos que hacen que una aplicación nativa
conformen una experiencia óptima de uso.

Se me ocurre lo siguiente:

Las aplicaciones nativas son rápidas. Tu accedes desde el menú principal de tu


móvil a una aplicación y en cuestión de un segundo tienes tu interfaz cargada lista para
ser usada.

18
Capítulo 3 - Los patrones App Shell y PRPL

Optimiza los recursos del usuario . Cuando un usuario se descarga una aplicación,
solo se descarga los binarios en su dispositivo una vez. Esto es algo que, por la propia
naturaleza Web, era complicado de llevar a cabo hace años. Cuando un usuario
necesita usar una Web periódicamente, la descarga de recursos es recurrente y por
tanto más costosa - cada vez que consulto la Web, su HTML, CSS, JS y assets son
descargados.

Tiene una inferfaz común para todas las pantallas. Vale, el núcleo central de cada
pantalla cambia, pero los menús, las barras de navegación y los pies de pantalla se
mantienen. En Web no tiene porque ser así, o antiguamente no se tenía tan en cuenta
esto.

Leyendo estas características, seguro que muchos de vosotros y vosotras tenéis una y mil
soluciones para acabar con estos problemas en la Web. Los problemas que planteo suenan
del mundo viejuno, sin embargo, siendo sinceros, no todas las Web han evolucionado como
debieran y aunque esto suena obvio, hay mucho trabajo que hacer.

Por ejemplo, las arquitecturas front de aplicaciones de única página, o SPAs como suelen
conocerse, vinieron para solucionar muchos de estos problemas:

Esta arquitectura nos permite - por fin - crear esta estructura principal que
homogeneice la interfaz . Ya no tengo que crear sistemas de renderizado
complicados para tener un único menú, barra de navegación o pie de página. Las
librerías de enrutado ya nos proporcionan esta funcionalidad.

Los sistemas de cacheo de HTML5 ya nos permitían cachear nuestras aplicaciones


en el navegador.

Y la velocidad dependía mucho del navegador y el código que optimizásemos.


Minificamos y ofuscamos y optimizamos las imágenes para ganar micro segundos y
estamos más concienciados en trabajar sobre esta partes de lo que lo hacíamos antes.

Pero las SPAs nos han traído problemas que estamos intentando solucionar. Por ejemplo:

Crear estos sistemas y con las herramientas que contábamos, nos ha obligado a
empaquetar toda nuestra aplicación (sí, toda) en un único fichero JavaScript. Con lo
que esto supone claro. Ya no solo estoy obligando a que el usuario se descargue todo
el rato mi Web, sino que encima le obligo a descargarse todo, aunque no vaya a hacer
uso de toda la funcionalidad.

Los manifests de HTML5 para indicar el cacheo de recursos nos a ayudado, pero la
experiencia de desarrollo en muchos casos nos ha dado problemas. Se nos ha
complicado bastante el actualizar estos ficheros cacheados cuando hemos querido
añadir nueva funcionalidad o solucionar problemas.

19
Capítulo 3 - Los patrones App Shell y PRPL

Por tanto, Google ha pensado en un término que está a medio camino entre el no hacer
nada por ayudar al usuario y el matar moscas como cañonazos como hacen las SPAs.

Además, estas nuevas técnicas se apoyan en las nuevas APIs para sacar mayor partido al
desarrollo y aunar por fin experiencia tanto de usuario como de desarrollo.

Es lo que se conoce como patrón App Shell o modelo App Shell. Compactar la mínima
funcionalidad común para todas la pantallas de nuestra aplicación, ya sea HTML, CSS y JS,
y cachearla por medio de Services Workers y Cache API.

El resto de la aplicación, se irá cargando bajo demanda del usuario. A nivel de interfaz se
trata de extrapolarlo de esta manera:

Todo lo que es App Shell se compilará junto y se cacheará y todo lo que sea contenido se
irá cargando bajo demanda ya sea de manera manual o por medio de herramientas
automatizadas de cacheo.

¿Qué es el patrón PRPL?

20
Capítulo 3 - Los patrones App Shell y PRPL

Por otro lado, tenemos lo que se está considerado por Google como patrón PRPL. Este
patrón esta en fase de estudio y se trata más de una idea que abarca conceptos sobre
optimización de recursos que de algo mucho más elaborado y abstracto.

Se trata de cómo realizar diferentes acciones para que el usuario final disfrute del contenido
en el menor tiempo posible y en cualquier dispositivo del mundo real.

PRPL son las siglas de:

Push o empaquetado de aquellos recursos que sean indispensables (esto es App


Shell) para el inicio de una aplicación,
Render o el renderizado de las primeras vistas lo antes posible,
Pre-cache o cacheado de aquellos recursos que nosotros intuyamos que van a ser
usados en breve por el usuario,
Lazy-load o carga de recursos bajo demanda y según el usuario los vaya necesitando.

Si nos damos cuenta, sigue mucho de los pasos de lo que ya aporta App Shell y de lo que
las nuevas SPAs intentan hacer. Digamos que PRPL abarca técnicas que ayudan a que
seamos proactivos a la hora de cachear y cargar de manera dinámica y perezosa recursos
de la aplicación.

Es decir, si sabemos que desde una pantalla en particular se puede navegar a otras dos
pantallas que todavía no se han cargado, quizá sería una buena idea que nosotros como
desarrolladores nos encargásemos de pedir esos recursos a nuestros servidores, que los
rendericemos o que ya vengan renderizados - mejor opción - y cachearlos en memoria,
liberando, si hiciese falta claro, recursos ya utilizados.

Todo esto desde procesos que se ejecuten en segundo plano. Si nos damos cuenta,
seguimos sacando partido de Services Workers y API Caché e intentamos aprovechar cada
una de sus posibilidades para conseguir que lo que el usuario demanda, se cargué en el
menor tiempo posible.

Sobre este patrón seguirá saliendo mucha documentación, muchos recursos y librerías que
nos guiarán para conseguir estos casos de uso.

Un poco de código
Ahora bien ¿Cómo se materializa todo esto de App Shell y PRPL a la hora de desarrollar?
Veamos por ejemplo cómo VueJS lo lleva a cabo.

21
Capítulo 3 - Los patrones App Shell y PRPL

AVISO: Crear un App Shell (o paquete mínimo cacheable) y aplicar PRPL no tiene
nada que ver con el framework JavaScript que uses. En el ejemplo uso Vue por mi
propia comodidad, pero cualquiera de las cosas que hago con VueJS las puedes hacer
a mano o con tu framework favorito. VueJS no es una librería específica para
implementar PWA, pero si está muy concienciada con este tipo de técnicas.

Para el ejemplo, vamos a usar la plantilla de vue-cli que la comunidad tiene para PWA.
Para ello ejecutamos el siguiente comando (recuerda tener instalado vue-cli ):

$ vue init pwa app-shell

Esto nos crea un proyecto con lo mínimo PWA necesario con nombre app-shell .

Lo primero que podemos observar es cómo la plantilla se encarga de crear un armazón


mínimo donde se cargue el Header , Footer y demás componentes comunes. Vayamos al
componentes App.vue . Este componente es el encargado de renderizar la layout por
defecto de la app.

https://gist.github.com/jdonsan/63f447d7ed8892b930ae8746e319bdd1

Como ya vimos en el manual de Vue, lo importante de este layout HTML es la etiqueta


router-view . Esta etiqueta de Vue es un componente dinámico. Es la zona en blanco que

estamos reservado para cargar el contenido de la app. El resto de ese template, es lo que
podríamos considerar el App Shell.

Vayamos ahora al router :

// router/index.js

import Vue from 'vue'


import Router from 'vue-router'
import Hello from '@/components/Hello'

Vue.use(Router)

export default new Router({


routes: [
{
path:'/',
name:'Hello',
component:Hello
}
]
})

22
Capítulo 3 - Los patrones App Shell y PRPL

Este fichero se encarga de configurar todas las rutas disponibles en nuestra Web. En el
futuro nos resolverá unos de los requisitos del checklist, pero bueno... por ahora olvidemos
eso y centrémonos.

Es una parte importante porque configurar las rutas y decidir qué componente se tiene que
renderizar es la clave para poder partir nuestro monolito SPA en partes modularizables. Por
ejemplo, añadamos una vista más:

import Vue from 'vue'


import Router from 'vue-router'
import Hello from '@/components/Hello'
import Detail from '@/components/Detail'

Vue.use(Router)

export default new Router({


routes: [
{
path: '/',
name: 'Hello',
component: Hello
},
{
path: '/detail',
name: 'Detail',
component: Detail
}
]
})

Lo que hacemos ahora es añadir una nueva pantalla. Cuando el usuario indique en la URL
/detail , se renderizará este componente Detail que simula una nueva ventana de

detalle y cuando ponga / , volveremos a la pantalla principal.

Esto es un primer paso pero no es el definitivo. Si dejamos esto así y construimos nuestro
paquete de producción ( npm run build ) conseguiremos algo como esto:

23
Capítulo 3 - Los patrones App Shell y PRPL

Está bien porque Webpack (con la configuración por defecto) ha sabido separarme en
diferentes ficheros lo que es lógica de aplicacion ( app ), de lo que son librerías de terceros
( vendor ) y el motor de dependencias de Webpack ( manifest ), pero no estamos
cumpliendo las directrices de App Shell. App sigue teniendo código innecesario. El código
de Detail y Home , no nos es necesario de primeras.

Para solucionar esto, hacemos uso de 'ES Modules' de ES6 y 'Lazy Load' de Webpack.
Esto es tan sencillo como poner en router lo siguiente:

import Vue from 'vue'


import Router from 'vue-router'

Vue.use(Router)

export default new Router({


routes: [
{
path: '/',
name: 'Hello',
component: () => import('@/components/Hello')
},
{
path: '/detail',
name: 'Detail',
component: () => import('@/components/Detail')
}
]
})

24
Capítulo 3 - Los patrones App Shell y PRPL

Ahora en el parámetro component , indicamos una factoría con una arrow function y
usamos el import de esta manera, la carga es en diferido y solo se hará cuando el usuario
vaya a esa vista. Esto Webpack sabe interpretarlo como una rotura del módulo y nos
genera lo siguiente:

Seguimos teniendo los ficheros app , vendor y manifest , pero tenemos cosas nuevas: 0
y 1 son los ficheros de cada una de las pantallas que hemos hecho que se carguen de
manera perezosa. Esto ya es contenido y no App Shell, hemos conseguido esa separación
que las SPAs de otra generación no conseguían por no contar con 'ES Modules', ni
Webpack (o similares).

Lo único que nos queda es cachearlo en el navegador del usuario. Esto también es muy
cómodo para el desarrollador y debería llevarnos poco trabajo. Tenemos dos maneras de
crear este cacheo: el manual y el automático. Yo recomiendo el automático, pero
expliquemos los dos:

Cacheo de recursos de manera manual


Lo que hacemos en este caso es unas la API de caché dentro del evento install del
service worker:

25
Capítulo 3 - Los patrones App Shell y PRPL

const cacheName = 'shell-content';


const filesToCache = [
'/static/js/app.2cbc45bd2965419a4043.js',
'/static/js/vendor.fa1ea1033599b0840fdf.js',
'/static/js/manifest.522a073e0941aec05df8.js',
'/static/css/app.b8e908dd1983cadb5682ced0bf5a9f82.css'
];

self.addEventListener('install', function(e) {
e.waitUntil(
caches.open(cacheName).then(function(cache) {
return cache.addAll(filesToCache);
})
);
});

Es un sistema muy poco cómodo porque indicamos en cada momento que cacheamos.
Tenemos un control de lo que se cachea y de lo que no, pero nos dificulta el cambio de
nombrado de hashes.

¿Y si cuando construimos nuestra aplicación, pudiésemos pre-cachear ya todo lo que se


indique de una manera más dinámica y no tan forzada?

Cacheo de recursos de manera automática


La gente de Google ha creado una librería que se llama sw-precache es una librería que te
habilita un Service Worker para cachear los recursos.

La librería se puede usar tanto en Gulp, como Grunt, pero yo os voy a mostrar cómo se usa
en Webpack. Vayamos al fichero build/webpack.prod.conf.js que es el fichero que se
encarga de construir nuestra aplicación para cuando queremos desplegar en producción.

Vayamos a la parte de plugins y observemos estas líneas:

// build/webpack.prod.conf.js

...
newSWPrecacheWebpackPlugin({
cacheId:'my-vue-app',
filename:'service-worker.js',
staticFileGlobs: ['dist/**/*.{js,html,css}'],
minify:true,
stripPrefix:'dist/'
})
...

26
Capítulo 3 - Los patrones App Shell y PRPL

Esta es la abstracción de la librería sw-precache por parte de Webpack. Lo que se nos pide
es: los ficheros a cachear ( staticFileGlobs ), el nombre con el fichero que se va a generar
( filename ) y dónde va a colocarlo ( stripPrefix ). Esto, una vez que se compile, creará un
fichero /dist/service-worker.js .

Lo único que nos queda es cargarlo en el index.html . Esto lo hacemos así:

// build/webpack.prod.conf.js

...
new HtmlWebpackPlugin({
...
serviceWorkerLoader:`
<script>${loadMinified(path.join(__dirname,'./service-worker-prod.js'))}<scrip
t>
`
}),
...

Que lo único que hace es incrustar el fichero dentro del index.html en donde se encuentre
la etiqueta serviceWorkerLoader .

Y ya está. Ejecuta el ejemplo (usa http-server , por ejemplo), pulsa F5 varias veces y
comprobarás en 'Developer Tools' en la pestaña de 'Network' que los recursos son cargados
desde la caché del navegador.

Conclusión
Parece que la propia plantilla de Vue para cumplir con el checklist de Google ya tiene en
cuenta todo esto :). Las nuevas plataformas de desarrollo front como ReactJS, Angular o
VueJS ya tienen muy en cuenta todas estás técnicas.

Webpack y otros empaquetadores de aplicaciones llevan unos años ayudando a que esto
sea posible y los Services Workers y la API Caché son la puntilla que nos faltaba para por
fin ser competentes contra aplicaciones nativas.

Los conceptos no son todo lo innovador que parecían, pero están ahí y nos permiten crear
un lenguaje fácil que otros perfiles menos técnicos quizá entiendan mejor. Es importante
concienciar a todos los integrantes de un equipo que este tipo de técnicas son importantes,
por tanto, el estandarizar y facilitar el conocimiento es algo que creo prioritario.

Aquí terminamos la introducción. En los dos siguientes módulos nos pondremos más
técnicos y por fin nos centraremos en aprender todo lo necesario sobre Service Workers y
API Caché.

27
Capítulo 3 - Los patrones App Shell y PRPL

Nos leemos :)

28
Capítulo 4 - Conceptos básicos

Capítulo 4 - Conceptos básicos sobre


Service Workers
Continuamos con PWA. Creo que ya tenemos una idea de lo que nos enfrentamos en esta
serie, por tanto, centrémonos en apartados más técnicos para poder cumplir con los
objetivos que Google nos aconseja tener.

Durante algunas semanas nos centraremos en una de las API que quieren revolucionar la
forma en la que entendemos el front y en cómo gestionamos y administramos los recursos
de nuestro navegador: Los Workers.

En nuestro caso los Workers que más nos interesan son los Service Workers. En el posts
de hoy, aprenderemos a diferenciar los tipos de Workers que existen, en qué nos puede
ayudar cada uno y cómo les podemos sacar provecho para crear aplicaciones Web que le
den guerra a las aplicaciones nativas.

¿Qué son?
Como ya sabemos - y si no, te lo cuento ahora - JavaScript es un lenguaje monohilo. Esto
quiere decir que toda la interpretación del código de nuestra aplicación va a ser atendido
simplemente en un único hilo de ejecución.

Su forma de realizar diferente acciones es por medio del uso de la entrada y salida de
manera asíncrona y controlando todas las acciones por medio de un bucle que va
decidiendo que se tiene que ir haciendo en cada momento.

Claro, esto en aplicaciones simples, no supone ningún problema, pero ¿qué ocurre si
necesitamos ejecutar una Web que requiere mucho recursos de máquina? Pues que el
sistema de único hilo no funciona.

Pongámonos en el caso de uso en la que nuestro navegador tiene que renderizar muchas
animaciones sin que estas sufran de ningún tipo de lag ni de parón incomodo para el ojo
humano. Imaginemos que a la vez que mostramos la animación, se necesita realizar un
procesado de datos por medio de JavaScript.

Bueno, puede ocurrirnos algo como esto:

29
Capítulo 4 - Conceptos básicos

Es lo que os comentaba. Esto es una animación de kirby que en cuanto ejecutamos un


algoritmo para calcular muchos número aleatorios se queda congelada. Este lag se debe a
que JavaScript ejecuta todo en un solo hilo de ejecución y la animación tiene que parar para
dejar paso al cómputo del algoritmo.

Bloquear animaciones es una mala idea si queremos ser competitivos en el mundo móvil.
Conseguir que el navegador reproduzca 60 frames por segundo (que es lo que el ojo
humano sabe interpretar como un movimiento real) es uno de nuestros trabajos.

Para ello vamos a tener que trabajar con nuevas herramientas que nos lo permitan.
JavaScript por si mismo no nos va a poder ayudar por su propia naturaleza. ¿Entonces?

En otros lenguajes de programación la ejecución multihilo, la posibilidad de lanzar


ejecuciones concurrentes es algo asimilado desde hace décadas y supuso un avance en el
procesamiento de información. Java, C# son lenguajes que ya soportan la gestión de
recursos en paralelos.

30
Capítulo 4 - Conceptos básicos

En JavaScript se ha implementado lo que se conoce como Workers, que no son otra cosa
que la posibilidad de ejecutar tareas en otro hilos de ejecución. El poder paralelizar tareas
nos ayuda en muchas cosas por que es una buena solución para lanzar tareas en
segundo plano. No todo el procesamiento que hace una aplicación tiene que ver con lo
que mostramos al usuario.

Por tanto, podemos estar:

Monitorizando muchas cosas sin que el usuario se de cuenta,


Descargando información que el usuario usará más tarde,
Intentando sincronizar información del usuario con nuestro servidor que en otro
momento fue imposible debido a la conexión de datos.

Estas situaciones son resueltas con dos tipos diferentes de Workers:

Web Workers: cuya API puedes encontrar en Mozilla y que nos ayudan la ejecución en
paralelo de script de forma intensiva. Se generan dos contextos globales dentro de
nuestro navegador para que podamos hacer tareas que no bloqueen la IU.
Service Workers: cuya API puedes encontrar también en Mozilla y que nos ayudan a
realizar tareas que tienen que ver con la solicitud de red. Es un buen proxy de
comunicaciones con otros sistemas de red. Un Web Worker es un tipo de Service
Worker.

Puede que volvamos más adelante a los Web Workers, pero detengámonos en los Service
Workers debido a su gran potencial de comunicación y no solo a su labor de paralelización
de recursos.

¿Para qué pueden usarse?


Los Service Workers nos interesan en el desarrollo de una PWA por 4 utilidades
favorecedoras para nosotros:

1. Nos permiten realizar tareas de cacheo de información . Puedo estar descargando


vistas y datos en segundo plano de nuestros servidores sin que el usuario sea
consciente. Este cacheo puede ayudar a la fluidez de la aplicación y a seguir el patrón
PRPL que comentamos en el post anterior.
2. Nos permite tener un sistema por donde recibir notificaciones Push . Abrir un
canal de comunicación con un servidor y que el propio servidor sepa enviarnos
información de forma proactiva. Podemos dejar estas tareas en un segundo plano sin
entorpecer en el hilo principal.
3. Nos permite sincronizar datos en segundo plano. Puede que la conexión se haya
caído y que tengamos datos no sincronizados en servidor. En vez de dejar al usuario

31
Capítulo 4 - Conceptos básicos

colgado, almacenamos y enviamos cuando sea posible.


4. Permitir instalar y actualizar nuestra aplicación . Podemos dejar un hilo secundario
comprobando cuando hay cambios en la aplicación y que esta los instale cuando los
haya.

Son 4 tareas que premian el trabajo offline, la velocidad del sistema en términos generales y
el ahorro de recursos. Justamente lo que una buena PWA nos demanda. Por tanto, los
Service Workers son uno de los pilares en los que una aplicación Web del futuro se
sustenta.

¿Qué tengo que tener en cuenta cuando los


use?
Ahora bien, los Service Workers no son el maná ni son algo tan del presente como
podamos pensar. Detengámonos un rato por ejemplo en qué cosas tenemos que tener en
cuenta si queremos hacer uso de ellos:

Un Service Worker se ejecuta en otro contexto diferente al del hilo principal. Esto
parece obvio, pero una de las primeras consecuencias es que desde él no tenemos
acceso al DOM. Al DOM solo se puede acceder desde el hilo principal. Podemos
comunicarnos con el hilo principal y que el ejecute acciones por nosotros, pero ya
tenemos que programar esa sincronización.
Un Service Worker está pensado para el cómputo asíncrono donde no existe el
bloqueo del proceso. Por tanto, ten en cuenta qué partes de la API de JavaScript son
síncronas porque no podrás hacer uso de ellas en un Service Worker. Por ejemplo el
uso de localStorage y el uso de XHR de manera síncronas dentro de un Service
Worker no son posibles porque bloquearías el proceso cuando es lo que intentamos
evitar.
Un Service Worker trata de levantar un nuevo contexto y tiene control total sobre las
comunicaciones que tiene el sistema. Esto puede traer a la larga vulnerabilidades así
que un Service Worker siempre tiene que ser ejecutado sobre redes HTTPS para evitar
ataques Man In The Middle. Al obligar HTTPS siempre nos aseguramos que el
Services Worker está cargado por nuestro servidor y no por terceras partes. Además, y
como apunte, ten en cuenta que en Firefox los Service Workers no funcionan en modo
privado o incógnito.

Por tanto y en resumen: el uso de un Service Worker es algo muy especifico y muchas
acciones que tienen que ir en el hilo principal de ejecución, no tendrán cabida dentro de él,
tenlo en cuenta.

32
Capítulo 4 - Conceptos básicos

Otro tema importante es cómo se encuentra la especificación de la API implementada en


los navegadores. Veamos el CanIUse para Service Workers a día de hoy:

Tiene un progreso prometedor, pero todavía hay demasiados navegadores que pasan de
ellos. Apple ha comentado que el año que viene entran dentro de su Roadmap, pero hasta
entonces recuerda que hacer una PWA para un dispositivo iOS es algo que no es posible. Y
esto es importante porque puede que a negocio le eche para atrás aventurarse en el
desarrollo de una PWA si su target va a verse reducido.

Por tanto, cuidado. Incluyamos Service Workers si pueden ayudarnos a hacer mejores
aplicaciones, pero tengamos en cuenta todo lo anterior. En estos primeros años, hasta que
los Service Workers se normalicen en todos los navegadores, programemos de manera
defensiva y progresiva, comprobemos en todo momento si la funcionalidad está disponible
para evitar fallos innecesarios.

Registrando un Service Worker


No quiero dejar el posts sin incluir algo práctico, pero como imagino que ya tenemos
bastante información por hoy, vamos a centrarnos simplemente en cómo debemos registrar
un Service Worker en nuestro sistema. Como veremos es un método bastante desacoplado
que piensa en todos los problemas que nos podamos encontrar en dispositivos legacy.

Lo primero que tenemos que tener en cuenta es desde dónde queremos que tenga acceso
el Service Worker. No es lo mismo registrar un Service Worker que se encuentra en la raíz
que un Service Worker que se encuentre en una ruta interna. Es decir, que si tu registras un

33
Capítulo 4 - Conceptos básicos

Service Worker que tengas en la raíz de tu proyecto, tendrás acceso a todos los recursos
desde la raíz.

Pero que si tu Service Worker se encuentra en /example solo tendrá acceso a recursos de
red sobre esta URL. Lo que provoca que si tengo un fichero app.css solo pueda trabajar
con él si se encuentra en /example/app.css . Nuestro SW se encontrará en la raíz y se
llamará sw.js .

Una vez que tenemos claro esto, programamos nuestro register . Lo primero que vamos a
hacer es curarnos de salud y comprobar que el navegador desde donde se ejecuta nuestra
aplicación tiene disponible la API de Service Worker.

Esto se consigue así:

if ('serviceWorker' in navigator) {
// código
}

Una vez que vemos que efectivamente tenemos disponible la API, podemos registrar el SW
hospedado en nuestro servidor. Ahora bien, detengámonos un momentos. Registrar e
instalar el SW nos llevará un tiempo de cómputo que asume el hilo principal. Por tanto,
puede que reduzcamos el rendimiento de nuestra aplicación. Como un SW es una
funcionalidad por lo general añadida, pero que no es crítica, vamos a esperar a registrarlo
una vez que todos los recursos críticos hayan sido cargados.

Para ello, usemos el evento load para estar seguros que solo se registrará cuanto todo esté
listo:

if ('serviceWorker' in navigator) {
window.addEventListener('load', function () {
// código
}
}

Cuidado con esto, porque dependiendo del tipo de aplicación que desarrolles, puede que
esta espera no sea suficiente todavía. Imagina que nada mas empezar tu aplicación, se va
a ejecutar una animación o que tu framework favorito necesita un tiempo para configurar
todo lo necesario para funcionar.

Puede que el registro tenga que posponerse un poco más, así que recuerda posponer el
registro lo máximo que puedas hasta que estés seguro que el sistema se encontrará en
cierto reposo y que no mines la experiencia de usuario.

Lo ultimo ya es hacer el registro:

34
Capítulo 4 - Conceptos básicos

if ('serviceWorker' in navigator) {
window.addEventListener('load', function () {
navigator.serviceWorker.register('/sw.js')
.then((registration) => console.log(registrarion.scope))
.catch(error) => console.error(error));
}
}

Y con eso, el navegador sabe como instalar el Worker y ejecutar lo que hayamos
programado en sw.js .

Puedes llamar a register() sin ningún problema cada vez que cargues la página. El
navegador determinará si el Service Worker está registrado o no, y actuará según
corresponda.

En próximos capítulos, estudiaremos toda la API y explicaremos cómo sacarle partido. Por
ahora es todo!

Nos leemos :)

Recursos utilizados para este capítulo:


The Basics of Web Workers
Service Workers API
Workers API
Service Workers según Google
Diferencias entre Web Workers, Service Workers y Web Sockets
Slides de Ramón Guijarro en su charla 'Web Multihilo'
Cascadia 2016

35