¿Enseñarle cómo crear una aplicación fuera de línea?

Autor: Millas

¿Qué es una aplicación fuera de línea?

La aplicación sin conexión se refiere al uso de la tecnología de almacenamiento en caché sin conexión para almacenar en caché los recursos localmente después de cargarlos por primera vez y devolver el archivo local directamente cuando se acceda a él la próxima vez, incluso si no hay conexión de red.

ventaja:

  • También puede abrir páginas web sin una red.
  • Dado que algunos de los recursos almacenados en caché se cargan directamente desde el área local, puede acelerar la velocidad de carga de las páginas web para los usuarios y reducir la presión del servidor y los costos del tráfico de transmisión para los operadores de sitios web.

El núcleo de las aplicaciones fuera de línea es la tecnología de almacenamiento en caché fuera de línea, que actualmente es Service Workers relativamente maduro. Puede controlar la lógica del almacenamiento en caché a través del código JavaScript. En otras palabras, este proceso se puede entregar al front-end para que lo maneje.

¿Por qué lo necesitas?

Las aplicaciones fuera de línea son en realidad un tipo de tecnología de almacenamiento en caché. Algunas personas pueden pensar que la estrategia de almacenamiento en caché HTTP se ha desarrollado con bastante madurez, entonces, ¿por qué necesita Service Workers? Los desarrolladores front-end pensarán: "¿Por qué confiamos en el back-end para los asuntos del navegador? El back-end solo necesita proporcionar datos. Quiero controlar cosas como el almacenamiento en caché".

¿Qué son los trabajadores de servicios?

Los Service Workers son scripts que se ejecutan en segundo plano en el navegador y su ciclo de vida es completamente independiente de las páginas web. No tiene acceso directo al DOM, pero puede comunicarse con el proceso de UI enviando mensajes a través de la interfaz postMessage. Interceptar solicitudes de red es una función importante de Service Workers, a través de la cual puede completar funciones como el almacenamiento en caché sin conexión, la edición de respuestas y el filtrado de respuestas.

Service Worker no está especialmente diseñado para el almacenamiento en caché, también puede resolver problemas como la inserción de aplicaciones web, el cálculo largo en segundo plano, etc.

La forma más fácil de saber si un navegador es compatible con Service Workers es a través del siguiente código:

// 如果 navigator 对象上存在 serviceWorker 对象,就表示支持
if (navigator.serviceWorker) {
  // 通过 navigator.serviceWorker 使用
}

Registrar trabajadores de servicios

Para acceder a Service Workers a una página web, debe registrar un script que describa la lógica de Service Workers después de cargar la página web. Normalmente index.htmlse registra en , el código es el siguiente:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
   
    </head>
    <body>
        <script>
            if ('serivceWorker' in navigator) {
                navigator.serviceWorker.register('/sw.js')
                    .then(reg => console.log('Service worker registered successfully!'))
                    .catch(err => console.log('Service worker failed to register!'));
            }
        </script>
    </body>
</html>

La lógica de Service Workers no tendrá efecto cuando la página web se abra por primera vez porque el script no se ha cargado ni registrado, pero la lógica del script tendrá efecto cuando la página web se vuelva a abrir más tarde.

En Chrome, chrome://inspect/#service-workerspuede .

Implementar el almacenamiento en caché sin conexión

Después de un registro exitoso, los Service Workers enviarán algunos eventos en su ciclo de vida y harán algunas cosas en nodos de tiempo específicos al escuchar los eventos correspondientes.

En el script de Service Workers, se introdujo una nueva palabra clave para selfrepresentar la instancia actual de Service Workers.

Después de que Service Workers se haya instalado correctamente, se enviará un installevento y la lógica de almacenamiento en caché de los recursos debe ejecutarse en este evento. El código de implementación es el siguiente:

sw.js

// 当前缓存版本的唯一标识符,用当前时间代替
var cacheKey = new Date().toISOString();

// 需要被缓存的文件的 URL 列表
var cacheFileList = [
  '/index.html',
  '/app.js',
  '/app.css'
];

// 监听 install 事件
self.addEventListener('install', function (event) {
  // 等待所有资源缓存完成时,才可以进行下一步
  event.waitUntil(
    caches.open(cacheKey).then(function (cache) {
      // 要缓存的文件 URL 列表
      return cache.addAll(cacheFileList);
    })
  );
});

A continuación, debe escuchar el evento de solicitud de red para interceptar la solicitud y reutilizar el caché. El código es el siguiente:

self.addEventListener('fetch', function(event) {
  event.respondWith(
    // 去缓存中查询对应的请求
    caches.match(event.request).then(function(response) {
        // 如果命中本地缓存,就直接返回本地的资源
        if (response) {
          return response;
        }
        // 否则就去用 fetch 下载资源
        return fetch(event.request);
      }
    )
  );
});

El código anterior ha implementado la función de almacenamiento en caché, pero si el código cambia, también debemos descargar nuevos recursos y actualizar los recursos almacenados en caché.

El navegador tiene los siguientes mecanismos para Service Workers:

  1. Cada vez que abra una página web que tenga acceso a Service Workers, el navegador volverá a descargar el archivo de script de Service Workers (así que tenga cuidado de que el archivo de script no sea demasiado grande).Si hay una diferencia de bytes con el archivo registrado actualmente , será considerado un "trabajador de nuevo servicio".
  2. Se iniciará un nuevo subproceso de Service Workers y se activará su evento de instalación.
  3. Cuando se cierra la página actualmente abierta en el sitio web, el antiguo subproceso de Service Workers finalizará y el nuevo subproceso de Service Workers tomará el control.
  4. Una vez que el nuevo subproceso de Service Workers toma el control, se activa su evento de activación.

Podemos eliminar el caché original en el evento de activación.

// 当前缓存白名单,在新脚本的 install 事件里将使用白名单里的 key 
var cacheWhitelist = [cacheKey];

self.addEventListener('activate', function(event) {
  event.waitUntil(
    caches.keys().then(function(cacheNames) {
      return Promise.all(
        cacheNames.map(function(cacheName) {
          // 不在白名单的缓存全部清理掉
          if (cacheWhitelist.indexOf(cacheName) === -1) {
            // 删除缓存
            return caches.delete(cacheName);
          }
        })
      );
    })
  );
});

Esto completa la actualización.

Implementar almacenamiento en caché fuera de línea en Vue

La mayoría de nuestros proyectos actuales están integrados en base a andamios, como recibir vue. Antes de publicar, no estamos seguros de cuántos archivos se empaquetarán. Si la estructura del directorio de archivos de la salida de compilación es:

├── app_4c3e186f.js
├── app_7cc98ad0.css
└── index.html

sw.jsEntonces cacheFileListel valor en el archivo debe ser:

var cacheFileList = [
  '/index.html',
  'app_4c3e186f.js',
  'app_7cc98ad0.css'
];

Sin embargo, los nombres de estos archivos a menudo no son fijos. Por ejemplo, algunos son nombrados por hash. En este caso, ¿cómo determinar la lista de rutas de archivos que deben almacenarse en caché?

Esto debe implementarse en el paquete web con la ayuda de un complemento:

const path = require('path');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const { WebPlugin } = require('web-webpack-plugin');
const ServiceWorkerWebpackPlugin = require('serviceworker-webpack-plugin');

module.exports = {
  entry: {
    app: './main.js'// Chunk app 的 JS 执行入口文件
  },
  output: {
    filename: '[name].js',
    publicPath: '',
  },
  module: {
    rules: [
      {
        test: /\.css$/,// 增加对 CSS 文件的支持
        // 提取出 Chunk 中的 CSS 代码到单独的文件中
        use: ExtractTextPlugin.extract({
          use: ['css-loader'] // 压缩 CSS 代码
        }),
      },
    ]
  },
  plugins: [
    // 一个 WebPlugin 对应一个 HTML 文件
    new WebPlugin({
      template: './template.html', // HTML 模版文件所在的文件路径
      filename: 'index.html' // 输出的 HTML 的文件名称
    }),
    new ExtractTextPlugin({
      filename: `[name].css`,// 给输出的 CSS 文件名称加上 Hash 值
    }),
    new ServiceWorkerWebpackPlugin({
      // 自定义的 sw.js 文件所在路径
      // ServiceWorkerWebpackPlugin 会把文件列表注入到生成的 sw.js 中
      entry: path.join(__dirname, 'sw.js'),
    }),
  ],
  devServer: {
    // Service Workers 依赖 HTTPS,使用 DevServer 提供的 HTTPS 功能。
    https: true,
  }
};

Debe modificar el sw.jsarchivo con valores estáticos escritos cacheFileListde la siguiente manera:

// 需要被缓存的文件的 URL 列表
var cacheFileList = global.serviceWorkerOption.assets;

Tenga en cuenta que se debe utilizar el protocolo https.

Resultados de la validación

Para verificar que Service Workers y el caché funcionen, debe verificar las herramientas de desarrollo de Chrome.

Al abrir la columna Trabajadores de servicios de aplicaciones de la herramienta para desarrolladores, puede ver los Trabajadores de servicios registrados en la página actual.

Figura 3.12.1 Ver los Service Workers registrados en la página actual

{{o.nombre}}
{{m.nombre}}

Supongo que te gusta

Origin my.oschina.net/u/3620858/blog/5514292
Recomendado
Clasificación