JS: Service Worker - почему страницы долго находятся в статусе Pending?

Рейтинг: 0Ответов: 1Опубликовано: 06.03.2023

Если установить PWA прилоежние на Windows, то страницы попавшие в кеш долго открываются.

Если в консоли включить Offline режим, то все отрабатывает моментально, но как только я реально отключаю интернет и смотрю в консоль, Pending держится очень долго (около 3 - 5 секунд) и только потом открывается закешированная страница. С телефона такой проблемы нет. Может где-то можно выставить таймаут?

async function getData() {
    let result = await fetch('/sw'),
        data = await result.json()

    return data ['result'];
}

async function preCache() {
    let cache = await caches.open(cacheVer),
        data = await getData()

    return cache.addAll(data ['assets'])
}

async function clearCache() {
    let keys = await caches.keys(),
        keysToDelete = keys.map(function (e) {
            if (e !== cacheVer) {
                return caches.delete(e)
            }
        })

    return Promise.all(keysToDelete)
}

async function fetchAssets(e) {
    try {
        return await fetch(e.request)
    } catch (err) {
        let cache = await caches.open(cacheVer),
            fromCache = await cache.match(e.request)

        if (fromCache) {
            return fromCache
        }

        return await cache.match('/offline')
    }
}

self.addEventListener('install', function (e) {
    self.skipWaiting()
    e.waitUntil(preCache())
})

self.addEventListener('activate', function (e) {
    e.waitUntil(clearCache())
})

self.addEventListener('fetch', function (e) {
    e.respondWith(fetchAssets(e))
})

Ответы

▲ 0

Возможно, проблема связана с тем, что браузер ждет ответа от сети до таймаута, прежде чем перейти к отображению закешированной страницы

Попробуй выставить опцию { timeout: <ms> } в вызов fetch()

async function fetchAssets(e) {
    try {
        return await fetch(e.request, { timeout: 3000 }) // 3 секунды таймаута
    } catch (err) {
        // ...
    }
}

Таймаут подбирай под себя. Ну или просто попробуй реализовать проверку наличия интернета перед вызовом.

Если его нет, выдавай кэш