Wer heute eine größere clientseitige Webanwendung schreibt, greift für gewöhnlich zu den üblichen Verdächtigen: Angular, React, Vue.js, Blazor und Co. Doch die Frontend-Landschaft wird sich durch Web Components verändern.
Single-Page Applications eignen sich hervorragend zur Entwicklung performanter und offlinefähiger Webanwendungen. Es existieren viele Frameworks und Bibliotheken, die die Entwicklung beschleunigen und vereinfachen. Diese Frameworks übernehmen etwa Aufgaben wie Templating, Data Binding, Routing, Dependency Injection und Ähnliches.
Alle großen Frontend-Plattformen haben früher oder später ein Komponentenmodell eingeführt (z.B. COM). Mit den Web Components hat das Web sein natives Komponentenmodell vergleichsweise spät erhalten. Seit Microsoft Edge auf Chromium aufsetzt, ist dieses in den vier großen Webbrowsern Chrome, Edge, Firefox und Safari verfügbar. Technisch basieren Web Components vorwiegend auf den Schnittstellen Custom Elements [1] zur Definition benutzerdefinierter HTML-Elemente und Shadow DOM [2] zum Kapseln der Elementinhalte, um sie äußeren Einflüssen etwa durch CSS zu entziehen. Sie können, wie normale HTML-Elemente auch, benutzerdefinierte Eigenschaften definieren und Ereignisse auslösen. Darüber lässt sich eine Kommunikationsinfrastruktur zwischen einzelnen Komponenten aufbauen, was bis hin zur komplexen SPA skaliert.
class MyElement extends HTMLElement {
constructor() {
super();const shadow = this.attachShadow({mode: 'open'});
shadow.innerHTML = 'Test!';
}
}
customElements.define('my-element', MyElement);
Die Einführung einer Web Component ist denkbar einfach: Es muss lediglich eine neue JavaScript-Klasse definiert werden, die vom HTMLElement erbt (siehe Listing). Kein Modul-Bundler, keine Rendering-Engine, keine Abhängigkeiten, keine Abstraktionsschichten, kein Build-Prozess. Einfache Anwendungen auf Basis von Web Components werden nur wenige Kilobyte groß. Nachteile sind jedoch, dass Web Components von Haus aus weder Data Binding unterstützen noch Templating-Magie wie das aus Angular bekannte *ngFor zum Wiederholen von DOM-Knoten. Auch Routing gestaltet sich mit reinen JavaScript-Bordmitteln als eher kompliziert. Weiterhin können derzeit noch nicht flächendeckend benutzerdefinierte Formularsteuerelemente "erfunden" werden, die Form-Associated Custom Elements [3] sind aber schon unterwegs.
Um diese Nachteile teilweise wieder auszugleichen, bieten sich neue Bibliotheken an: Vaadin Router [4] vereinfacht das Routing deutlich und bietet eine Express-ähnliche Routensyntax, die auch Angular-Entwickler kennen. Die Bibliothek lit-element [5] aus dem Polymer-Umfeld bringt Data Binding und eine Art Templating. Für beides braucht es weiterhin keinen Build-Prozess, durch die Abhängigkeiten wird die Anwendung jedoch schon mehrere hundert Kilobyte groß. Damit ist sie wieder größer als ein Produktiv-Build einer kleinen Angular-App.
Web Components sind außerdem interoperabel: Angular unterstützt etwa das Erzeugen von Web Components aus Angular-Komponenten heraus [6]das Erzeugen von Web Components aus Angular-Komponenten heraus [7], Web Components wiederum lassen sich in jedem beliebigen Framework verwenden – das öffnet auch die Tür zu Microfrontends.
Mit Web Components lassen sich schon heute vollwertige Anwendungen bauen. Ausgestattet mit den richtigen Bibliotheken können Entwickler damit teilweise auch SPA-Frameworks ersetzen. Allerdings müssen sich Web-Component-Entwickler ihren Toolbelt erst selbst zusammenstellen. Frameworks wie Angular bringen alles Notwendige im Lieferumfang bereits mit. Gerade wer von einer komplett anderen Technologie ins Web wechselt, wird die Vorteile eines Opinionated-Framework wie Angular spüren. Kurzum gesellen sich Web Components als weitere valide Option zu den bekannten SPA-Frameworks.
URL dieses Artikels:https://www.heise.de/-4850959
Links in diesem Artikel:[1] https://developer.mozilla.org/de/docs/Web/Web_Components/Using_custom_elements[2] https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM[3] https://html.spec.whatwg.org/multipage/custom-elements.html#custom-elements-face-example[4] https://vaadin.com/router[5] https://lit-element.polymer-project.org/[6] https://angular.io/guide/elements[7] https://angular.io/guide/elements
Copyright © 2020 Heise Medien
Wenn man auf Entwickler*innen nicht aufpasst, machen sie den ganzen Tag Unsinn. Wie soll man damit umgehen?
Relativ häufig wird mir die Frage gestellt: "Wie kontrolliert man die Technologieauswahl im Team?" In der Diskussion zeigt sich dann die Meinung, dass Entwickler*innen Technologieentscheidungen eigentlich nicht treffen sollten. Das Projekt würde sonst in Chaos und Anarchie versinken, weil alle denkbaren Technologien genutzt werden. Developer sind schließlich verantwortungslose Spielkinder! Die Leidtragenden, wenn Projekte in Chaos und Anarchie versinken, sind aber Entwickler*innen. Es ist also in ihrem besten Interesse, Technologien mit Augenmaß zu nutzen. Das spielt in der Diskussion aber nur selten eine Rolle.
Die nächste Eskalationsstufe sind Äußerungen wie "Meine 14-jährige Tochter programmiert auch und die bekommt das schneller hin als diese Entwickler" oder "Mit den Entwicklerinnen hier kann man moderne Ideen eh nicht umsetzen". Entwickler*innen sind hochqualifizierte Expert*innen. Software gehört zum Komplexesten, was Menschen überhaupt produzieren können. Ich halte solche Äußerungen schlicht für respektlos.
Aber nehmen wir an, dass Developer tatsächlich verantwortungslose Spielkinder sind. Dann kann man anscheinend nur auf Kontrolle setzen. Das führt zu klaren Richtlinien, beispielsweise bezüglich zu nutzender Technologien oder Coding-Standards, idealerweise mit automatisierter Überprüfung.
Sicherlich können solche Maßnahmen sinnvoll sein. Aber die Kontrollen funktionieren oft nur schlecht: In einem meiner ersten Großprojekte haben wir gemeinsam einige Coding-Richtlinien festgelegt und mit Werkzeugen automatisiert überprüft. Nach einiger Zeit gab es keine Verstöße, aber nur scheinbar: In Wirklichkeit hatten einige Entwickler*innen die Werkzeuge an bestimmten Code-Stelle einfach deaktiviert. So kann ein sinnloser Wettlauf mit zunehmend mehr Kontrolle und dem Unterwandern der Kontrollen beginnen.
Offensichtlich kommt man so also nicht weiter. Und Kontrolle skaliert auch nicht: Man kann nicht als einzelne Person alles verstehen, kontrollieren und korrigieren, was ein ganzes Team produziert. Wer den Anspruch an sich hat, der muss scheitern. Passend dazu zeigt die in diesem Blog schon einmal zitierte empirische Untersuchung in der “State of DevOps”-Studie [1], dass ein schwergewichtiger Änderungsprozess die Leistungsfähigkeit der Softwareentwicklungsorganisation negativ beeinflusst. Mehr Kontrolle und Overhead sind also wohl kaum die Lösung.
Von Fred George habe ich sinngemäß einen Satz im Ohr: "Developer wollen an Dingen tüfteln. Also gib ihnen Dinge zum Tüfteln!" Daraus leitet er in seinem Modell weitgehende Freiheiten für Entwickler*innen ab. Außerdem tüfteln sie dann nicht nur am Code, sondern direkt an Geschäftszielen wie Umsatzsteigerung oder Kundenzufriedenheit. Bezeichnenderweise heißt das Modell "Developer Anarchy". Wie kann das funktionieren? Schließlich sind Developer doch verantwortungslose Spielkinder!
Vielleicht sind sie doch verantwortungsvolle Personen? Immerhin kenne ich durchaus einige Entwickler*innen, die im privaten Leben erhebliche Budgets auf eigenes Risiko verwalten – beispielsweise beim Hausbau. Ihre Fähigkeiten sind ihnen auch wichtig. Sie programmieren auch in ihrer Freizeit [2]oder nehmen zum Beispiel an abendlichen Meetups oder an Coderetreats [3] an Wochenenden teil. Das zeugt von einer hohen Motivation, die eigenen Fähigkeiten sogar in der Freizeit ständig weiterzuentwickeln.
Meiner Meinung nach ist der einzige Weg aus dieser Situation, zunächst einmal Respekt vor Entwickler*innen und ihren Qualifikationen aufzubauen. Ich nehme sie als Spezialist*innen für Code wahr – was sie auch sind.
Vertrauen und Delegation können das Verhalten ändern und eine Voraussetzung für verantwortungsvolles Handeln sein. Wenn Entwickler*innen in ihren Augen sinnlose Entscheidungen umsetzen müssen, werden sie versuchen, diese Entscheidungen zu unterlaufen. Wenn das gesamte Projekt sinnlos erscheint, werden sie sich Ecken suchen, in denen sie herumspielen können. Wenn Entwickler*innen aber selbst Entscheidungen treffen, werden sie sich anders verhalten müssen. Sie können nicht einfach nur kritisieren, sondern müssen selbst konstruktiv sein. Außerdem müssen sie mit den Konsequenzen leben – also werden sie sich die Entscheidungen gut überlegen.
Als Bezeichnung für einen Schritt hin zu mehr Vertrauen finde ich "Leap of Faith" (Sprung des Glaubens) gut: Man glaubt an die Entwickler*innen und springt ins Unbekannte, was natürlich Mut erfordert.
Wenn ihr Vorgehen optimierbar ist, hilft Kontrolle eben nicht weiter, denn diese lässt sich halt unterlaufen. Stattdessen sollten Wissensaustausch und -transfer im Fokus stehen. Wenn Entwickler*innen sowohl die Ziele als auch ihre technische Umsetzung verstanden haben, gibt es eine relativ hohe Wahrscheinlichkeit, dass sie die Konzepte der technischen Umsetzung auch befolgen. Und wenn nicht: War es vielleicht doch keine gute Idee? Vielleicht haben sie sogar eine bessere? So kann es offene, produktive Diskussionen und Verbesserungen geben.
So tritt an die Stelle von Kontrolle eine Zusammenarbeit, bei der unterschiedliche Sichtweisen der Beteiligten ausgetauscht werden und so sogar noch bessere Lösungen entstehen, als dies durch Kontrollen alleine möglich wäre. Entwickler*innen sind eben auch Spezialist*innen für ihren Bereich.
Nun kann man natürlich sagen, dass Management und Architekt*innen endlich den Entwickler*innen gegenüber den nötigen Respekt und das nötige Vertrauen zollen müssen – und damit ist das Problem endlich gelöst!
Respekt ist aber keine Einbahnstraße. Entwickler*innen müssen auch Management und Architekt*innen Respekt entgegenbringen und ihnen vertrauen. Sonst sind wohl kaum Diskussionen auf Augenhöhe möglich. Sie sind ebenfalls Expert*innen – nur eben in anderen Bereichen. Architekt*innen können beispielsweise größere Systeme strukturieren und das Management sich um die Organisation kümmern.
Wechselseitiger Respekt und Vertrauen sind die Grundlage für erfolgreiche Zusammenarbeit.
Vielen Dank an meine Kolleginnen und Kollegen Christoph Iserlohn, Robert Glaser, Anja Kammer, Michel Krämer, Martin Kühl, Stefan Tilkov, Hermann Schmidt und Benjamin Wolf für die Kommentare zu einer früheren Version des Artikels.
URL dieses Artikels:https://www.heise.de/-4786297
Links in diesem Artikel:[1] https://cloud.google.com/devops/state-of-devops/[2] https://www.heise.de/news/Studie-Entwickler-programmieren-in-der-Freizeit-weiter-4782219.html[3] https://www.coderetreat.org/
Copyright © 2020 Heise Medien
In der Softwarearchitektur nimmt die Diskussion von Zielbildern viel Platz ein – schließlich muss es ein Ziel geben, auf das man hinarbeitet. Aber die Prioritäten sollten anders verteilt sein, und eigentlich sind Zielbilder auch nicht das Ziel.
Zielbilder stellen dar, wie eine Architektur idealerweise aussehen sollte und in welche Teile das System zerlegt werden soll. Der Entwurf einer solchen Architektur scheint die zentrale Architekturherausforderung zu sein: kein Wunder, dass Teams dieser Aufgabe so viel Zeit einräumen.
In den meisten Fällen ist aber schon eine Architektur vorhanden. Eine neue muss eigentlich die vorhandene Architektur als Rahmenbedingungen für den Entwurf mitbetrachten. Dennoch erscheint eine Zielarchitektur sinnvoll: Schließlich muss man wissen, auf welches Ziel man hinarbeiten muss. Die vorhandene Architektur dabei mitzubetrachten, kann dazu verleiten, die Fehler der Vergangenheit zu wiederholen.
Wenn das Zielbild fertig ist, muss man die Frage nach der Umsetzbarkeit stellen: Wann lässt sich das Zielbild mit welchem Aufwand erreichen? Spätestens an dieser Stelle wird oft klar, dass ein Zielbild alles andere als einfach zu erreichen ist. Aber das war auch gar nicht die Idee beim Entwurf des Zielbilds: Es soll eine Architekturutopie darstellen, die daher nicht realistisch erreichbar sein muss.
Die Diskussion über das Zielbild ist jedoch nur dann sinnvoll, wenn sie Auswirkungen auf das Projekt hat. Das Zielbild hat oft kaum noch etwas mit der aktuellen Situation zu tun. Es gibt also unzählige Stellen, an denen man auf das Zielbild hinarbeiten kann. Wo aber anfangen?
Für eine Zielbilddiskussion drängt sich der Vergleich mit einer Expedition zu einem Berggipfel auf: Natürlich ist es sinnvoll, einen Blick auf den Berggipfel in der Ferne zu werfen, um zu schauen, ob man in die richtige Richtung unterwegs ist. Aber noch wichtiger sind der nächste Schritt und der nächste Fluss oder das nächste Hindernis, das es zu überwinden gilt.
Die Metapher der Expedition nimmt an, dass man das Zielbild, also den Berggipfel, erreichen wird. Bei einem Architekturzielbild ist das nicht unbedingt so: Ich jedenfalls sehe praktisch nie Projekte, die das Zielbild erreicht haben. Das kann aber daran liegen, dass Berater*innen nur dann gebraucht werden, wenn es gilt, etwas zu verbessern, und daher kaum perfekte Projekte sehen.
Wichtiger als eine Diskussion zum Erreichen eines Zielbilds finde ich daher konkrete Maßnahmen, um in einem Projekt besser zu werden. Solche Aktivitäten müssen nicht auf die Strukturierung des Systems begrenzt sein, wie es der Begriff "Zielbild" nahelegt, sondern es können ganz unterschiedliche Aktivitäten im Bereich von Entwicklung, Betrieb oder auch Anforderungsmanagement sein. Solche Maßnahmen sind im Gegensatz zu einem Zielbild tatsächlich umsetzbar und bringen schon kurzfristig einen Nutzen.
Eigentlich ist ein Zielbild sogar verzichtbar. Die Stakeholder eines Systems interessieren sich für Features und Qualitäten der Software wie Performance oder Sicherheit. Der interne Aufbau, den ein Zielbild zeigt, ist nur wichtig, wenn er Qualitäten wie die Wartbarkeit beeinflusst. Das Zielbild beeinflusst viele wichtige Qualitäten wie Benutzerfreundlichkeit gar nicht. Die Features und Qualitäten sind eigentlich die Ziele des Projekts. Sie haben sogar weitergehende Konsequenzen: Qualitäten wie Benutzerfreundlichkeit können wesentlich für den Erfolg eines Produkts oder gar einer Firma sein.
Die meisten Architekturdokumentationen, die ich bei Reviews oder Beratungen sehe, zeigen eine Aufteilung des Systems oder ein Zielbild, oft sogar als Hauptartefakt. Die Ziele des Projekts und die daraus abgeleiteten Features und Qualitäten finden sich nur sehr selten, obwohl sie wichtiger wären. Und genau hier wäre eine Zieldiskussion angebracht: Was soll das Projekt erreichen? Welche Features und Qualitätsziele müssen erfüllt sein? Das führt zu einem besseren Verständnis für die Domäne und damit zu einer besseren Grundlage für das Projekt.
Und dann sollte es Maßnahmen geben, um die Qualitätsziele auch tatsächlich zu erreichen. Auch das kommt in den meisten Projekten zu kurz. Schließlich mag Benutzerfreundlichkeit ja wichtig sein, aber es in der Architektur zu betrachten, unterbleibt dann doch oft.
Vielleicht ist das also der Berggipfel, den wir in Wirklichkeit in Augenschein nehmen und dann erklimmen sollten.
Vielen Dank an meine Kolleginnen und Kollegen Anja Kammer und Martin Otten für die Kommentare zu einer früheren Version des Artikels.
Diskussionen über Zielbilder können zwar hilfreich sein, aber nur konkrete Maßnahmen führen zu einer wirklichen Verbesserung. Und wichtiger als ein Architekturzielbild ist Klarheit über das Ziel des Projekts.
URL dieses Artikels:https://www.heise.de/-4772393
Copyright © 2020 Heise Medien
Quick fix for FreshRSS 1.16.1.
loading="lazy" for favicons #2962.stick elements in older Webkit browsers #2995lib_phpQuery for full-content retrieval #3004FRESHRSS_ENV environment variable #2963Progressive Web Apps (PWA) erhalten mehr und mehr Zugriff auf native Funktionen. Ein häufig nachgefragtes, bislang nicht vorhandenes Feature sind Schnellaktionen. Diese Möglichkeit steht auf Android nun erstmals zur Verfügung.
Progressive Web Apps lassen sich auf Mobil- und Desktop-Systemen installieren und erscheinen dann auf dem Home-Bildschirm oder in der Programmliste. Das Aussehen und Verhalten der installierten PWA definiert das Web App Manifest [1].
Unter iOS gibt es für Home-Bildschirm-Icons sogenannte Schnellaktionen, Symbole in der Windows-Taskbar können Sprunglisten definieren und auch in macOS lassen sich im Dock häufig verwendete Aktionen hinterlegen. Diese Shortcuts stellen einen zweiten Einsprungspunkt in die Anwendung dar. Eine PWA konnte keine solche Shortcuts definieren – bis jetzt.

Der Arbeitsentwurf der Web-App-Manifest-Spezifikation wurde vergangenen November dazu um die Eigenschaft shortcuts [2] ergänzt, die eine Auflistung von Shortcut-Items entgegennimmt. Ein solches Element besteht mindestens aus einem Titel (Eigenschaft title) und einer zu öffnenden URL (url), optional lassen sich ein Kurztitel (short_name), eine Beschreibung (description) und Symbole (icons) angeben:
{
"shortcuts": [
{
"name": "New Email message",
"description": "Compose a new email.",
"url": "/mails/new",
"icons": [
{
"src": "/icons/mail.svg",
"type": "image/svg+xml",
"purpose": "any"
}
]
},
{
"name": "New Appointment",
"description": "Create a new appointment.",
"url": "/appointments/new"
}
]
}
Bei der Installation der Webanwendung kann der jeweilige Browser die Einträge an der passenden Stelle hinterlegen, unter Windows beispielsweise als Sprungliste, unter iOS könnten sie als Schnellaktionen auf dem Home-Bildschirm erscheinen, sofern Apple sich zur Implementierung der Funktion entschließt. Gegenwärtig sind die Einträge statisch, es gibt also keine Schnittstelle, um die Einträge zur Laufzeit zu modifizieren.
Die Shortcuts sind ein Prio-1-Feature von Project Fugu [3], Microsoft implementiert das Feature aktuell in Chromium [4]. Mit der Vorschauversion Google Chrome Canary kann das Feature auf Android bereits getestet werden, zum Beispiel auf der Beispiel-PWA https://pwa.liebel.io [5]. In auf Chromium basierenden Browsern dürften PWA-Entwickler zeitnah auch plattformübergreifend auf die Funktion zugreifen können. Informationen zur Implementierung in Mozilla Firefox und Apple Safari gibt es zwar noch nicht. Das Web App Manifest begibt sich demnächst jedoch in Richtung W3C-Empfehlungskandidat – und mit ihm auch die Shortcuts.
URL dieses Artikels:https://www.heise.de/-4722790
Links in diesem Artikel:[1] https://www.heise.de/developer/artikel/Progressive-Web-Apps-Teil-3-Wie-die-Web-App-zur-App-App-wird-3464603.html[2] https://www.w3.org/TR/appmanifest/#shortcuts-member[3] https://www.heise.de/developer/artikel/Google-Projekt-Fugu-Die-Macht-des-Kugelfisches-4255636.html[4] https://bugs.chromium.org/p/chromium/issues/detail?id=955497[5] https://pwa.liebel.io
Copyright © 2020 Heise Medien
![]()
Das storylastige Survival-Spiel Green Hell kann man nun mit bis zu vier Leuten im Team zocken, außerdem gibts neue Inhalte – wir haben es zu zweit ausprobiert.
Bereits im August 2019 hat das Survival-Spiel Green Hell seine Early-Access-Phase abgeschlossen [1] und enthält eine komplette Single-Player-Kampagne im Storymodus. Und das Indie-Entwicklerstudio Creepy Jar aus Warschau macht weiter: Inzwischen hat Green Hell auch einen Multiplayer-Modus für bis zu vier Personen erhalten, mit dem man gemeinsam im brasilianischen Regenwald ums Überleben kämpft. Weitere neue Inhalte umfassen beispielsweise den Anbau von Pflanzen. Das c't-zockt-Team testet den Multiplayermodus in einem neuen Let's Play im c't-zockt-YouTube-Channel [2].
Das Survival-Spiel wird seinem Genre gerecht und macht das Überleben alles andere als leicht: Gemeinsam landet man in einem veritablen Dschungel und muss erst lernen, was man essen kann – und was besser nicht –, wie man Trinkwasser sammelt, Wunden desinfiziert, sich Werkzeuge und eine Unterkunft baut. Gefahren gibt es mit giftigen Schlangen, Spinnen, angriffslustigen Raubkatzen und Eingeborenen reichlich. Doch auch Krankheiten und Parasiten wie Blutegel und Würmer unter der Haut machen einem das Leben schwer.
Green Hell ist für 21 Euro bei Steam [5] für Windows erhältlich. In unserem Test lief es mit Steam Play / Proton auch unter Linux.
()
c't zockt sammelt die Gamer des c't Magazins und von heise online. Wir spielen Games quer Beet, gern Indie- und Early-Access-Spiele, haben ein Herz für Retro-Titel und wagen uns gelegentlich in die Virtual Reality.
Wir streamen Live-LAN-Parties aus unserem Videostudio auf YouTube und veröffentlichen dort außerdem regelmäßig neue Videos rund um Spiele. Schaut doch mal rein: youtube.com/ctzockt [7]
URL dieses Artikels:https://www.heise.de/-4718768
Links in diesem Artikel:[1] https://www.heise.de/ct/artikel/c-t-angezockt-Green-Hell-Ueberleben-im-Regenwald-4537363.html[2] https://youtube.com/ctzockt[3] https://www.heise.de/bilderstrecke/bilderstrecke_4719572.html?back=4718768;back=4718768[4] https://www.heise.de/bilderstrecke/bilderstrecke_4719572.html?back=4718768;back=4718768[5] https://store.steampowered.com/app/815370/Green_Hell/[6] mailto:rop@ct.de[7] https://www.youtube.com/ctzockt
Copyright © 2020 Heise Medien
lib_phpQuery) #2874
#article .title, #article .content!date: allowing to exclude any date interval #2869
!date:P1W (exlude articles newer than 1 week), !pubdate:2019, -date:2020-01-01/P5d, etc.newestItemTimestampUsec #2853HTTP/1.x 200 OK for an empty request, to ease discovery #2855author: #2806COPY_LOG_TO_SYSLOG and FRESHRSS_ENV controlling logging #2745foreach in applyFilterActions #2809lib_phpQuery when fetching the full content of HTML documents with a complex <head ...> #2864yield #2588
<audio> widgets to use the full width of the reading zone, to help navigation in e.g. podcasts #2875<p> instead of <pre> to display <media:description> information #2807#force_feed simplepie#643
./extensions/ is solely for third-party extensions #2837
./extensions/ as a Docker volume, to ease adding third-party extensionscheck_url_before_add and feed_before_actualize #2704entry_before_display hook also through the API #2762Im letzten Teil dieser Serie werden die drei gezeigten Mechanismen noch einmal kurz zusammengefasst. Außerdem geht es um die Frage, wie sich Fehler bei der Hintergrundsynchronisation aufspüren und beheben lassen. Dazu sind die Chrome DevTools besonders nützlich.
In den vergangenen drei Teilen der Serie wurden die folgenden Schnittstellen vorgestellt:
Diese drei Schnittstellen laufen aktuell nur auf Chromium-basierten Browsern. Ob Mozilla und Apple diese auch implementieren, ist nicht sicher. Der Background Fetch, aber vielleicht auch die Web Periodic Background Sync API sind dabei höhere Chancen einzuräumen als der Web Background Sync API in ihrer heutigen Form.
Als vierte Möglichkeit kommt auch noch die Push API in Betracht. Bei eingehenden Push-Nachrichten hat der Service Worker ebenfalls noch kurz Zeit, eine bestimmte Synchronisationslogik durchzuführen. Das ist ebenfalls mehrfach und theoretisch ohne Intervallbeschränkung möglich, allerdings muss für jedes eingegangene Ereignis eine Push-Benachrichtigung dargestellt werden. Auf diese Art können Messenger-Apps etwa die eingegangene Nachricht gleich in der lokalen Clientdatenbank hinterlegen, sodass kein erneutes Abrufen beim Öffnen der Anwendung erforderlich ist. Die Schnittstelle ist neben Google Chrome und Microsoft Edge auch in Mozilla Firefox verfügbar, nicht jedoch in Safari und auf den Plattformen iOS und macOS.
Die vorgestellten Mechanismen zur Hintergrundsynchronisation lassen sich mithilfe der DevTools auf Chromium-basierten Browsern wie Google Chrome oder Microsoft Edge gut debuggen. Geöffnet werden sie mit F12. Als besonders hilfreich erweist sich dazu die Application-Registerkarte in den Entwicklertools. Hier ist im Bereich Service Worker zunächst die Service-Worker-Registrierung zu sehen, die für alle Schnittstellen vorausgesetzt wird. Ebenfalls befindet sich dort die Möglichkeit, ein Ereignis für die Background Sync, Periodic Sync oder Push API zu simulieren. Dazu wird in das Textfeld das Tag (Sync) beziehungsweise die Nachricht (Push) eingegeben, für das das jeweilige Ereignis ausgelöst werden soll. Per Klick auf die Schaltfläche neben dem Textfeld wird es direkt ausgelöst.

Per Klick auf den Skriptnamen wechseln die Entwicklertools in das Sources-Tab und öffnen dort direkt den Quelltext der Service-Worker-Implementierung. Hier können, wie Entwickler es von integrierten Entwicklungsumgebungen gewohnt sind, Breakpoints gesetzt, lokale Variablen inspiziert und die Ausführung bei aufgetretenen Fehlern unterbrochen werden.

Im Sources-Tab lassen sich auch die Quelltexte der Webanwendung untersuchen, sodass auch die Registrierung für Synchronisierungsereignisse auf diese Art geprüft werden kann. Schließlich befindet sich im Application-Tab auch der Bereich Background Services. Hier können in den Sichten Background Sync, Background Fetch, Notifications und Push Messaging per Klick auf das Record-Symbol die aufgetretenen Ereignisse für die jeweilige Schnittstellenart aufgezeichnet werden. Das geschieht für bis zu drei Tage und auch dann, wenn die DevTools nicht geöffnet sind. Die aufgetretenen Ereignisse können dann im Protokoll nachverfolgt werden.

Hintergrundereignisse verbessern die PWA-Erfahrung für Anwender noch weiter. Die Schnittstellen eben Cloud-Sync-Clients, Messenger, Nachrichten-Apps und viele weiteren Anwendungsarten den Weg ins Web. Machen Sie Ihre Progressive Web App also noch besser und statten Sie diese um die gezeigten Möglichkeiten zur Hintergrundsynchronisation aus.
URL dieses Artikels:https://www.heise.de/-4691413
Links in diesem Artikel:[1] https://www.heise.de/developer/artikel/Hintergrund-Synchronisation-fuer-PWAs-Teil-1-Background-Sync-API-4676538.html[2] https://www.heise.de/developer/artikel/Hintergrund-Synchronisation-fuer-PWAs-Teil-2-Background-Fetch-API-4681556.html[3] https://www.heise.de/developer/artikel/Hintergrund-Synchronisation-fuer-PWAs-Teil-3-Periodic-Sync-API-4685964.html
Copyright © 2020 Heise Medien
Im dritten Teil dieser Serie widmen wir uns der Periodic Sync API, der neuesten Schnittstelle zur Umsetzung von Hintergrundsynchronisation für Progressive Web Apps und andere Anwendungen. Diese soll einen wiederkehrenden Datenaustausch ermöglichen.
Mit der Schnittstelle soll im Gegensatz zur Background Sync API [1] und Background Fetch API [2] eine Möglichkeit geschaffen werden, Synchronisierungsereignisse regelmäßig mehr als einmal auslösen zu können. Das Vorgehen eignet sich etwa für Nachrichtenanwendungen, die regelmäßig im Hintergrund die offline vorgehaltenen Artikel aktualisieren wollen. Die Web Periodic Background Sync API [3] setzt auf der Background Sync API aus dem ersten Teil [4] auf. Sie möchte die originale Schnittstelle erweitern und die dort angesprochenen Schwachpunkte adressieren. So ist zur Verwendung der Schnittstelle diesmal zuerst eine Berechtigungsabfrage erforderlich:
const permission = await navigator.permissions.query({
name: 'periodic-background-sync'
});
if (permission.state === 'granted') {
// Periodic Sync API available
} else {
// Periodic Sync API not available
}
Wie die Background Sync API zeigt auch die Periodic Background Sync API keine Information auf der Benutzeroberfläche an, wenn ein Hintergrundvorgang im Gange ist (vergleichbar zu nativen Apps). Wie alle zuvor genannten Ansätze ist auch für diese Schnittstelle zunächst eine Service-Worker-Registrierung erforderlich und Entwickler müssen separat auf das Vorhandensein der Webschnittstelle prüfen. Ist das PeriodicSyncManager-Interface im globalen Window-Objekt vorhanden, steht die API auf dem Zielsystem zur Verfügung. Auf der Service-Worker-Registrierung steht die Instanz des PeriodicSyncManager zur Verfügung. Wenn der Anwender zuvor zugestimmt hat, können sich Entwickler über die Methode register() für ein periodisches Synchronisierungsereignis registrieren:
navigator.serviceWorker.ready.then(async registration => {
if ('PeriodicSyncManager' in window) {
try {
await registration.periodicSync.register('articles', {
minInterval: 24 * 60 * 60 * 1000
});
} catch (error) {
// Periodic background sync cannot be used.
}
}
});
Neben dem verpflichtenden, aus Teil 1 bekannten Bezeichner (im Beispiel articles) lässt sich in einem Konfigurationsobjekt das gewünschte Mindestintervall angeben (im Beispiel ein Ereignis pro Tag). Über das tatsächliche Aufrufintervall entscheidet jedoch der Webbrowser.
In Chromium-basierten Browsern ist die Anwendung zunächst auf dem Gerät zu installieren. Nur in diesem Fall gibt die oben gezeigte Berechtigungsabfrage granted zurück. Ein Abfragefenster erscheint übrigens nicht, da Chrome die Installation der Anwendung als implizite Einwilligung ansieht. Dann hängt die Entscheidung, ob und wie oft eine Website die Schnittstelle nutzen darf, von ihrem Site-Engagement-Score ab. Dieser beträgt zwischen 0 und 100 Punkten, wird durch die Verwendung der Website beeinflusst und lässt sich unter chrome://site-engagement einsehen.
Da Websites im Hintergrund Rechenzeit nutzen können und damit den Akku belasten, ist die Nutzung überhaupt nur Websites gestattet, die regelmäßig genutzt werden, die also einen Site-Engagement-Score größer 0 haben. Je höher er ist, desto öfter dürfen die Ereignisse ausgelöst werden, im Bestfall einmal pro Tag. Wird eine Website irgendwann nicht mehr so oft genutzt, wird auch die Synchronisierung weniger häufig ausgelöst. Ist der Browser schließlich noch der Ansicht, dass Anwender gerade online sind (mit den im ersten Teil beschriebenen Einschränkungen), wird im Service Worker das Ereignis periodicsync ausgelöst. Wie zuvor ist auch hier keine erneute Prüfung der Existenz der Schnittstelle erforderlich, da das Ereignis auf Browsern ohne Unterstützung für die API einfach nicht aufgerufen wird:
self.addEventListener('periodicsync', event => {
if (event.tag === 'articles') {
event.waitUntil(syncArticles());
}
});
Der Service Worker kann dann wieder eine beliebige Synchronisierungslogik durchführen, etwa einen HTTPS-Request auslösen und die empfangenen Daten in den Cache legen oder den erhaltenen Datenstand mit der lokalen IndexedDB-Instanz zusammenführen.
Die Web Periodic Background Synchronization API ist seit Google Chrome 80 verfügbar – auch auf anderen Browsern, die auf die Chromium-Engine aufsetzen, wie Microsoft Edge. Eine Demoanwendung zum Testen der Schnittstelle steht hier [5] zur Verfügung. Dieser Patch [6] zeigt, was zu tun ist, um eine bestehende PWA mit Periodic-Sync-Funktionalität auszustatten. Die Periodic Sync API bietet sich für alle Anwendungen an, deren Zustand sich im Hintergrund regelmäßig ändert: Nachrichten-, ERP- oder Social-Media-Anwendungen. Dank dieser Schnittstellen erhalten Nutzer beim Öffnen der Anwendung immer einen relativ frischen Datenstand. Im nächsten und letzten Teil dieser Serie werden die drei vorgestellten Synchronisationsmechanismen noch einmal kurz zusammengefasst und gezeigt, wie man diese debuggen kann.
URL dieses Artikels:https://www.heise.de/-4685964
Links in diesem Artikel:[1] https://www.heise.de/developer/artikel/Hintergrund-Synchronisation-fuer-PWAs-Teil-1-Background-Sync-API-4676538.html[2] https://www.heise.de/developer/artikel/Hintergrund-Synchronisation-fuer-PWAs-Teil-2-Background-Fetch-API-4681556.html[3] https://wicg.github.io/BackgroundSync/spec/PeriodicBackgroundSync-index.html[4] https://www.heise.de/developer/artikel/Hintergrund-Synchronisation-fuer-PWAs-Teil-1-Background-Sync-API-4676538.html[5] https://so-pwa.firebaseapp.com/[6] https://github.com/GoogleChromeLabs/so-pwa/pull/11/files
Copyright © 2020 Heise Medien
Die zweite Schnittstelle zur Hintergrundsynchronisation von Daten ist die Background Fetch API. Über sie können selbst größere Datenmengen im Hintergrund übertragen werden. Der Browser zeigt den Fortschritt an und gibt Anwendern damit eine Kontrollmöglichkeit.
Im vergangenen Teil dieser Serie [1] wurde die Background Sync API vorgestellt, die einmalig im Hintergrund einen Synchronisierungsvorgang durchführen darf. Die Synchronisierungslogik lässt sich im Service Worker feingranular steuern. Da die Schnittstelle bei Aktivität jedoch keinen Indikator anzeigt und keiner Freigabe durch den Anwender bedarf, ist sie im Hinblick auf den Datenschutz unter den Browserherstellern umstritten. Die Background Fetch API [2] geht einen anderen Weg: Hier können Entwickler eine Reihe von Netzabfragen definieren, die im Hintergrund ausgeführt werden. Damit können Daten zum Anwendungsserver hoch- und von diesem heruntergeladen werden.
Die Ausführung übernimmt der Browser, der Service Worker wird hierfür zunächst nicht gebraucht. Außerdem wird eine Benutzeroberfläche dargestellt, die Anwendern die Durchführung und den Fortschritt der Aktion verdeutlicht. Die Schnittstelle eignet sich beispielsweise für Streaming-Dienste, die Inhalte offline speichern wollen, Navigations-Apps, die im Hintergrund Kartenmaterial herunterladen oder Cloud-Synchronisierungsdienste.
Die Background Fetch API stellt eine Erweiterung der Service-Worker-Schnittstellen dar. Und auch hier muss zunächst wieder geprüft werden, ob der Zielbrowser die Schnittstelle unterstützt. Ist das BackgroundFetchManager-Interface vorhanden, kann auf dessen Instanz auf der Service-Worker-Registrierung die Methode fetch() aufgerufen werden.
navigator.serviceWorker.ready.then(registration => {
if ('BackgroundFetchManager' in window) {
registration.backgroundFetch.fetch('offline-songs', [
'songs/Katy_Perry/Firework.mp3',
'songs/Hilltop_Hoods/1955.mp3',
'songs/The_Script/Nothing.mp3'
], {
title: 'Songs für Offlinewiedergabe speichern…'
});
}
});

Diese nimmt zunächst eine ID entgegen, anhand derer die Gruppe der Netzwerkabfragen identifiziert werden kann. Als zweites Argument wird die Liste der abzurufenden Ressourcen hinterlegt. Für einfache GET-Requests genügt es, die Zeichenkette der abzufragenden URL zu hinterlegen. Komplexere Abfragen mit Nutzlast lassen sich hier aber ebenfalls hinterlegen. Schließlich kann ein Konfigurationsobjekt angegeben werden, dem etwa der Titel der Aktion für die Anzeige auf der Benutzeroberfläche mitgegeben werden kann. Auch ließen sich hier ein Icon hinterlegen und die Gesamtanzahl herunterzuladender Bytes überschreiben.
Nach Abschluss der Aktion wird das Ereignis backgroundfetchsuccess auf dem Service Worker aufgerufen. Hierfür ist keine Prüfung erforderlich, die Schnittstelle wird auf Browsern ohne Unterstützung schlichtweg nicht aufgerufen. Hier haben Entwickler Zugriff auf die Antworten des Anwendungsservers und können diese verarbeiten: entweder im Service-Worker-Cache oder in der IndexedDB hinterlegen. Da der Service Worker unabhängig von der Webanwendung ausgeführt werden kann, muss diese hierfür nicht geöffnet sein. Im folgenden Beispiel werden die oben angeforderten Songdateien nach erfolgreichem Download im Service-Worker-Cache hinterlegt und stehen dort künftig auch offline zur Verfügung:
self.addEventListener('backgroundfetchsuccess', event => {
event.waitUntil(async () => {
const cache = await caches.open('songs');
const songRecords = await event.registration.matchAll();
const promises = songRecords.map(async songRecord => {
const response = await songRecord.responseReady;
await cache.put(songRecord.request, response);
});
await Promise.all(promises);
event.updateUI({ title: 'Songs heruntergeladen.' });
});
});
Zugriff auf die Einträge erhalten Entwickler über die Eigenschaft registration. Die Oberfläche lässt sich nach Abschluss der Aktion über die Methode updateUI() auf Wunsch noch aktualisieren.
Die Background Fetch API wurde 2018 in Chromium implementiert [3]. Seit Google Chrome 74 ist sie generell verfügbar und auch in anderen Chromium-basierten Browsern wie Microsoft Edge anzutreffen. Von Mozilla Firefox und Apple Safari wird sie derzeit nicht implementiert. Unter backgroundfetch.com [4] kann sie unter Chromium-basierten Browsern auf dem Desktop oder Android interaktiv ausprobiert werden.
Wie die Background Sync API unterstützt Background Fetch nur einen einmaligen Datenaustausch. Nachrichtenanwendungen könnten hingegen regelmäßig im Hintergrund ihre Inhalte aktualisieren wollen, um dem Anwender direkt beim Öffnen eine aktuelle Auswahl von Artikeln präsentieren zu können. Diese Funktionalität möchte die Periodic Background Sync API ins Web bringen. Mehr dazu im nächsten Teil dieser Serie.
URL dieses Artikels:https://www.heise.de/-4681556
Links in diesem Artikel:[1] https://www.heise.de/developer/artikel/Hintergrund-Synchronisation-fuer-PWAs-Teil-1-Background-Sync-API-4676538.html[2] https://wicg.github.io/background-fetch/[3] https://developers.google.com/web/updates/2018/12/background-fetch[4] https://backgroundfetch.com
Copyright © 2020 Heise Medien
In dieser Reihe geht es um die Möglichkeit, im Hintergrund Daten zwischen einer Progressive Web App und dem Anwendungsserver auszutauschen – auch dann, wenn die Anwendung gar nicht geöffnet ist. Den Anfang macht die Web Background Synchronization API, die in auf Chromium basierenden Browsern schon seit 2016 funktioniert.
Progressive Web Apps laufen dank dem Service Worker und der IndexedDB offline: Im Cache des Service Worker können die Quelldateien der Anwendung offline gehalten werden, in der lokalen Clientdatenbank die strukturierten Anwenderdaten. Die Background Sync API [1] möchte Progressive Web Apps nun um die Funktionalität ausstatten, Daten auch im Hintergrund mit dem Anwendungsserver auszutauschen. Das Verhalten ist von nativen Anwendungen wie WhatsApp bekannt: Anwender können eine Nachricht verfassen, absenden und das Smartphone wieder wegpacken. Besteht eine Internetverbindung, wird die Nachricht direkt verschickt. Andernfalls wird sie im Hintergrund übermittelt, sobald wieder eine Verbindung zur Verfügung steht. Die App muss dafür nicht noch einmal geöffnet, das Smartphone nicht noch einmal aus der Hosentasche gekramt werden.
Bei der Background Sync API handelt es sich um eine Erweiterung der Service-Worker-Schnittstellen [2], eine der technischen Grundlagen von Progressive Web Apps. Ein Service Worker ist ein Stück JavaScript, das von der Website registriert wird. Das Skript kann anschließend losgelöst von der ursprünglichen Website laufen – also auch dann, wenn die Website gar nicht geöffnet ist. Genau diese Eigenschaft macht man sich bei der Background Sync API zunutze.
Da nicht jeder Browser mit Unterstützung für Service Worker auch die Web Background Sync API unterstützt, müssen Entwickler vor der Verwendung der Schnittstelle sowohl die Existenz der Service-Worker-API als auch die des SyncManager-Interfaces prüfen. Ist es vorhanden, lässt sich innerhalb der Webanwendung über die Service-Worker-Registrierung auf die Instanz des SyncManagers zugreifen. Hier können Synchronisierungsereignisse mit einem bestimmten Bezeichner (Tag) registriert werden. Im Falle des Messenger-Beispiels würde die register()-Methode des SyncManagers nach jeder abgeschickten Nachricht aufgerufen werden:
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('./sw.js');
navigator.serviceWorker.ready.then(registration => {
if ('SyncManager' in window) {
registration.sync.register('messages');
}
});
}
Aufseiten des Service-Worker-Skripts implementiert man einen Ereignis-Handler für das von der Background Sync API definierte sync-Ereignis. Bei der Ereignisregistrierung ist übrigens keine Prüfung auf die Existenz der API erforderlich, das Ereignis wird in Browsern ohne Unterstützung für die Web Background Sync API schlichtweg nicht aufgerufen. Bei bestehender Internetverbindung wird der Ereignis-Handler direkt aufgerufen. Andernfalls wird das Auslösen des Ereignisses solange verzögert, bis der Webbrowser der Ansicht ist, dass wieder eine Verbindung besteht. Mit absoluter Sicherheit lässt sich das aber nie sagen: Trotz hervorragender WiFi-Verbindung muss nicht zwingend eine Verbindung zum Internet bestehen (z.B. Drucker-WLANs). Und trotz EDGE-Empfang müssen Pakete nicht zwingend ihr Ziel finden. Ein Restrisiko, dass die Synchronisation dennoch nicht stattfinden kann, bleibt also.
Sollte beim Durchführen der Synchronisationslogik ein Fehler auftreten, kann der Webbrowser den Ereignis-Handler noch mehrmals aufrufen. Beim letzten Versuch ist die Eigenschaft lastChance in den Ereignisargumenten auf true gesetzt. Auf ihnen ist in der Eigenschaft tag der Bezeichner aus der Webanwendung zu finden. Anhand dessen ließen sich unterschiedliche Synchronisierungsabläufe wählen.
self.addEventListener('sync', event => {
if (event.tag == 'messages') {
event.waitUntil(syncMessages());
}
});
Sowohl der Service Worker als auch die Website teilen sich Zugriff auf dieselbe IndexedDB-Instanz. Die Webanwendung kann hochzuladende Inhalte in der Datenbank hinterlegen. Von dort kann der Service Worker diese dann mit dem Backend austauschen und neue oder geänderte Inhalte auf dem Rückweg in der Datenbank hinterlegen.
Da bei jeder Netzabfrage die IP-Adresse übermittelt wird, könnten Entwickler auf diese Art ein begrenztes Bewegungsprofil der Anwender erstellen. Da weder zur Installation des Service Worker noch zur Nutzung der Background Sync API eine vorherige Berechtigungsabfrage geschieht, haben Anwender keine Möglichkeit, diesem entgegenzuwirken. Auch gibt es bei der Schnittstelle keinen visuellen Indikator, dass eine PWA gerade Ereignisse im Hintergrund ausführt.
Derzeit wird die Web Background Sync API lediglich von Google Chrome und darauf basierenden Browsern wie Opera oder Microsoft Edge unterstützt. Es gilt als unwahrscheinlich, dass Apple die Schnittstelle nutzen wird. Auch in Mozilla Firefox wurde die Implementierung der Schnittstelle pausiert. Deswegen und zur Unterstützung älterer Browser müssen Entwickler immer noch einen zweiten Weg innerhalb der Webanwendung [3] implementieren, über den sich die Daten mit dem Anwendungsserver austauschen lassen. Dafür muss die Anwendung dann aber geöffnet sein.
Mit der Background Fetch API und der Periodic Sync API stehen glücklicherweise Alternativen zur Verfügung, die sich möglicherweise ihren Weg in weitere Browser bahnen könnten. Diese stelle ich in den nächsten beiden Teilen dieser Serie vor.
URL dieses Artikels:https://www.heise.de/-4676538
Links in diesem Artikel:[1] https://wicg.github.io/BackgroundSync/spec/[2] https://www.heise.de/developer/artikel/Progressive-Web-Apps-Teil-2-Die-Macht-des-Service-Worker-3740464.html[3] https://developers.google.com/web/updates/2015/12/background-sync#progressive_enhancement
Copyright © 2020 Heise Medien
Die zweite Schnittstelle zur Hintergrundsynchronisation von Daten ist die Background Fetch API. Über sie können selbst größere Datenmengen im Hintergrund übertragen werden. Der Browser zeigt den Fortschritt an und gibt Anwendern damit eine Kontrollmöglichkeit.
Im vergangenen Teil dieser Serie [1] wurde die Background Sync API vorgestellt, die einmalig im Hintergrund einen Synchronisierungsvorgang durchführen darf. Die Synchronisierungslogik lässt sich im Service Worker feingranular steuern. Da die Schnittstelle bei Aktivität jedoch keinen Indikator anzeigt und keiner Freigabe durch den Anwender bedarf, ist sie im Hinblick auf den Datenschutz unter den Browserherstellern umstritten. Die Background Fetch API [2] geht einen anderen Weg: Hier können Entwickler eine Reihe von Netzabfragen definieren, die im Hintergrund ausgeführt werden. Damit können Daten zum Anwendungsserver hoch- und von diesem heruntergeladen werden.
Die Ausführung übernimmt der Browser, der Service Worker wird hierfür zunächst nicht gebraucht. Außerdem wird eine Benutzeroberfläche dargestellt, die Anwendern die Durchführung und den Fortschritt der Aktion verdeutlicht. Die Schnittstelle eignet sich beispielsweise für Streaming-Dienste, die Inhalte offline speichern wollen, Navigations-Apps, die im Hintergrund Kartenmaterial herunterladen oder Cloud-Synchronisierungsdienste.
Die Background Fetch API stellt eine Erweiterung der Service-Worker-Schnittstellen dar. Und auch hier muss zunächst wieder geprüft werden, ob der Zielbrowser die Schnittstelle unterstützt. Ist das BackgroundFetchManager-Interface vorhanden, kann auf dessen Instanz auf der Service-Worker-Registrierung die Methode fetch() aufgerufen werden.
navigator.serviceWorker.ready.then(registration => {
if ('BackgroundFetchManager' in window) {
registration.backgroundFetch.fetch('offline-songs', [
'songs/Katy_Perry/Firework.mp3',
'songs/Hilltop_Hoods/1955.mp3',
'songs/The_Script/Nothing.mp3'
], {
title: 'Songs für Offlinewiedergabe speichern…'
});
}
});

Diese nimmt zunächst eine ID entgegen, anhand derer die Gruppe der Netzwerkabfragen identifiziert werden kann. Als zweites Argument wird die Liste der abzurufenden Ressourcen hinterlegt. Für einfache GET-Requests genügt es, die Zeichenkette der abzufragenden URL zu hinterlegen. Komplexere Abfragen mit Nutzlast lassen sich hier aber ebenfalls hinterlegen. Schließlich kann ein Konfigurationsobjekt angegeben werden, dem etwa der Titel der Aktion für die Anzeige auf der Benutzeroberfläche mitgegeben werden kann. Auch ließen sich hier ein Icon hinterlegen und die Gesamtanzahl herunterzuladender Bytes überschreiben.
Nach Abschluss der Aktion wird das Ereignis backgroundfetchsuccess auf dem Service Worker aufgerufen. Hierfür ist keine Prüfung erforderlich, die Schnittstelle wird auf Browsern ohne Unterstützung schlichtweg nicht aufgerufen. Hier haben Entwickler Zugriff auf die Antworten des Anwendungsservers und können diese verarbeiten: entweder im Service-Worker-Cache oder in der IndexedDB hinterlegen. Da der Service Worker unabhängig von der Webanwendung ausgeführt werden kann, muss diese hierfür nicht geöffnet sein. Im folgenden Beispiel werden die oben angeforderten Songdateien nach erfolgreichem Download im Service-Worker-Cache hinterlegt und stehen dort künftig auch offline zur Verfügung:
self.addEventListener('backgroundfetchsuccess', event => {
event.waitUntil(async () => {
const cache = await caches.open('songs');
const songRecords = await event.registration.matchAll();
const promises = songRecords.map(async songRecord => {
const response = await songRecord.responseReady;
await cache.put(songRecord.request, response);
});
await Promise.all(promises);
event.updateUI({ title: 'Songs heruntergeladen.' });
});
});
Zugriff auf die Einträge erhalten Entwickler über die Eigenschaft registration. Die Oberfläche lässt sich nach Abschluss der Aktion über die Methode updateUI() auf Wunsch noch aktualisieren.
Die Background Fetch API wurde 2018 in Chromium implementiert [3]. Seit Google Chrome 74 ist sie generell verfügbar und auch in anderen Chromium-basierten Browsern wie Microsoft Edge anzutreffen. Von Mozilla Firefox und Apple Safari wird sie derzeit nicht implementiert. Unter backgroundfetch.com [4] kann sie unter Chromium-basierten Browsern auf dem Desktop oder Android interaktiv ausprobiert werden.
Wie die Background Sync API unterstützt Background Fetch nur einen einmaligen Datenaustausch. Nachrichtenanwendungen könnten hingegen regelmäßig im Hintergrund ihre Inhalte aktualisieren wollen, um dem Anwender direkt beim Öffnen eine aktuelle Auswahl von Artikeln präsentieren zu können. Diese Funktionalität möchte die Periodic Background Sync API ins Web bringen. Mehr dazu im nächsten Teil dieser Serie.
URL dieses Artikels:https://www.heise.de/-4681556
Links in diesem Artikel:[1] https://www.heise.de/developer/artikel/Hintergrund-Synchronisation-fuer-PWAs-Background-Sync-API-Teil-1-4676538.html[2] https://wicg.github.io/background-fetch/[3] https://developers.google.com/web/updates/2018/12/background-fetch[4] https://backgroundfetch.com
Copyright © 2020 Heise Medien
Die zweite Schnittstelle zur Hintergrundsynchronisation von Daten ist die Background Fetch API. Über sie können selbst größere Datenmengen im Hintergrund übertragen werden. Der Browser zeigt den Fortschritt an und gibt Anwendern damit eine Kontrollmöglichkeit.
Im vergangenen Teil dieser Serie [1] wurde die Background Sync API vorgestellt, die einmalig im Hintergrund einen Synchronisierungsvorgang durchführen darf. Die Synchronisierungslogik lässt sich im Service Worker feingranular steuern. Da die Schnittstelle bei Aktivität jedoch keinen Indikator anzeigt und keiner Freigabe durch den Anwender bedarf, ist sie im Hinblick auf den Datenschutz unter den Browserherstellern umstritten. Die Background Fetch API [2] geht einen anderen Weg: Hier können Entwickler eine Reihe von Netzabfragen definieren, die im Hintergrund ausgeführt werden. Damit können Daten zum Anwendungsserver hoch- und von diesem heruntergeladen werden.
Die Ausführung übernimmt der Browser, der Service Worker wird hierfür zunächst nicht gebraucht. Außerdem wird eine Benutzeroberfläche dargestellt, die Anwendern die Durchführung und den Fortschritt der Aktion verdeutlicht. Die Schnittstelle eignet sich beispielsweise für Streaming-Dienste, die Inhalte offline speichern wollen, Navigations-Apps, die im Hintergrund Kartenmaterial herunterladen oder Cloud-Synchronisierungsdienste.
Die Background Fetch API stellt eine Erweiterung der Service-Worker-Schnittstellen dar. Und auch hier muss zunächst wieder geprüft werden, ob der Zielbrowser die Schnittstelle unterstützt. Ist das BackgroundFetchManager-Interface vorhanden, kann auf dessen Instanz auf der Service-Worker-Registrierung die Methode fetch() aufgerufen werden.
navigator.serviceWorker.ready.then(registration => {
if ('BackgroundFetchManager' in window) {
registration.backgroundFetch.fetch('offline-songs', [
'songs/Katy_Perry/Firework.mp3',
'songs/Hilltop_Hoods/1955.mp3',
'songs/The_Script/Nothing.mp3'
], {
title: 'Songs für Offlinewiedergabe speichern…'
});
}
});

Diese nimmt zunächst eine ID entgegen, anhand derer die Gruppe der Netzwerkabfragen identifiziert werden kann. Als zweites Argument wird die Liste der abzurufenden Ressourcen hinterlegt. Für einfache GET-Requests genügt es, die Zeichenkette der abzufragenden URL zu hinterlegen. Komplexere Abfragen mit Nutzlast lassen sich hier aber ebenfalls hinterlegen. Schließlich kann ein Konfigurationsobjekt angegeben werden, dem etwa der Titel der Aktion für die Anzeige auf der Benutzeroberfläche mitgegeben werden kann. Auch ließen sich hier ein Icon hinterlegen und die Gesamtanzahl herunterzuladender Bytes überschreiben.
Nach Abschluss der Aktion wird das Ereignis backgroundfetchsuccess auf dem Service Worker aufgerufen. Hierfür ist keine Prüfung erforderlich, die Schnittstelle wird auf Browsern ohne Unterstützung schlichtweg nicht aufgerufen. Hier haben Entwickler Zugriff auf die Antworten des Anwendungsservers und können diese verarbeiten: entweder im Service-Worker-Cache oder in der IndexedDB hinterlegen. Da der Service Worker unabhängig von der Webanwendung ausgeführt werden kann, muss diese hierfür nicht geöffnet sein. Im folgenden Beispiel werden die oben angeforderten Songdateien nach erfolgreichem Download im Service-Worker-Cache hinterlegt und stehen dort künftig auch offline zur Verfügung:
self.addEventListener('backgroundfetchsuccess', event => {
event.waitUntil(async () => {
const cache = await caches.open('songs');
const songRecords = await event.registration.matchAll();
const promises = songRecords.map(async songRecord => {
const response = await songRecord.responseReady;
await cache.put(songRecord.request, response);
});
await Promise.all(promises);
event.updateUI({ title: 'Songs heruntergeladen.' });
});
});
Zugriff auf die Einträge erhalten Entwickler über die Eigenschaft registration. Die Oberfläche lässt sich nach Abschluss der Aktion über die Methode updateUI() auf Wunsch noch aktualisieren.
Die Background Fetch API wurde 2018 in Chromium implementiert [3]. Seit Google Chrome 74 ist sie generell verfügbar und auch in anderen Chromium-basierten Browsern wie Microsoft Edge anzutreffen. Von Mozilla Firefox und Apple Safari wird sie derzeit nicht implementiert. Unter backgroundfetch.com [4] kann sie unter Chromium-basierten Browsern auf dem Desktop oder Android interaktiv ausprobiert werden.
Wie die Background Sync API unterstützt Background Fetch nur einen einmaligen Datenaustausch. Nachrichtenanwendungen könnten hingegen regelmäßig im Hintergrund ihre Inhalte aktualisieren wollen, um dem Anwender direkt beim Öffnen eine aktuelle Auswahl von Artikeln präsentieren zu können. Diese Funktionalität möchte die Periodic Background Sync API ins Web bringen. Mehr dazu im nächsten Teil dieser Serie.
URL dieses Artikels:https://www.heise.de/-4681556
Links in diesem Artikel:[1] https://www.heise.de/developer/artikel/Hintergrund-Synchronisation-fuer-PWAs-Background-Sync-API-Teil-1-4676538.html[2] https://wicg.github.io/background-fetch/[3] https://developers.google.com/web/updates/2018/12/background-fetch[4] https://backgroundfetch.com
Copyright © 2020 Heise Medien
In dieser Reihe geht es um die Möglichkeit, im Hintergrund Daten zwischen einer Progressive Web App und dem Anwendungsserver auszutauschen – auch dann, wenn die Anwendung gar nicht geöffnet ist. Den Anfang macht die Web Background Synchronization API, die in auf Chromium basierenden Browsern schon seit 2016 funktioniert.
Progressive Web Apps laufen dank dem Service Worker und der IndexedDB offline: Im Cache des Service Worker können die Quelldateien der Anwendung offline gehalten werden, in der lokalen Clientdatenbank die strukturierten Anwenderdaten. Die Background Sync API [1] möchte Progressive Web Apps nun um die Funktionalität ausstatten, Daten auch im Hintergrund mit dem Anwendungsserver auszutauschen. Das Verhalten ist von nativen Anwendungen wie WhatsApp bekannt: Anwender können eine Nachricht verfassen, absenden und das Smartphone wieder wegpacken. Besteht eine Internetverbindung, wird die Nachricht direkt verschickt. Andernfalls wird sie im Hintergrund übermittelt, sobald wieder eine Verbindung zur Verfügung steht. Die App muss dafür nicht noch einmal geöffnet, das Smartphone nicht noch einmal aus der Hosentasche gekramt werden.
Bei der Background Sync API handelt es sich um eine Erweiterung der Service-Worker-Schnittstellen [2], eine der technischen Grundlagen von Progressive Web Apps. Ein Service Worker ist ein Stück JavaScript, das von der Website registriert wird. Das Skript kann anschließend losgelöst von der ursprünglichen Website laufen – also auch dann, wenn die Website gar nicht geöffnet ist. Genau diese Eigenschaft macht man sich bei der Background Sync API zunutze.
Da nicht jeder Browser mit Unterstützung für Service Worker auch die Web Background Sync API unterstützt, müssen Entwickler vor der Verwendung der Schnittstelle sowohl die Existenz der Service-Worker-API als auch die des SyncManager-Interfaces prüfen. Ist es vorhanden, lässt sich innerhalb der Webanwendung über die Service-Worker-Registrierung auf die Instanz des SyncManagers zugreifen. Hier können Synchronisierungsereignisse mit einem bestimmten Bezeichner (Tag) registriert werden. Im Falle des Messenger-Beispiels würde die register()-Methode des SyncManagers nach jeder abgeschickten Nachricht aufgerufen werden:
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('./sw.js');
navigator.serviceWorker.ready.then(registration => {
if ('SyncManager' in window) {
registration.sync.register('messages');
}
});
}
Aufseiten des Service-Worker-Skripts implementiert man einen Ereignis-Handler für das von der Background Sync API definierte sync-Ereignis. Bei der Ereignisregistrierung ist übrigens keine Prüfung auf die Existenz der API erforderlich, das Ereignis wird in Browsern ohne Unterstützung für die Web Background Sync API schlichtweg nicht aufgerufen. Bei bestehender Internetverbindung wird der Ereignis-Handler direkt aufgerufen. Andernfalls wird das Auslösen des Ereignisses solange verzögert, bis der Webbrowser der Ansicht ist, dass wieder eine Verbindung besteht. Mit absoluter Sicherheit lässt sich das aber nie sagen: Trotz hervorragender WiFi-Verbindung muss nicht zwingend eine Verbindung zum Internet bestehen (z.B. Drucker-WLANs). Und trotz EDGE-Empfang müssen Pakete nicht zwingend ihr Ziel finden. Ein Restrisiko, dass die Synchronisation dennoch nicht stattfinden kann, bleibt also.
Sollte beim Durchführen der Synchronisationslogik ein Fehler auftreten, kann der Webbrowser den Ereignis-Handler noch mehrmals aufrufen. Beim letzten Versuch ist die Eigenschaft lastChance in den Ereignisargumenten auf true gesetzt. Auf ihnen ist in der Eigenschaft tag der Bezeichner aus der Webanwendung zu finden. Anhand dessen ließen sich unterschiedliche Synchronisierungsabläufe wählen.
self.addEventListener('sync', event => {
if (event.tag == 'messages') {
event.waitUntil(syncMessages());
}
});
Sowohl der Service Worker als auch die Website teilen sich Zugriff auf dieselbe IndexedDB-Instanz. Die Webanwendung kann hochzuladende Inhalte in der Datenbank hinterlegen. Von dort kann der Service Worker diese dann mit dem Backend austauschen und neue oder geänderte Inhalte auf dem Rückweg in der Datenbank hinterlegen.
Da bei jeder Netzabfrage die IP-Adresse übermittelt wird, könnten Entwickler auf diese Art ein begrenztes Bewegungsprofil der Anwender erstellen. Da weder zur Installation des Service Worker noch zur Nutzung der Background Sync API eine vorherige Berechtigungsabfrage geschieht, haben Anwender keine Möglichkeit, diesem entgegenzuwirken. Auch gibt es bei der Schnittstelle keinen visuellen Indikator, dass eine PWA gerade Ereignisse im Hintergrund ausführt.
Derzeit wird die Web Background Sync API lediglich von Google Chrome und darauf basierenden Browsern wie Opera oder Microsoft Edge unterstützt. Es gilt als unwahrscheinlich, dass Apple die Schnittstelle nutzen wird. Auch in Mozilla Firefox wurde die Implementierung der Schnittstelle pausiert. Deswegen und zur Unterstützung älterer Browser müssen Entwickler immer noch einen zweiten Weg innerhalb der Webanwendung [3] implementieren, über den sich die Daten mit dem Anwendungsserver austauschen lassen. Dafür muss die Anwendung dann aber geöffnet sein.
Mit der Background Fetch API und der Periodic Sync API stehen glücklicherweise Alternativen zur Verfügung, die sich möglicherweise ihren Weg in weitere Browser bahnen könnten. Diese stelle ich in den nächsten beiden Teilen dieser Serie vor.
URL dieses Artikels:https://www.heise.de/-4676538
Links in diesem Artikel:[1] https://wicg.github.io/BackgroundSync/spec/[2] https://www.heise.de/developer/artikel/Progressive-Web-Apps-Teil-2-Die-Macht-des-Service-Worker-3740464.html[3] https://developers.google.com/web/updates/2015/12/background-sync#progressive_enhancement
Copyright © 2020 Heise Medien
In dieser Reihe geht es um die Möglichkeit, im Hintergrund Daten zwischen einer Progressive Web App und dem Anwendungsserver auszutauschen – auch dann, wenn die Anwendung gar nicht geöffnet ist. Den Anfang macht die Web Background Synchronization API, die in auf Chromium basierenden Browsern schon seit 2016 funktioniert.
Progressive Web Apps laufen dank dem Service Worker und der IndexedDB offline: Im Cache des Service Worker können die Quelldateien der Anwendung offline gehalten werden, in der lokalen Clientdatenbank die strukturierten Anwenderdaten. Die Background Sync API [1] möchte Progressive Web Apps nun um die Funktionalität ausstatten, Daten auch im Hintergrund mit dem Anwendungsserver auszutauschen. Das Verhalten ist von nativen Anwendungen wie WhatsApp bekannt: Anwender können eine Nachricht verfassen, absenden und das Smartphone wieder wegpacken. Besteht eine Internetverbindung, wird die Nachricht direkt verschickt. Andernfalls wird sie im Hintergrund übermittelt, sobald wieder eine Verbindung zur Verfügung steht. Die App muss dafür nicht noch einmal geöffnet, das Smartphone nicht noch einmal aus der Hosentasche gekramt werden.
Bei der Background Sync API handelt es sich um eine Erweiterung der Service-Worker-Schnittstellen [2], eine der technischen Grundlagen von Progressive Web Apps. Ein Service Worker ist ein Stück JavaScript, das von der Website registriert wird. Das Skript kann anschließend losgelöst von der ursprünglichen Website laufen – also auch dann, wenn die Website gar nicht geöffnet ist. Genau diese Eigenschaft macht man sich bei der Background Sync API zunutze.
Da nicht jeder Browser mit Unterstützung für Service Worker auch die Web Background Sync API unterstützt, müssen Entwickler vor der Verwendung der Schnittstelle sowohl die Existenz der Service-Worker-API als auch die des SyncManager-Interfaces prüfen. Ist es vorhanden, lässt sich innerhalb der Webanwendung über die Service-Worker-Registrierung auf die Instanz des SyncManagers zugreifen. Hier können Synchronisierungsereignisse mit einem bestimmten Bezeichner (Tag) registriert werden. Im Falle des Messenger-Beispiels würde die register()-Methode des SyncManagers nach jeder abgeschickten Nachricht aufgerufen werden:
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('./sw.js');
navigator.serviceWorker.ready.then(registration => {
if ('SyncManager' in window) {
registration.sync.register('messages');
}
});
}
Aufseiten des Service-Worker-Skripts implementiert man einen Ereignis-Handler für das von der Background Sync API definierte sync-Ereignis. Bei der Ereignisregistrierung ist übrigens keine Prüfung auf die Existenz der API erforderlich, das Ereignis wird in Browsern ohne Unterstützung für die Web Background Sync API schlichtweg nicht aufgerufen. Bei bestehender Internetverbindung wird der Ereignis-Handler direkt aufgerufen. Andernfalls wird das Auslösen des Ereignisses solange verzögert, bis der Webbrowser der Ansicht ist, dass wieder eine Verbindung besteht. Mit absoluter Sicherheit lässt sich das aber nie sagen: Trotz hervorragender WiFi-Verbindung muss nicht zwingend eine Verbindung zum Internet bestehen (z.B. Drucker-WLANs). Und trotz EDGE-Empfang müssen Pakete nicht zwingend ihr Ziel finden. Ein Restrisiko, dass die Synchronisation dennoch nicht stattfinden kann, bleibt also.
Sollte beim Durchführen der Synchronisationslogik ein Fehler auftreten, kann der Webbrowser den Ereignis-Handler noch mehrmals aufrufen. Beim letzten Versuch ist die Eigenschaft lastChance in den Ereignisargumenten auf true gesetzt. Auf ihnen ist in der Eigenschaft tag der Bezeichner aus der Webanwendung zu finden. Anhand dessen ließen sich unterschiedliche Synchronisierungsabläufe wählen.
self.addEventListener('sync', event => {
if (event.tag == 'messages') {
event.waitUntil(syncMessages());
}
});
Sowohl der Service Worker als auch die Website teilen sich Zugriff auf dieselbe IndexedDB-Instanz. Die Webanwendung kann hochzuladende Inhalte in der Datenbank hinterlegen. Von dort kann der Service Worker diese dann mit dem Backend austauschen und neue oder geänderte Inhalte auf dem Rückweg in der Datenbank hinterlegen.
Da bei jeder Netzabfrage die IP-Adresse übermittelt wird, könnten Entwickler auf diese Art ein begrenztes Bewegungsprofil der Anwender erstellen. Da weder zur Installation des Service Worker noch zur Nutzung der Background Sync API eine vorherige Berechtigungsabfrage geschieht, haben Anwender keine Möglichkeit, diesem entgegenzuwirken. Auch gibt es bei der Schnittstelle keinen visuellen Indikator, dass eine PWA gerade Ereignisse im Hintergrund ausführt.
Derzeit wird die Web Background Sync API lediglich von Google Chrome und darauf basierenden Browsern wie Opera oder Microsoft Edge unterstützt. Es gilt als unwahrscheinlich, dass Apple die Schnittstelle nutzen wird. Auch in Mozilla Firefox wurde die Implementierung der Schnittstelle pausiert. Deswegen und zur Unterstützung älterer Browser müssen Entwickler immer noch einen zweiten Weg innerhalb der Webanwendung [3] implementieren, über den sich die Daten mit dem Anwendungsserver austauschen lassen. Dafür muss die Anwendung dann aber geöffnet sein.
Mit der Background Fetch API und der Periodic Sync API stehen glücklicherweise Alternativen zur Verfügung, die sich möglicherweise ihren Weg in weitere Browser bahnen könnten. Diese stelle ich in den nächsten beiden Teilen dieser Serie vor.
URL dieses Artikels:https://www.heise.de/-4676538
Links in diesem Artikel:[1] https://wicg.github.io/BackgroundSync/spec/[2] https://www.heise.de/developer/artikel/Progressive-Web-Apps-Teil-2-Die-Macht-des-Service-Worker-3740464.html[3] https://developers.google.com/web/updates/2015/12/background-sync#progressive_enhancement
Copyright © 2020 Heise Medien
Metaphern für Softwareentwicklung gibt es viele. Sie als Spiel zu begreifen, scheint zunächst respektlos. Wenn man tiefer gräbt, ergeben sich aber zahlreiche Parallelen.
Der Begriff "Spiel" steht erst mal für Spaß. Softwareentwicklung ist aber kein Spaß – es geht meistens um ernsthafte Geschäftsziele und oft hohe Budgets. So etwas ist kein Spiel.
Die Spieltheorie [1] ist allerdings eine wissenschaftlich anerkannte Theorie, die sich mit Strategien für Spiele und andere Entscheidungssituationen beschäftigt. Diese Theorie hat viele Anwendungen. Auch Kriege oder Vorgehen in der Wirtschaft werden spieltheoretisch untersucht und so bessere Strategien entwickelt.
Spiele scheinen außerdem trivial zu sein. Schließlich spielen schon Kinder. Aber auch hier liegen bei näherer Betrachtung die Dinge anders. Einige Profis widmen ihr ganzes Leben Spielen wie Schach oder dem asiatischen Spiel Go [2]. Es gibt viel mehr denkbare Go-Stellungen (ca. 10^170) als Atome im Universum (ca. 10^80). Das ist alles andere als trivial.
Softwareentwicklungsprojekte als Spiele zu betrachten, führt zu einigen Erkenntnissen:
Spiele haben Gewinnbedingungen. Jede Aktivität sollte auf die Gewinnbedingungen einzahlen und man muss kollaborieren. Das hilft auch bei Softwareentwicklung.
Vielen Dank an meine Kolleginnen und Kollegen Hanna Prinz, Tobias Erdle und Sonja Scheungrab für die Kommentare zu einer früheren Version des Artikels.
URL dieses Artikels:https://www.heise.de/-4659442
Links in diesem Artikel:[1] https://de.wikipedia.org/wiki/Spieltheorie[2] https://de.wikipedia.org/wiki/Go_(Spiel)[3] https://www.heise.de/developer/artikel/Ueber-die-optimale-Softwarearchitektur-3785166.html[4] https://de.wikipedia.org/wiki/Pandemie_(Spiel).
Copyright © 2020 Heise Medien
Progressive Web Apps lassen sich auf allen relevanten Plattformen installieren. In manchen Punkten hakt die Integration allerdings noch. So lassen sich aus dem Browser heraus installierte PWAs unter Windows nicht über die Systemsteuerung deinstallieren oder automatisch mit dem Betriebssystem starten. Hier bessert Microsoft nun nach.
Seitdem Microsoft die eigene Entwicklung seiner eigenen Browser-Engine zugunsten von Chromium aufgegeben hat, [1] beteiligt sich das Unternehmen an der Entwicklung des quelloffenen Unterbaus der Webbrowser Google Chrome, Samsung Internet, Brave oder Microsoft Edge. Die Chromium-Kontributoren Google, Microsoft und Intel haben sich darüber hinaus zur Initiative Project Fugu [2] zusammengeschlossen, die Progressive Web Apps leistungsfähiger machen möchte. Als Teil dieser Initiative kümmert sich Microsoft um die Verbesserung der PWA-Integration ins Betriebssystem.
Auf vielen Desktop-Betriebssystemen können Benutzer ihre Anwendungen mit dem Start des Betriebssystems beziehungsweise der Benutzersession direkt ausführen lassen. Unter Windows kennt man diese Funktionalität unter dem Namen Autostart, unter macOS nennt man diese Programme auch Login Items. PWAs sollen bei der Installation vorschlagen können, sich automatisch mit dem System starten zu lassen [3]. Dazu muss die Funktionalität im Web App Manifest [4] angefordert werden. Außerdem ist ein Kontrollkästchen geplant, das Anwender aktivieren müssen, wenn die App in den Autostart gelegt werden soll.

Bei der Installation einer PWA aus dem Browser wird auf Desktop-Systemen eine Verknüpfung in der Programmliste des Betriebssystems hinterlegt. Unter Windows erhalten Anwender im Startmenü per Rechtsklick eine Option zum Deinstallieren von Anwendungen, die zur Liste installierter Programme in der Einstellungen-App führt. In dieser Liste sind PWAs aber noch nicht eingetragen, insofern läuft die Aktion ins Leere. Die Deinstallation funktioniert aktuell etwa nur über das Drei-Punkte-Menü des PWA-Fensters. Microsoft kümmert sich darum [5], dass diese Anwendungen in Zukunft auch aus der Einstellungen-App oder der Systemsteuerung entfernt werden können.
Das Web kann schon heute das Schließen einer Website verhindern, wenn noch offene Aktionen (zum Beispiel ein nicht abgeschicktes Formular oder nicht synchronisierte Änderungen) ausstehen. Die Beschriftung des Dialogs verrät aber nicht, was genau noch offen ist. Produktivitätsanwendungen erlauben Anwendern beim Schließen außerdem oftmals auch eine komplexere Auswahl, etwa das Speichern eines geöffneten Dokuments, das bewusste Verwerfen der Änderungen oder das Abbrechen des Schließvorgangs. Für installierte PWAs möchte Microsoft diese Funktionalität ebenfalls nachreichen [6].

Visual Studio macht es, Spotify macht es, Microsoft Teams macht es auch: Diese Anwendungen erweitern die Titelzeile des Fensters um eigene Steuerelemente, um den verfügbaren Platz effizienter zu nutzen. Auch diese Funktionalität soll installierten Progressive Web Apps bald offenstehen [7]. Die PWA darf sich dabei bis in die Titelzeile erweitern. Nur die Fenstersteuerelemente des Betriebssystems und des Webbrowsers legen sich dann noch über die Anwendung.

Die hier gezeigten Vorschläge verbessern die Benutzererfahrung von Progressive Web Apps besonders auf Desktop-Systemen. An allen Vorschlägen wird derzeit aktiv gearbeitet, ein Zieldatum gibt es derzeit allerdings noch nicht. Die Arbeit von Microsoft zeigt, dass die Lücke zwischen nativen Anwendungen und Progressive Web Apps kontinuierlich schmilzt und Entwickler auch weiterhin einen immer größer werdenden Funktionsumfang erwarten dürfen.
URL dieses Artikels:https://www.heise.de/-4653366
Links in diesem Artikel:[1] https://www.heise.de/developer/artikel/Analyse-Da-waren-s-nur-noch-drei-4244599.html[2] https://www.heise.de/developer/artikel/Google-Projekt-Fugu-Die-Macht-des-Kugelfisches-4255636.html[3] https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/master/RunOnLogin/Explainer.md[4] https://www.heise.de/developer/artikel/Progressive-Web-Apps-Teil-3-Wie-die-Web-App-zur-App-App-wird-3464603.html[5] https://bugs.chromium.org/p/chromium/issues/detail?id=957043[6] https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/master/CustomDialogOnClose/explainer.md[7] https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/master/TitleBarCustomization/explainer.md
Copyright © 2020 Heise Medien
Progressive Web Apps sind in aller Munde. Mit der ersten PWAConf will die Community nun alle PWA-Beteiligten in London zusammenbringen. Auf der Bühne stehen Vertreter der Browserhersteller, Mitglieder der Standardisierungsorganisationen und Webentwickler aus der Community.
Die erste Ausgabe der PWAConf findet am Sonntag, den 19. April 2020, im Victoria Park Plaza Hotel in London statt. An einem ganzen Tag voller technischer Sessions wird zusammengefasst, was das Web als Anwendungsplattform schon heute leisten kann, welche Best Practices es zur Entwicklung nativ erscheinender Webanwendungen gibt und welche zukünftigen Features PWA-Entwickler erwarten. Die PWAConf soll Browserhersteller, Mitglieder der Standardisierungsgremien, Webentwickler und weitere PWA-Enthusiasten in den gemeinsamen Austausch bringen.
Das Programm wird von der PWA-Community zusammengestellt, vertreten durch Majid Hajian, Christian Liebel (Thinktecture), Laura Morinigo (Samsung Internet) und Maxim Salnikov (Microsoft). Gastgeber der Veranstaltung ist die International JavaScript Conference, die ihre Infrastruktur freundlicherweise für die Community-Konferenz bereitstellt. Die iJS schließt sich vom 20. bis 22. April 2020 im selben Hotel an. Tickets sind für 89 GBP zzgl. VAT erhältlich. Zehn kostenfreie Diversity-Tickets werden an Teilnehmer unterrepräsentierter Gruppen in der IT vergeben. Weitere Informationen sind unter PWAConf.io [1] zu finden.
URL dieses Artikels:https://www.heise.de/-4653876
Links in diesem Artikel:[1] https://pwaconf.io
Copyright © 2020 Heise Medien
Cross-Platform-Entwickler, die auf Webtechniken setzen, haben die Qual der Wahl: Verpackt man Web-Apps auf altbewährte Weise mit Apache Cordova und GitHub Electron? Oder greift man lieber auf Progressive Web Apps zurück, bei denen das Leben der Anwendung im Browser beginnt?
Optisch unterscheiden sich beide Methoden kaum: Am Ende läuft die eigene Web-App auf Desktopsystemen in einem eigenen Fenster, auf Mobilgeräten vollflächig – wie alle anderen Apps auch. Unterschiede gibt es jedoch in der Art der Verteilung und im Funktionsumfang.

Bei Cordova und Electron wird eine Webanwendung in einem nativen Anwendungsrahmen verpackt. Über ihn lassen sich sämtliche Funktionen und APIs aufrufen, die die jeweilige Plattform zur Verfügung stellt. Insgesamt stehen diese Anwendungen ihren nativen Gegenstücken in nichts nach. Daher können sie auch über alle Vertriebswege verteilt werden, typischerweise App-Stores im mobilen Umfeld oder als Executable für den Desktop.
Problematisch bei diesem Ansatz ist aber, dass nicht nur die Anwendung selbst zu warten ist, sondern auch der Container. Bei Electron sind neben der eigentlichen App darüber hinaus noch Node.js und Chromium Teil des Anwendungsbündels, die regelmäßig aktualisiert werden sollten. Im Falle von Cordova ist festzustellen, dass die bereitgestellten Plug-ins, die Zugriff auf native Funktionen erlauben, zunehmend altern und die Weiterentwicklung oftmals an einer überschaubaren Anzahl an Community-Mitgliedern hängt.
Progressive Web Apps kommen komplett ohne diesen Wrapper aus. Stattdessen beginnt das Leben der Anwendung im Browser, von dort kann sie auf dem jeweiligen Gerät installiert werden. Somit fallen auch keine Kosten für App-Stores an, Verkäufe oder Abogebühren sind ebenfalls nicht mehr zwingend mit dem Plattformanbieter zu teilen. Das heißt aber nicht, dass sich diese Anwendungen nicht später doch wieder in einen Store einstellen lassen. Der Microsoft Store und Google Play nehmen so auch Progressive Web Apps auf.
Allerdings können Progressive Web Apps nicht auf sämtliche nativen Schnittstellen zugreifen, sondern nur auf diejenigen, für die es auch eine Webschnittstelle gibt. Das Web hat in den vergangenen Jahren viele APIs mit nativer Power erhalten, etwa Browserdatenbanken, Zugriff auf Geolocation, Mikrofon und Kamera, doch es bleibt noch ein gewisser Versatz zum kompletten nativen Funktionsumfang. Dank Initiativen wie Project Fugu [1] schwindet dieser Abstand aber zusehends.
Webanwendungen sollten zunächst immer mit dem Ziel entwickelt werden, eine Progressive Web App zu sein. Niemand hindert Entwickler später daran, diese doch noch in einem nativen Anwendungscontainer zu verpacken. Wer zu sehr auf native APIs baut, kann seine Anwendung umgekehrt nicht so einfach als PWA bereitstellen. Nur dann, wenn Entwickler auf eine kritische Funktion stoßen, für die es keine Webschnittstelle gibt oder zwingend ein Executable oder eine Präsenz im Apple App Store gebraucht wird, sollten sie ergänzend oder alternativ auf Wrapper-Ansätze wie Cordova und Electron zurückgreifen.
Ausführlich beleuchten Christian Liebel und Thorsten Hans von Thinktecture dieses Thema am 27. Februar 2020 im Rahmen der BASTA! Spring in Frankfurt [2].
URL dieses Artikels:https://www.heise.de/-4634262
Links in diesem Artikel:[1] https://www.heise.de/developer/artikel/Google-Projekt-Fugu-Die-Macht-des-Kugelfisches-4255636.html[2] https://basta.net/web-development/electron-cordova-pwa-was-wann-wie-und-warum/
Copyright © 2020 Heise Medien