Service Worker Terdaftar dan Diaktifkan tetapi Tidak Bekerja dalam Mode Offline

Dalam aplikasi UI5, saya telah mendaftarkan pekerja layanan saya di index.html:

$(document).ready(function() {
  if ('serviceWorker' in navigator) {
    navigator.serviceWorker
      .register('service-worker.js', { scope: './' })
      .then(function(registration) {
        console.log("Service Worker Registered");
      })
      .catch(function(err) {
        console.log("Service Worker Failed to Register", err);
      })
  }
});

Selain itu, saya memiliki file service-worker.js di folder root sehingga pekerja layanan dapat menyimpan semua elemen di bawahnya dalam cache. File ini berisi kode berikut:

// Set a name for the current cache
var cacheName = 'v2'; 

// Default files to always cache
var cacheFiles = [
    './',
    './inicio.html?I_APLICACION=CAPCGENA02',
    './resources/sap-ui-core.js',
    './resources/sap/ui/core/themes/base/fonts/SAP-icons.ttf',
    './resources/sap-ui-core.js',
    './resources/sap/ui/core/library-preload.js',
    './resources/sap/m/library-preload.js',
    './resources/sap/ui/unified/library-preload.js',
    './resources/sap/ui/comp/library-preload.js',
    './resources/sap/ui/table/library-preload.js',
    './resources/sap/ui/fl/library-preload.js',
    './resources/sap/tnt/library-preload.js',
    './resources/sap/ui/unified/themes/sap_belize/library-parameters.json',
    './resources/sap/ui/table/themes/sap_belize/library-parameters.json',
    './resources/sap/ui/comp/themes/sap_belize/library-parameters.json',
    './resources/sap/tnt/themes/sap_belize/library-parameters.json',
    './resources/sap/ui/layout/library-preload.js',
    './resources/sap/ui/unified/themes/sap_belize/library.css',
    './resources/sap/ui/table/themes/sap_belize/library.css',
    './resources/sap/ui/comp/themes/sap_belize/library.css',
    './resources/sap/tnt/themes/sap_belize/library.css',
    './css/style.css',
    './css/fonts/ttf/CMEEMEN18.ttf',
    './images/temporal/chart.PNG',
    './Component.js',
    './Component-preload.js',
    './manifest.json',
    './api/api.reformation.data.js',
    './api/ApiManager.js',
    './api/ApiStructure.js',
    './api/ibd.api.login.data.js',
    './controller/Home.controller.js',
    './controller/Login.controller.js',
    './controller/Menu.controller.js',
    './controller/fragment/ManagePartes.js',
    './controller/fragment/FilterDialogController.js',
    './controller/structure/Container.controller.js',
    './controller/structur
    './database/apiBBDD.js',
    './database/bbdd.js',
    './i18n/i18n.properties',
    './i18n/i18n_en.properties',
    './i18n/i18n_es.properties',
    './i18n/i18n_en_US.properties',
    './i18n/i18n_es_ES.properties',
    './manager/dataManager/DataManager.js',
    './manager/functionalityManager/FunctionalityManager.js',
    './manager/mappingManager/MappingManager.js',
    './manager/parserManager/ReformationParser.js',
    './manager/sessionManager/SessionManager.js',
    './manager/structureManager/ElementManager.js',
    './manager/structureManager/StructureManager.js',
    './manager/viewManager/ViewManager.js',
    './singleton/Singleton.js',
    './utils/Consts.js',
    './utils/Funcionality.js',
    './utils/FunctionalityEvent.js',
    './utils/MaskedPassword.js',
    './utils/Utils.js',
    './view/Home.view.xml',
    './view/Login.view.xml',
    './view/Menu.view.xml',
    './view/fragment/DialogConfirm.fragment.xml',
    './view/fragment/DialogEnd.fragment.xml',
    './view/fragment/DialogError.fragment.xml',
    './view/fragment/DialogTag.fragment.xml',
    './view/fragment/DialogWaiting.fragment.xml',
    './view/fragment/HistoryDialog.fragment.xml',
    './view/fragment/HistoryNoticeDialog.fragment.xml',

]


self.addEventListener('install', function(e) {
    console.log('[ServiceWorker] Installed');

    // e.waitUntil Delays the event until the Promise is resolved
    e.waitUntil(

        // Open the cache
        caches.open(cacheName).then(function(cache) {

            // Add all the default files to the cache
            console.log('[ServiceWorker] Caching cacheFiles');
            //return cache.addAll(cacheFiles);
            return cache.addAll(cacheFiles.map(url => new Request(url, {credentials: 'same-origin'})));
        })
    ); // end e.waitUntil
});


self.addEventListener('activate', function(e) {
    console.log('[ServiceWorker] Activated');

    e.waitUntil(

        // Get all the cache keys (cacheName)
        caches.keys().then(function(cacheNames) {
            return Promise.all(cacheNames.map(function(thisCacheName) {

                // If a cached item is saved under a previous cacheName
                if (thisCacheName !== cacheName) {

                    // Delete that cached file
                    console.log('[ServiceWorker] Removing Cached Files from Cache - ', thisCacheName);
                    return caches.delete(thisCacheName);
                }
            }));
        })
    ); // end e.waitUntil

});


self.addEventListener('fetch', function(e) {
    console.log('[ServiceWorker] Fetch', e.request.url);

    // e.respondWidth Responds to the fetch event
    e.respondWith(

        // Check in cache for the request being made
        caches.match(e.request)


            .then(function(response) {

                // If the request is in the cache
                if ( response ) {
                    console.log("[ServiceWorker] Found in Cache", e.request.url, response);
                    // Return the cached version
                    return response;
                }

                // If the request is NOT in the cache, fetch and cache

                var requestClone = e.request.clone();
                fetch(requestClone)
                    .then(function(response) {

                        if ( !response ) {
                            console.log("[ServiceWorker] No response from fetch ")
                            return response;
                        }

                        var responseClone = response.clone();

                        //  Open the cache
                        caches.open(cacheName).then(function(cache) {

                            // Put the fetched response in the cache
                            cache.put(e.request, responseClone);
                            console.log('[ServiceWorker] New Data Cached', e.request.url);

                            // Return the response
                            return response;

                        }); // end caches.open

                    })
                    .catch(function(err) {
                        console.log('[ServiceWorker] Error Fetching & Caching New Data', err);
                    });


            }) // end caches.match(e.request)
    ); // end e.respondWith
});

Dengan semua ini, pekerja layanan saya terinstal dan diaktifkan dengan benar. Dan jika saya membuka tab Penyimpanan Cache, saya memiliki informasi yang di-cache:

Penyimpanan Cache

Koneksi saya aman (HTTPS) tetapi ketika saya masuk ke mode offline, permintaan datang kembali dari cache-disk bukan dari pekerja layanan.

Saya kira itu karena mengambilnya dari cache otomatis browser, tetapi jika saya mengklik opsi "Nonaktifkan cache" di Chrome, halaman offline tidak dimuat.

Apakah ada yang tahu mengapa hal ini terjadi?


person Angel Silvan    schedule 20.02.2018    source sumber
comment
Apakah Anda melihat tanda from service worker saat memeriksa navigator.serviceWorker.controller? Jika tidak, halaman Anda tidak dikontrol oleh pekerja layanan. Meskipun SW Anda masih aktif, Anda harus memeriksa apakah halaman Anda termasuk dalam cakupan SW di chrome://serviceworker-internals/.   -  person ashxvi    schedule 20.02.2018
comment
Bagaimana cara memeriksa navigator.serviceWorker.controller? Saya meletakkannya di konsol javascript tetapi mengembalikan nol. Saya telah memeriksa cakupannya di chrome://serviceworker-internals/ dan saya telah memverifikasi bahwa halaman saya berada dalam cakupan SW.   -  person Angel Silvan    schedule 20.02.2018
comment
Silakan lihat cuplikan dari serviceworke.rs/immediate-claim_service-worker_doc.html I Anda pikir Anda harus menambahkan clients.claim() ke pendengar aktif Anda sehingga Service Worker Anda akan tersedia untuk halaman dengan cakupan yang sama.   -  person ashxvi    schedule 20.02.2018
comment
@AngelSilvan Apakah pengurangan XHR sinkronisasi seperti yang disarankan dalam jawaban di bawah ini membantu?   -  person Boghyon Hoffmann    schedule 31.05.2018
comment
Kurang tepat, sayangnya saya tidak dapat mengurangi semua panggilan sinkron.   -  person Angel Silvan    schedule 12.06.2018


Jawaban (1)


Berikut adalah jawaban untuk "Apakah ada yang pernah mengerjakan Implementasi Service Worker di SAPUI5?"
Dan kutipan dari MDN:

[Service Worker] dirancang untuk sepenuhnya asinkron; sebagai konsekuensinya, API seperti XHR sinkron [...] tidak dapat digunakan di dalam pekerja layanan.

Jadi saat ini, Service Worker tidak mencegat sinkronisasi XHR dan UI5 mengirimkan banyak XHR sinkronisasi yang menjelaskan mengapa file-file tersebut tidak dicegat.

Oleh karena itu, cobalah untuk mengurangi sinkronisasi XHR sebanyak mungkin dijelaskan di sini.

  1. Buat file Pramuat Komponen
  2. Tetapkan di mana saja async: true bila memungkinkan. Misalnya.

    • Untuk komponen

      sap.ui.component({
        manifestUrl: "...",
        async: true,
      })
      
    • Tampilan Root (dalam deskriptor aplikasi)

      rootView : {
        viewName: "...",
        type: "XML",
        async: true,
        ...
      },
      
  3. Muat perpustakaan secara asinkron melalui konfigurasi bootstrap preload dengan nilai "async". Misalnya.:

    data-sap-ui-preload="async"
    
  4. Pramuat perpustakaan dengan xx-waitForTheme yang diaktifkan. Misalnya.:

    data-sap-ui-libs="sap.m, sap.ui.core, sap.f"
    data-sap-ui-xx-waitForTheme="true"
    

Saya juga melihat Anda memiliki beberapa fragmen. Hindari memuat kontrol dengan malas melalui pabrik fragmen karena fragmen diambil secara serempak dengan cara ini.

person Boghyon Hoffmann    schedule 20.02.2018