1. Что такое ПВА
Полное название PWA — Progressive Web App, то есть прогрессивное веб-приложение.
Приложение PWA — это сначала веб-страница, а приложение веб-страницы может быть написано с помощью веб-технологий. Затем добавляются App Manifest и Service Worker для реализации установки PWA и автономных функций.
- Его можно добавить на главный экран, щелкните значок главного экрана, чтобы реализовать анимацию запуска и скрыть адресную строку.
- Реализовать функцию автономного кэширования, даже если мобильный телефон пользователя не подключен к сети, некоторые автономные функции все же можно использовать.
- Реализован push сообщений
Вышеуказанные функции постепенно сделают веб-приложения ближе к нативным приложениям.
2. Функции ПВА
- Прогрессивный: гарантирует, что каждый пользователь может открыть страницу
- Отзывчивый: ПК, мобильный телефон, планшет, независимо от формата, формат веб-страницы может быть идеально адаптирован
- Автономное приложение: помогите пользователям открывать веб-страницы без доступа в Интернет, здесь вам понадобится помощь Service Worker.
- APPification: возможность взаимодействовать с пользователями, как APP
- Частое обновление: как только на веб-странице происходят какие-либо изменения, они могут быть немедленно отражены на стороне пользователя.
- Безопасность: PWA основан на протоколе HTTPS.
- Доступен для поиска: можно искать по двигателям
- Push: отправляйте новые сообщения, не открывая веб-страницу.
- Устанавливаемый: возможность добавить Интернет на рабочий стол, как приложение.
- Jumpable: переход на вашу веб-страницу всего одним подключением
3. Как внедрить PWA
Упомянутое выше PWA может реализовывать добавление веб-приложения на главный экран и кэширование в автономном режиме. открытие браузера. В родном приложении функция отправки сообщений в автономном режиме.
Итак, для этих реализаций, от чего зависит PWA?
В основном зависит от manifest.json и сервисного работника (может быть записан в виде файла с именем SW.js в проекте и импортирован в проект)
manifest.json вводится в проект как файл формата json, который в основном используется для добавления страниц PWA на главный экран, определения URL-адреса при запуске приложения (поскольку приложение PWA по сути представляет собой сеть) и т. д.
4.Service Worker
Service Worker — это веб-API, предложенный командой Chrome и предназначенный для предоставления веб-приложениямРасширенный устойчивыйВозможность фоновой обработки. По сравнению с предыдущим Web Worker, который представляет собой решение для кэширования вне основного потока, Service Worker является постоянным. Поскольку веб-воркер является временным, результаты того, что он делает каждый раз, не могут быть сохранены.Если такая же сложная операция будет выполняться в следующий раз, потребуется время, чтобы выполнить ее снова.
Сервисные работники действуют как перехватчик между сервером и веб-страницей, способный перехватывать входящие и исходящие HTTP-запросы, предоставляя вам полный контроль над вашим веб-сайтом.
Основная особенность
- После того, как страница зарегистрирована и успешно установлена, она работает в фоновом режиме браузера, на нее не влияет обновление страницы, и она может отслеживать и перехватывать HTTP-запросы всех страниц в пределах области действия.
- Веб-сайты должны использовать HTTPS. За исключением отладки с использованием локальной среды разработки (например, с использованием localhost для имени домена).
- Работая в фоновом режиме браузера, он может контролировать все запросы страниц в рамках открытой области.
- Отдельная область видимости, отдельная среда выполнения и поток выполнения
- Страница DOM не может быть изменена. Но это можно обработать через механизм событий
- поток обслуживания, управляемый событиями
Поскольку сервис-воркеры требуют среды HTTPS, мы обычно можем прибегнуть кgithub pageНаучитесь отлаживать. Конечно, когда общий браузер позволяет отлаживать Service Worker, хост
localhost
или127.0.0.1
Также хорошо.Механизм кэширования Service Worker зависит отCache APIосуществленный
полагатьсяHTML5 fetch API
полагатьсяPromiseвыполнить
Чтобы установить Service Worker, нам нужно начать установку, зарегистрировав Service Worker в основном потоке js ( js на обычных страницах), этот процесс сообщит браузеру, где находится файл JavaScript нашего потока Service Worker.
if ('serviceWorker' in navigator) {
window.addEventListener('load', function () {
navigator.serviceWorker.register('/sw.js', {scope: '/'})
.then(function (registration) {
// 注册成功
console.log('ServiceWorker registration successful with scope: ', registration.scope);
})
.catch(function (err) {
// 注册失败:(
console.log('ServiceWorker registration failed: ', err);
});
});
}
По этому коду в первую очередь судят о доступности Service Worker API, если он будет поддерживаться, то мы продолжим говорить о реализации, иначе не будем об этом.
Если поддерживается, на странице
onload
при регистрации на/sw.js
сервисный работник.Каждый раз, когда страница успешно загружается, она будет вызываться
register()
метод, браузер определит, был ли зарегистрирован поток Service Worker, и обработает его соответствующим образом.-
Параметр области действия метода register является необязательным и используется для указания подкаталога содержимого, которым должен управлять Service Worker. Файл сервис-воркера в этой демонстрации находится в корневом домене, а это означает, что областью действия сервис-воркера будет весь исходный код.
о
register
Параметр области действия метода должен быть объяснен: поток Service Worker получит событие выборки всех элементов в каталоге домена, указанном в области действия.Если файл javaScript нашего Service Worker находится в/a/b/sw.js
, если значение области не передано, значение области/a/b
.Значение значения области видимости состоит в том, что если значение области видимости равно
/a/b
, то поток Service Worker может захватывать путь только как/a/b
начиная с (/a/b/page1
,/a/b/page2
, ...) событие выборки страницы. По значению области мы также можем видеть, что Service Worker не обслуживает ни одной страницы, поэтому глобальные переменные нужно использовать с осторожностью в логике js Service Worker. then()
Функция цепи вызывает наше обещание, когда обещание разрешится, когда внутри кода выполняется.В конце мы приковали
catch()
Функция, которая будет выполняться только при отклонении обещания.
4.1.2 Установка
После того, как ваш Service Worker успешно зарегистрирован, у нас уже есть рабочий контекст, принадлежащий вашему собственному веб-приложению в нашем браузере. В это время браузер будет пытаться установить и активировать страницы на вашем сайте без остановок. Он, и здесь может выполнять кэширование статических ресурсов.
Мы свяжем событие установки в файле Service Worker.После того, как Service Worker будет успешно установлен, событие установки будет запущено.
Событие установки обычно используется для заполнения возможностей автономного кэширования вашего браузера. Для этого мы используем новый API кэша хранилища подписей Service Worker — глобальный объект в Service Worker, который позволяет нам хранить ресурсы из сетевых ответов и генерировать ключи на основе их запросов. Этот API работает так же, как стандартный кеш браузера, но только для домена вашего сайта. Он сохраняется до тех пор, пока вы не скажете ему не сохранять его, и вы получите полный контроль.
Использование localStorage очень похоже на использование кеша Service Worker, но, поскольку localStorage — это синхронное использование, его нельзя использовать в Service Worker. IndexedDB также может хранить данные в Service Worker.
// 监听 service worker 的 install 事件
this.addEventListener('install', function (event) {
// 如果监听到了 service worker 已经安装成功的话,就会调用 event.waitUntil 回调函数
event.waitUntil(
// 安装成功后操作 CacheStorage 缓存,使用之前需要先通过 caches.open() 打开对应缓存空间。
caches.open('my-test-cache-v1').then(function (cache) {
// 通过 cache 缓存对象的 addAll 方法添加 precache 缓存
return cache.addAll([
'/',
'/index.html',
'/main.css',
'/main.js',
'/image.jpg'
]);
})
);
});
Здесь мы добавляем прослушиватель событий установки, а затем подбираем прослушиватель событий
ExtendableEvent.waitUntil()
Метод. Это гарантирует, что Service Worker не будет установлен до тех пор, пока код внутри waitUntil() не завершит выполнение.существует
waitUntil()
внутри мы использовалиcaches.open()
метод для создания нового кеша с именем v1, который будет первой версией кеша ресурсов нашего сайта. Он возвращает обещание создать кеш, и когда оно разрешается, мы вызываем метод для созданного экземпляра кеша (Cache API).addAll()
, аргументом этого метода является массив URL-адресов, относящихся к источнику, которые представляют собой список ресурсов, которые вы хотите кэшировать.Если обещание отклонено, установка завершится ошибкой, и рабочий ничего не сделает. Это также нормально, потому что вы можете исправить свой код и повторить попытку при следующей регистрации.
После успешного завершения установки Service Worker активируется. Это не будет иметь никакого значения при первой регистрации/активации вашего сервисного работника. Но когда Service Worker обновляется, это не то же самое.
4.1.3 Пользовательский ответ на запрос
На этом этапе вы действительно можете кэшировать ресурсы своего сайта, и вам нужно указать Service Worker использовать кэшированный контент для каких-либо действий. С событием выборки это легко сделать.
Каждый раз, когда запрашивается любой ресурс, контролируемый Service Worker, будет инициировано событие fetch.Эти ресурсы включают HTML-документы в указанной области действия и любые другие ресурсы, на которые есть ссылки в этих HTML-документах (например,index.html
Инициируется междоменный запрос на встраивание образа, который также будет проходить через Service Worker), и образ прокси-сервера Service Worker потихоньку появляется, и хук этого прокси-сервера основан на двух мощных инструментах: события области действия и выборки.Управление запросами на сайте может быть хорошо организовано.
Вы можете добавить прослушиватель событий выборки в Service Worker, а затем вызвать событие для события.respondWith()
метод для перехвата наших HTTP-ответов, а затем вы можете использовать свою собственную магию для их обновления.
this.addEventListener('fetch', function (event) {
event.respondWith(
caches.match(event.request).then(function (response) {
// 来来来,代理可以搞一些代理的事情
// 如果 Service Worker 有自己的返回,就直接返回,减少一次 http 请求
if (response) {
return response;
}
// 如果 service worker 没有返回,那就得直接请求真实远程服务
var request = event.request.clone(); // 把原始请求拷过来
return fetch(request).then(function (httpRes) {
// http请求的返回已被抓到,可以处置了。
// 请求失败了,直接返回失败的结果就好了。。
if (!httpRes || httpRes.status !== 200) {
return httpRes;
}
// 请求成功的话,将请求缓存起来。
var responseClone = httpRes.clone();
caches.open('my-test-cache-v1').then(function (cache) {
cache.put(event.request, responseClone);
});
return httpRes;
});
})
);
});
мы можемinstall
кэширование статических ресурсов приfetch
Обработка обратных вызовов событий к запросу страницы прокси-сервера для достижения динамического кэширования ресурсов.
Можно сравнить два способа:
Преимущество установки при установке состоит в том, что она может быть отключена после второго посещения, но недостатком является то, что URL-адрес, который необходимо кэшировать, необходимо вставить в скрипт во время компиляции, что увеличивает объем кода и снижает удобство сопровождения;
Преимущество on fetch в том, что нет необходимости менять процесс компиляции и не генерируется дополнительный трафик, а недостатком в том, что требуется еще одно посещение, чтобы быть доступным в оффлайне.
В дополнение к статическим страницам и файлам, если данные Ajax должным образом кэшируются для обеспечения реальной доступности в автономном режиме, на этом этапе может потребоваться некоторый рефакторинг существующего веб-приложения для разделения данных и шаблонов.
4.1.4 Обновление версии Service Worker
/sw.js
Управляет кэшированием ресурсов страницы и запросов. Что делать, если стратегию кэширования необходимо обновить? то есть, если/sw.js
А если обновление?/sw.js
Как обновить себя?
если/sw.js
Содержимое обновляется, при посещении страницы сайта браузер получает новый файл и сравнивает его побайтно./sw.js
Когда файл будет найден другим, он будет думать, что есть обновление для запуска.алгоритм обновления, который устанавливает новый файл и запускает событие установки. Но старый сервис-воркер, который уже находится в активном состоянии, в это время все еще работает, а новый сервис-воркер перейдет в состояние ожидания после завершения установки. Пока все открытые страницы не будут закрыты, старый сервис-воркер автоматически останавливается, и новый сервис-воркер не вступит в силу на следующей повторно открытой странице.
4.1.5 Автоматически обновлять все страницы
Что делать, если вы хотите, чтобы все страницы обновлялись автоматически вовремя, когда выходит новая версия? Может выполняться в событии установкиself.skipWaiting()
Метод пропускает состояние ожидания и переходит непосредственно к фазе активации. затем вactivate
Когда происходит событие, путем выполненияself.clients.claim()
способ обновления Service Worker на всех клиентах.
// 安装阶段跳过等待,直接进入 active
self.addEventListener('install', function (event) {
event.waitUntil(self.skipWaiting());
});
self.addEventListener('activate', function (event) {
event.waitUntil(
Promise.all([
// 更新客户端
self.clients.claim(),
// 清理旧版本
caches.keys().then(function (cacheList) {
return Promise.all(
cacheList.map(function (cacheName) {
if (cacheName !== 'my-test-cache-v1') {
return caches.delete(cacheName);
}
})
);
})
])
);
});
Еще одно замечание,/sw.js
Файл может быть связан с проблемами кэширования браузера. Когда файл изменяется, браузер по-прежнему использует старый файл. Это может привести к неотвечающим обновлениям. Если вы столкнулись с этой проблемой, вы можете попробовать следующее: добавить правило фильтрации для файла на веб-сервере, не кэшировать или установить более короткий срок действия.
4.1.6 Обновление Service Worker вручную
На странице вы можете вручную использоватьRegistration.update()
возобновить.
var version = '1.0.1';
navigator.serviceWorker.register('/sw.js').then(function (reg) {
if (localStorage.getItem('sw_version') !== version) {
reg.update().then(function () {
localStorage.setItem('sw_version', version)
});
}
});
Особенностью Service Worker является то, что в дополнение к обновлению, инициированному браузером, он также применяет особую стратегию кэширования: если файл не обновлялся в течение 24 часов, он будет принудительно обновлен при срабатывании Update. Это означает, что в худшем случае Service Worker будет обновляться раз в сутки.
4.2 Жизненный цикл сервисного работника
Когда пользователь переходит по URL-адресу в первый раз, сервер возвращает веб-страницу в ответ.
- Шаг 1: Когда вы вызываете функцию register(), Service Worker начинает загрузку.
- Шаг 2: В процессе регистрации браузер загружает, анализирует и выполняет Service Worker(). Если на этом шаге возникнут какие-либо ошибки, обещание, возвращаемое функцией register(), будет отклонено, а Service Worker будет удален.
- Шаг 3. После успешного выполнения Service Worker будет активировано событие установки.
- Шаг 4: После завершения установки Service Worker активируется и контролирует все в пределах своей области. Если все события в жизненном цикле выполнены успешно, Service Worker готов и готов к использованию!
5. Пример реализации PWA
5.1 Реализация manifest.json добавлена на главный экран
index.html
<head>
<title>Minimal PWA</title>
<meta name="viewport" content="width=device-width, user-scalable=no" />
<link rel="manifest" href="manifest.json" />
<link rel="stylesheet" type="text/css" href="main.css">
<link rel="icon" href="/e.png" type="image/png" />
</head>
manifest.json
{
"name": "Minimal PWA", // 必填 显示的插件名称
"short_name": "PWA Demo", // 可选 在APP launcher和新的tab页显示,如果没有设置,则使用name
"description": "The app that helps you understand PWA", //用于描述应用
"display": "standalone", // 定义开发人员对Web应用程序的首选显示模式。standalone模式会有单独的
"start_url": "/", // 应用启动时的url
"theme_color": "#313131", // 桌面图标的背景色
"background_color": "#313131", // 为web应用程序预定义的背景颜色。在启动web应用程序和加载应用程序的内容之间创建了一个平滑的过渡。
"icons": [ // 桌面图标,是一个数组
{
"src": "icon/lowres.webp",
"sizes": "48x48", // 以空格分隔的图片尺寸
"type": "image/webp" // 帮助userAgent快速排除不支持的类型
},
{
"src": "icon/lowres",
"sizes": "48x48"
},
{
"src": "icon/hd_hi.ico",
"sizes": "72x72 96x96 128x128 256x256"
},
{
"src": "icon/hd_hi.svg",
"sizes": "72x72"
}
]
}
5.2 Service Worker реализует автономное кэширование
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello Caching World!</title>
</head>
<body>
<!-- Image -->
<img src="/images/hello.png" />
<!-- JavaScript -->
<script async src="/js/script.js"></script>
<script>
// 注册 service worker
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/service-worker.js', {scope: '/'}).then(function (registration) {
// 注册成功
console.log('ServiceWorker registration successful with scope: ', registration.scope);
}).catch(function (err) {
// 注册失败 :(
console.log('ServiceWorker registration failed: ', err);
});
}
</script>
</body>
</html>
Примечание. Путь регистрации Service Worker определяет область действия по умолчанию его области.
Если service-worker.js находится по пути к странице /sw/, это заставляет сервис-воркер получать события выборки только по пути к странице /sw/ по умолчанию.
При сохранении в корневом пути веб-сайта будут получены все события выборки для этого веб-сайта.
Если вы хотите изменить его область действия, вы можете установить область действия во втором параметре. В примере он изменен на корневой каталог, который действует для всего сайта.
service-worker.js
var cacheName = 'helloWorld'; // 缓存的名称
// install 事件,它发生在浏览器安装并注册 Service Worker 时
self.addEventListener('install', event => {
/* event.waitUtil 用于在安装成功之前执行一些预装逻辑
但是建议只做一些轻量级和非常重要资源的缓存,减少安装失败的概率
安装成功后 ServiceWorker 状态会从 installing 变为 installed */
event.waitUntil(
caches.open(cacheName)
.then(cache => cache.addAll([ // 如果所有的文件都成功缓存了,便会安装完成。如果任何文件下载失败了,那么安装过程也会随之失败。
'/js/script.js',
'/images/hello.png'
]))
);
});
/**
为 fetch 事件添加一个事件监听器。接下来,使用 caches.match() 函数来检查传入的请求 URL 是否匹配当前缓存中存在的任何内容。如果存在的话,返回缓存的资源。
如果资源并不存在于缓存当中,通过网络来获取资源,并将获取到的资源添加到缓存中。
*/
self.addEventListener('fetch', function (event) {
event.respondWith(
caches.match(event.request)
.then(function (response) {
if (response) {
return response;
}
var requestToCache = event.request.clone(); //
return fetch(requestToCache).then(
function (response) {
if (!response || response.status !== 200) {
return response;
}
var responseToCache = response.clone();
caches.open(cacheName)
.then(function (cache) {
cache.put(requestToCache, responseToCache);
});
return response;
})
);
});
Примечание. Зачем использовать request.clone() и response.clone()
Это необходимо, потому что запрос и ответ представляют собой поток, который можно использовать только один раз. Поскольку мы уже использовали его один раз через кеш, а затем сделали еще один HTTP-запрос, нам нужно клонировать запрос на этом этапе.
5.3 Service Worker реализует отправку сообщений
- Шаг 1. Подскажите пользователю и получите информацию о его подписке
- Шаг 2. Сохраните эти данные на сервере
- Шаг 3. Отправьте любое сообщение, когда это необходимо
Для разных браузеров требуются разные серверы push-сообщений. Если взять в качестве примера использование Google Cloud Messaging
Шаг 1 + Шаг 2 index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Progressive Times</title>
<link rel="manifest" href="/manifest.json">
</head>
<body>
<script>
var endpoint;
var key;
var authSecret;
var vapidPublicKey = 'BAyb_WgaR0L0pODaR7wWkxJi__tWbM1MPBymyRDFEGjtDCWeRYS9EF7yGoCHLdHJi6hikYdg4MuYaK0XoD0qnoY';
// 方法很复杂,但是可以不用具体看,只是用来转化vapidPublicKey用
function urlBase64ToUint8Array(base64String) {
const padding = '='.repeat((4 - base64String.length % 4) % 4);
const base64 = (base64String + padding)
.replace(/\-/g, '+')
.replace(/_/g, '/');
const rawData = window.atob(base64);
const outputArray = new Uint8Array(rawData.length);
for (let i = 0; i < rawData.length; ++i) {
outputArray[i] = rawData.charCodeAt(i);
}
return outputArray;
}
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('sw.js').then(function (registration) {
return registration.pushManager.getSubscription()
.then(function (subscription) {
if (subscription) {
return;
}
return registration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: urlBase64ToUint8Array(vapidPublicKey)
})
.then(function (subscription) {
var rawKey = subscription.getKey ? subscription.getKey('p256dh') : '';
key = rawKey ? btoa(String.fromCharCode.apply(null, new Uint8Array(rawKey))) : '';
var rawAuthSecret = subscription.getKey ? subscription.getKey('auth') : '';
authSecret = rawAuthSecret ?
btoa(String.fromCharCode.apply(null, new Uint8Array(rawAuthSecret))) : '';
endpoint = subscription.endpoint;
return fetch('./register', {
method: 'post',
headers: new Headers({
'content-type': 'application/json'
}),
body: JSON.stringify({
endpoint: subscription.endpoint,
key: key,
authSecret: authSecret,
}),
});
});
});
}).catch(function (err) {
// 注册失败 :(
console.log('ServiceWorker registration failed: ', err);
});
}
</script>
</body>
</html>
Шаг 3 Сервер отправляет сообщение сервис-воркеру
app.js
const webpush = require('web-push');
const express = require('express');
var bodyParser = require('body-parser');
const app = express();
webpush.setVapidDetails(
'mailto:contact@deanhume.com',
'BAyb_WgaR0L0pODaR7wWkxJi__tWbM1MPBymyRDFEGjtDCWeRYS9EF7yGoCHLdHJi6hikYdg4MuYaK0XoD0qnoY',
'p6YVD7t8HkABoez1CvVJ5bl7BnEdKUu5bSyVjyxMBh0'
);
app.post('/register', function (req, res) {
var endpoint = req.body.endpoint;
saveRegistrationDetails(endpoint, key, authSecret);
const pushSubscription = {
endpoint: req.body.endpoint,
keys: {
auth: req.body.authSecret,
p256dh: req.body.key
}
};
var body = 'Thank you for registering';
var iconUrl = 'https://example.com/images/homescreen.png';
// 发送 Web 推送消息
webpush.sendNotification(pushSubscription,
JSON.stringify({
msg: body,
url: 'http://localhost:3111/',
icon: iconUrl
}))
.then(result => res.sendStatus(201))
.catch(err => {
console.log(err);
});
});
app.listen(3111, function () {
console.log('Web push app listening on port 3111!')
});
Сервисный работник прослушивает push-событие и отправляет детали уведомления пользователю.
service-worker.js
self.addEventListener('push', function (event) {
// 检查服务端是否发来了任何有效载荷数据
var payload = event.data ? JSON.parse(event.data.text()) : 'no payload';
var title = 'Progressive Times';
event.waitUntil(
// 使用提供的信息来显示 Web 推送通知
self.registration.showNotification(title, {
body: payload.msg,
url: payload.url,
icon: payload.icon
})
);
});
6. Резюме
Преимущества PWA
- Вы можете разместить ярлык приложения на рабочем столе и запустить его в полноэкранном режиме, как и родное приложение.
- Может использоваться в различных сетевых средах, включая плохую сеть и условия отключения, не будет отображаться неопределенное
- Возможность отправлять сообщения
- Его суть - веб-страница без различных условий запуска нативных приложений, быстро реагирующая на инструкции пользователя.
Проблемы с PWA
- Уровень поддержки невелик: PWA сейчас не поддерживается на мобильных телефонах ios, а IE пока не поддерживает.
- Chrome по-прежнему имеет значительную долю настольной версии в Китае, но очень низкую долю на мобильном терминале Android.
- Крупные производители еще явно не поддерживают pwa.
- Зависимый сервис GCM нельзя использовать в Китае.
- Конкурс мини-программ WeChat
Несмотря на некоторые из вышеперечисленных недостатков, технология PWA все же имеет массу достоинств, которые можно использовать.
- Технология Service Worker реализует автономное кэширование, которое может помещать в кэш некоторые статические файлы, которые редко изменяются, чтобы улучшить взаимодействие с пользователем.
- Сервисный работник реализует push-сообщение и использует функцию push-уведомлений браузера для привлечения пользователей.
- Прогрессивная разработка, несмотря на то, что некоторые браузеры временно не поддерживаются, может использовать преимущества вышеописанных методов, чтобы повысить удобство работы пользователей, использующих поддерживаемые браузеры.
Вдохновленные проектом общедоступной бета-платформы компании, личные исследования и размышления о возможности использования PWA для разработки продуктов компании заключаются в следующем:
Ввиду того, что PWA еще не созрела, но самым большим преимуществом является улучшение опыта работы с веб-приложением, я думаю о реальном рабочем приложении PWA в тестовом проекте просмотра идеальной общедоступной бета-платформы кампуса. применение: характер каждой записи «потерянный» и «найденный» в списке информационных потоков в Lost and Found на самом деле является давним информационным сообщением, потому что некоторые потерянные или найденные предметы могут быть очень трудно найти. описание утерянных и найденных предметов, содержание каждого поста встречается реже, чем посты с социальной информацией, и задействованное взаимодействие может в основном заключаться в контакте с владельцем или человеком, который нашел его на странице, поэтому для такого рода обновления информационного потока встречается не слишком часто, но подходит для условий отсутствия сети или слабой сети.Вы можете просмотреть информацию о публикации и связаться с издателем в любое время и в любом месте (особенно, получив контактный номер, номер QQ или идентификатор WeChat для прямого контакта. метод) , личное мнение подходит для использования технологии PWA или комбинации PWA и Index DB, представленной Zhibing Zhou на прошлой неделе, для преобразования этого приложения, которое может эффективно снизить затраты, такие как внутренние серверы. Во-вторых, учитывая, что на общедоступной бета-платформе есть приложение «Расписание» и приложение «Школьный календарь», PWA также можно использовать для преобразования или разработки, поскольку частота обновления информации этих двух приложений не будет слишком быстрой, например, учебная программа. а школьный календарь может быть. Школа будет обновлять его раз в семестр, и часть обновлений будет не слишком большой, и точек обновления будет не слишком много, что подходит для Service Worker для обработки кеша (это не значит, что Service Worker не может обрабатывать относительно большие кэши).
Использование PWA необходимо оценивать в соответствии с характером проекта. Есть надежда, что некоторые внутренние проекты могут быть реализованы как PWA в один прекрасный день, а некоторые или общая стоимость проекта в целом может быть снижена с самого начала. Конечная перспектива.Лично я думаю, что основные компетенции и конкурентоспособность фронтенд-разработчиков заключаются не только в овладении фреймворком или инструментом, но и в использовании правильных технических средств для снижения сопутствующих затрат на проект.
Тем не менее, личные способности все еще неглубокие, и я надеюсь продолжать усердно работать над предпосылкой освоения и опыта в соответствующих необходимых технологиях.