PWA ist einfach. Hallo habr

Fortsetzung unserer Bekanntschaft mit Progressive Web Applications. Nach dem theoretischen letzten Teil ist es Zeit, mit dem Üben fortzufahren.

Heute werden wir eine einfache, aber vollwertige PWA „Hello Habr“ bauen.




Die Anwendung ist unter https://altrusl.imtqy.com/habr-pwa/hello-habr/ verfügbar. Beim Öffnen in einem Browser auf einem mobilen Gerät ist es möglich, eine Verknüpfung zum Startbildschirm hinzuzufügen und im Vollbildmodus zu starten.

Wenn jemand das betreffende Beispiel auf seinem Computer ausprobieren möchte, können Sie mit Chrome lokal mit einfachen PWA-Anwendungen arbeiten, ohne Webserver von Drittanbietern mit SSL-Zertifikaten installieren zu müssen.
Anleitung zum lokalen Ausführen von "Hello Habr"
Sie müssen diese oder eine ähnliche Erweiterung aus dem Chrome Web Store installieren, dem lokalen Webserver. Natürlich ohne PHP-Unterstützung.



Hallo Habr-Dateien können von GitHub-a - https://github.com/altrusl/habr-pwa/tree/master/hello-habr entnommen werden

Legen Sie alles in einem Verzeichnis ab und zeigen Sie es auf den Webserver.


"Hallo Habr" besteht aus einer Seite. Er zeigt darauf ein Bild (Logo) und eine animierte Inschrift.

"Hallo Habr" Code

index.html


<html> <head> <title>Hello Habr</title> <script src="hh.js"></script> <link rel="stylesheet" href="hh.css" /> <script type="text/javascript"> if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/sw.js') .then(function(registration) { console.log('Registration successful, scope is:', registration.scope); }) .catch(function(error) { console.log('Service worker registration failed, error:', error); }); } </script> </head> <body> <div class="center"> <p id="text"></p> </div> <div id="logo"></div> </body> </html> 

hh.css


 @font-face { font-family: Zaplyv-Heavy; src: url(Zaplyv-Heavy.otf); } body { display: flex; align-items: center; align-content: center; justify-content: center; overflow: auto; } .center { font-family: Zaplyv-Heavy; font-size: 8vmax; } #logo { background-image: url(logo.jpg); background-size: 100%; width: 100px; height: 100px; position: absolute; top: 0; right: 0; margin: 10px; } 

hh.js.


 window.onload = function() { fetch("hh.txt?mode=nocache").then(data => data.text()).then(data => { animateText(data) }); } function animateText(data) { var ele = document.getElementById("text"), txt = data.split(""); var interval = setInterval(function(){ if(!txt[0]){ return clearInterval(interval); }; ele.innerHTML += txt.shift(); }, 150); } 

hh.txt


 Hello Hubr 


Benutzerdefinierte Schriftart ist ebenfalls vorhanden. Total - der minimale vollständige Satz von Ressourcen einer durchschnittlichen Website. Wenn Sie index.html in einem Browser öffnen, werden ein Bild und eine Beschriftung angezeigt. Die Inschrift wird per Javascript per Abruf aus der Datei hh.txt geladen - dem einfachsten Modell einer allgemeinen PWA-Anwendung.

Wenn Sie ohne sw.js öffnen, handelt es sich um eine reguläre Website. Fügen Sie Service Worker zu unseren Dateien hinzu.

sw.js
 // Caches var CURRENT_CACHES = { font: 'font-cache-v1', css:'css-cache-v1', js:'js-cache-v1', site: 'site-cache-v1', image: 'image-cache-v1' }; self.addEventListener('install', (event) => { self.skipWaiting(); console.log('Service Worker has been installed'); }); self.addEventListener('activate', (event) => { var expectedCacheNames = Object.keys(CURRENT_CACHES).map(function(key) { return CURRENT_CACHES[key]; }); // Delete out of date caches event.waitUntil( caches.keys().then(function(cacheNames) { return Promise.all( cacheNames.map(function(cacheName) { if (expectedCacheNames.indexOf(cacheName) == -1) { console.log('Deleting out of date cache:', cacheName); return caches.delete(cacheName); } }) ); }) ); console.log('Service Worker has been activated'); }); self.addEventListener('fetch', function(event) { console.log('Fetching:', event.request.url); event.respondWith(async function() { const cachedResponse = await caches.match(event.request); if (cachedResponse) { console.log("\tCached version found: " + event.request.url); return cachedResponse; } else { console.log("\tGetting from the Internet:" + event.request.url); return await fetchAndCache(event.request); } }()); }); function fetchAndCache(request) { return fetch(request) .then(function(response) { // Check if we received a valid response if (!response.ok) { return response; // throw Error(response.statusText); } var url = new URL(request.url); if (response.status < 400 && response.type === 'basic' && url.search.indexOf("mode=nocache") == -1 ) { var cur_cache; if (response.headers.get('content-type') && response.headers.get('content-type').indexOf("application/javascript") >= 0) { cur_cache = CURRENT_CACHES.js; } else if (response.headers.get('content-type') && response.headers.get('content-type').indexOf("text/css") >= 0) { cur_cache = CURRENT_CACHES.css; } else if (response.headers.get('content-type') && response.headers.get('content-type').indexOf("font") >= 0) { cur_cache = CURRENT_CACHES.font; } else if (response.headers.get('content-type') && response.headers.get('content-type').indexOf("image") >= 0) { cur_cache = CURRENT_CACHES.image; } else if (response.headers.get('content-type') && response.headers.get('content-type').indexOf("text") >= 0) { cur_cache = CURRENT_CACHES.site; } if (cur_cache) { console.log('\tCaching the response to', request.url); return caches.open(cur_cache).then(function(cache) { cache.put(request, response.clone()); return response; }); } } return response; }) .catch(function(error) { console.log('Request failed for: ' + request.url, error); throw error; }); } 


Wie Sie sehen, erstellen wir für jeden Ressourcentyp fünf Caches. Der Site-Cache ist für HTML-Dateien. Alle Ressourcen werden zwischengespeichert, mit Ausnahme derjenigen, die in der GET-Abfrage "mode = nocache" haben - und dies ist unsere Anfrage an die Datei hh.txt mit einer Zeile für die Beschriftung.
Manchmal können Sie sehen, dass die Ressource aus dem Festplatten-Cache entnommen wurde. Dies ist ein häufiges Problem bei der Entwicklung von Anwendungen mit Service Worker. Daher ist es besser, den Festplatten-Cache (Browser-Cache) zu deaktivieren. Und nicht in meinem Browser, sondern auf dem Server - zum Beispiel in
.htaccess
 # Cache-Control Headers <ifModule mod_headers.c> <FilesMatch (\.css|\.js|sprites\.png)$> Header unset ETag Header unset Expires Header set Cache-Control "no-cache" </FilesMatch> </IfModule> 

Die Logik hinter sw.js ist einfach: "Cache fällt auf das Netzwerk zurück". Zunächst wird die angeforderte Ressource im Cache überprüft. Wenn sie vorhanden ist, wird sie übernommen und von dort an den Browser zurückgegeben. Wenn nicht, wird es vom Netzwerk abgerufen, an den Browser zurückgegeben und eine Kopie der Ressource wird zwischengespeichert.

Nach dem ersten Öffnen der Seite index.html in der Chrom-a-Konsole werden Aufzeichnungen zur Installation und Aktivierung des Service Worker angezeigt. Nach dem zweiten Öffnen werden unsere Caches im Speicher erstellt und unsere Ressourcen in ihnen abgelegt. Es ist auch ersichtlich, dass bei nachfolgenden Öffnungen nur Anforderungen an hh.txt an den Webserver gesendet werden und alle anderen Ressourcen von Service Worker-a übernommen werden.

Screenshot


Lokal gespeicherte index.html, hh.css, hh.js, hh.otf, logo.jpg - Dies ist genau die Anwendungsshell, eine Shell aus statischen Ressourcen und Daten, die als Programm-Shell auf dem Client fungiert. Alle dynamischen Informationen, die für das Funktionieren der Site erforderlich sind, werden durch Javascript-Anforderungen an den Server und die Anzeige der empfangenen Daten in der App-Shell-e abgerufen. In unserem Fall ist dies eine Anfrage an text.txt.

Um als voll funktionsfähige PWA bezeichnet zu werden, fehlt „Hello Habr“ eines - die Symbole auf dem Startbildschirm von Smartphones und der Start im Vollbildmodus.

Dazu müssen Sie das Anwendungsmanifest in index.html verbinden:
manifest.json
 { "short_name": "Hello Habr", "name": "Hello Habr - PWA example", "icons": [ { "src": "logo3.jpg", "type": "image/jpg", "sizes": "192x192" }, { "src": "logo2.jpg", "type": "image/jpg", "sizes": "512x512" } ], "start_url": "index.html", "background_color": "#3367D6", "display": "standalone", "scope": "/habr-pwa/hello-habr/", "theme_color": "#3367D6" } 

Es ist in index.html verbunden:
 <link rel="manifest" href="manifest.json"> 


Danach bieten mobile Browser (jeder auf seine Weise) an, eine Verknüpfung für die Anwendung auf dem Startbildschirm zu erstellen. Wenn die Anwendung über eine Verknüpfung gestartet wird, wird sie im Standalone- Modus geöffnet - ohne Browsersteuerung. Weitere Informationen zu Manifestoptionen finden Sie bei Google Developers .

Die Hello Habr-Anwendung besitzt minimal alle Funktionen von PWA und ist es im Wesentlichen. Wie Sie sehen, müssen Sie zum Übertragen einer einfachen Site an PWA nur das Manifest und die Service Worker-Datei verbinden. Die Verwendung von sw.js ist ziemlich universell.

Das nächste Mal werden wir die fertige Site an PWA an CMS Joomla übertragen (die Site ist mit den anfänglichen Demo-Daten "out of the box"). Darüber hinaus bleiben sw.js nahezu gleich.

Source: https://habr.com/ru/post/de419585/


All Articles