Workboxjs precacheAndRoute не обслуживает новый контент - PullRequest
0 голосов
/ 24 августа 2018

Я создал автономную документацию с MkDocs и Workboxjs .

Я выполняю workbox generateSW для файлов, сгенерированных MkDocs, который генерирует Service Worker с настройкой предварительного кэширования с функцией precacheAndRoute.

Это работает нормально, но когда я обновляю документацию и генерирую новые html-файлы и Service Worker, он не обслуживает новый контент, пока я полностью не закрою браузер. Обновление или просто закрытие вкладки недостаточно.

Работник корректно обновляет содержимое в Cache Storage, что я вижу по Chrome devtools (Приложение -> Cache Storage -> workbox-precache *), но независимо от того, сколько раз я нажимаю обновить, браузер не будет отображаться новый контент.

Я использую эту функцию для регистрации работника сервиса

async function register() {
    const registration = await navigator.serviceWorker.register(SW_URL);

    registration.onupdatefound = () => {
        const installingWorker = registration.installing;

        installingWorker.onstatechange = () => {
            if (installingWorker.state === "installed") {
                if (navigator.serviceWorker.controller) {
                    console.log(
                        "New content is available; please refresh."
                    );
                } else {
                    console.log("Content is cached for offline use.");
                }
            }
        };
    };
}

Интересно, нужно ли мне что-то делать, чтобы контент обновлялся правильно?

Мой рабочий ящик-config.js -

module.exports = {
    globDirectory: ".doc_build",
    globPatterns: ["**/*"],
    swDest: ".doc_build/sw.js"
};

Это происходит как в Firefox, так и в Chrome.

1 Ответ

0 голосов
/ 24 августа 2018

Благодаря ссылке Роберта Раунтри в комментарии к вопросу я понял это.

В моем случае содержимое обновляется для кэширования, но старая версия работника службы предварительного кэширования все еще продолжает работать со списком объектов.как это

{
  "url": "index.html",
  "revision": "e4919b0cd0e772b3beb2d1f3d09af437"
}

, поскольку вы можете видеть, что в нем есть контрольная сумма старой версии, и она будет обслуживать ее до тех пор, пока старый сервисный работник не будет деактивирован, а новая активирована.

Это можно увидеть, проверив registration.waiting, когда старый обслуживающий работник ожидает деактивации и установки нового.Кажется, что браузер делает это «в какой-то момент».Это действительно происходит, если я просто держу вкладки достаточно долго.

Решение моего вопроса - заставить обслуживающего работника пропустить период ожидания.Это можно сделать, отправив сообщение работнику сервиса из события обновления

async function register() {
    const registration = await navigator.serviceWorker.register(SW_URL);
    registration.onupdatefound = () => {
        const installingWorker = registration.installing;
        installingWorker.onstatechange = async () => {
            if (installingWorker.state === "installed") {
                if (navigator.serviceWorker.controller) {
                    console.log(
                        "New content is available; please refresh."
                    );
                    // Send message to the service worker telling
                    // it should stop waiting for browser to deactivate it
                    registration.waiting.postMessage("skipWaiting");
                } else {
                    console.log("Content is cached for offline use.");
                }
            }
        };
    };
}

Тогда в коде работника сервиса мне пришлось обработать это сообщение и вызвать skipWaiting()

self.addEventListener("message", messageEvent => {
    if (messageEvent.data === "skipWaiting") {
        return skipWaiting();
    }
});

Чтобы сделать это, мне пришлось перейти с workbox generateSW на workbox injectManifest, чтобы добавить код пропуска.

Но в этом решении есть предостережения.Читайте по ссылке Роберта далее

«Самый простой и опасный подход - просто пропустить ожидание во время установки.»

https://redfin.engineering/how-to-fix-the-refresh-button-when-using-service-workers-a8e27af6df68

К счастью, этого достаточно для моего случая.

...