PWAを使用すると、デバイス接続がオフラインモードでダウンした場合に処理できます。しかし、どのようにして固定ネットワーク接続を検出し、アプリケーションを自動的にリロード/再アクティブ化するのでしょうか?
offline
およびonline
イベント を監視できます。これらは 広くサポートされています です。さらに、ターゲットサーバーのURLからHEAD
をフェッチして、接続をテストできます。
// Test this by running the code snippet below and then
// use the "Offline" checkbox in DevTools Network panel
window.addEventListener('online', handleConnection);
window.addEventListener('offline', handleConnection);
function handleConnection() {
if (navigator.onLine) {
isReachable(getServerUrl()).then(function(online) {
if (online) {
// handle online status
console.log('online');
} else {
console.log('no connectivity');
}
});
} else {
// handle offline status
console.log('offline');
}
}
function isReachable(url) {
/**
* Note: fetch() still "succeeds" for 404s on subdirectories,
* which is ok when only testing for domain reachability.
*
* Example:
* https://google.com/noexist does not throw
* https://noexist.com/noexist does throw
*/
return fetch(url, { method: 'HEAD', mode: 'no-cors' })
.then(function(resp) {
return resp && (resp.ok || resp.type === 'opaque');
})
.catch(function(err) {
console.warn('[conn test failure]:', err);
});
}
function getServerUrl() {
return document.getElementById('serverUrl').value || window.location.Origin;
}
<fieldset>
<label>
<span>Server URL for connectivity test:</span>
<input id="serverUrl" style="width: 100%">
</label>
</fieldset>
<script>document.getElementById('serverUrl').value = window.location.Origin;</script>
<p>
<i>Use Network Panel in DevTools to toggle Offline status</i>
</p>
これを処理する1つの technique :
オフラインイベント
オンラインイベント
接続されている場合にのみデバイスに通知するonline
イベントに注意してください。実際のインターネット接続なしで(たとえば、資格情報のため)WiFiホットスポットに接続できます。
PWAでの一般的な方法は、アプリケーションに対して Application Shell アプローチに従うことです。これにより、エントリ時にアプリケーションシェルをキャッシュし、接続に基づいてデータをロードできます。
このアプローチでのキャッシュと提供の最も一般的な方法は、キャッシュからネットワークへのフォールバックを提供することです。この場合、要求されたリソースがキャッシュで利用できない場合は、ネットワーク経由で要求を送信し、応答をキャッシュします。次に、キャッシュから提供します。
これにより、電車の中などの接続が不安定な場合でも、より適切な劣化を行うことができます。
これを実装する例:
const cacheName = "my-cache-v1"
self.addEventListener('fetch', (event) => {
if (event.request.method === 'GET') {
event.respondWith(
caches.match(event.request).then((response) => {
if (response) {
return response;
}
return fetch(event.request).then((response) => {
return caches.open(cacheName).then((cache) => {
cache.put(event.request.url, response.clone());
return response;
});
});
})
);
}
});
上記の例( Service Worker ライフサイクルで必要な手順の1つのみ)では、古いキャッシュエントリも削除する必要があります。
私が見たほとんどのサービスは、次の方法を使用しています:特定の値までタイムアウトを増やし、サーバーに接続しようとします。最大タイムアウト値に達すると、再接続の次の試行が発生する回数を示す手動の再接続ボタン付きのインジケータが表示されます