{"id":12376,"date":"2021-02-24T16:32:55","date_gmt":"2021-02-24T15:32:55","guid":{"rendered":"https:\/\/blog.mi.hdm-stuttgart.de\/?p=12376"},"modified":"2023-06-18T18:07:01","modified_gmt":"2023-06-18T16:07:01","slug":"serviceworker-offline-first","status":"publish","type":"post","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2021\/02\/24\/serviceworker-offline-first\/","title":{"rendered":"ServiceWorker \u2013 Offline First"},"content":{"rendered":"\n<p>In der Vorlesung Rich Media haben wir uns viel mit Performance in Web Anwendungen besch\u00e4ftigt. Dabei habe ich mich mit ServiceWorkern in Bezug auf Offlinenutzung, Funktionalit\u00e4t und Performance besch\u00e4ftigt. Zuerst habe ich mich damit befasst, wie ein ServiceWorker funktioniert. Danach habe ich geschaut, wie sich die Nutzung eines ServiceWorker und des Ansatzes Offline First auf die Performance auswirkt.<\/p>\n\n\n\n<!--more-->\n\n\n\n<h2 class=\"wp-block-heading\">Was sind ServiceWorker?<\/h2>\n\n\n\n<p>ServiceWorker bieten einige hilfreiche Funktionalit\u00e4ten. Mit ihrer Hilfe k\u00f6nnen zum Beispiel Webseiten v\u00f6llig Offline bedienbar gemacht werden. Zus\u00e4tzlich kann man das Caching komplett selbst in die Hand nehmen und konfigurieren, wie man es selbst f\u00fcr richtig h\u00e4lt. Ein ServiceWorker l\u00e4uft im Hintergrund der Webseite, daher ist es m\u00f6glich im Hintergrund Daten zu synchronisieren und Push Notifications zu versenden. Durch die Synchronisation im Hintergrund kann man auch w\u00e4hrend einer Offline Session http Requests abspeichern und absenden, sobald man wieder Online ist.<\/p>\n\n\n\n<p>Technisch gesehen ist ein ServiceWorker ein ganz einfacher programmierbarer Netzwerk Proxy im Browser. Er basiert auf den Event-getriebenen Web Workern und l\u00e4uft in einem separaten Thread des Browsers. Sobald ein ServiceWorker mal nicht gebraucht wird, wird er beendet. Wenn er dann wieder ben\u00f6tigt wird, wird er wieder gestartet. Dadurch werden keine Ressourcen dauerhaft verbraucht. Er kann auch laufen, wenn die zugeh\u00f6rige Webseite nicht ge\u00f6ffnet ist, z.B. um Push Notifications zu senden.<br>Da man mit dem ServiceWorker alle Requests abf\u00e4ngt und ab\u00e4ndern kann, wird aus Sicherheitsgr\u00fcnden nur https erlaubt. W\u00e4hrend der Entwicklung unter localhost kann jedoch trotzdem http genutzt werden. Ein ServiceWorker kann nicht auf den DOM zugreifen, daher wird \u00fcber eine Schnittstelle kommuniziert. Genauer gesagt \u00fcber EventListener und die postMessage Schnittstelle. Diese Eigenschaften sind durch die Basis des Web Workers gegeben.<\/p>\n\n\n\n<p>Haupts\u00e4chlich genutzt werden ServiceWorker in Progressive Web Apps, wobei sie auch auf vielen anderen Webseiten zum Einsatz kommen. Progressive Web Apps werden jedoch bereits in einem anderen Blogeintrag innerhalb dieser Vorlesung beschrieben, daher werde ich hier nicht weiter darauf eingehen.<\/p>\n\n\n\n<p>Unterst\u00fctz werden ServiceWorker mittlerweile von den meisten Browsern. Selbst die meisten mobilen Browser haben keine Probleme damit. Progressive Web Apps mit einem ServiceWorker kommen sehr nah an eine App ran, die M\u00f6glichkeit eine App damit abzul\u00f6sen liegt also nicht so weit entfernt.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">LifeCycle Events<\/h2>\n\n\n\n<p>Hier wird das ganze etwas Technischer. Im Leben eines ServiceWorker gibt es &nbsp;drei wichtige Lifecycle Events: register, install und activate. Durch diese Events muss der ServiceWorker gehen, bevor er genutzt werden kann.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">register<\/h3>\n\n\n\n<p>Damit der Browser von dem ServiceWorker erf\u00e4hrt, muss er beim ihm registriert werden. Dies passiert innerhalb des Scripts der Webseite.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-1.png\"><img loading=\"lazy\" decoding=\"async\" width=\"812\" height=\"350\" data-attachment-id=\"12377\" data-permalink=\"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2021\/02\/24\/serviceworker-offline-first\/picture-1\/\" data-orig-file=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-1.png\" data-orig-size=\"812,350\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"Picture-1\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-1.png\" src=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-1.png\" alt=\"\" class=\"wp-image-12377\" srcset=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-1.png 812w, https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-1-300x129.png 300w, https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-1-768x331.png 768w\" sizes=\"auto, (max-width: 812px) 100vw, 812px\" \/><\/a><\/figure>\n\n\n\n<p>In Zeile 1 wird erst einmal \u00fcberpr\u00fcft, ob der ServiceWorker \u00fcberhaupt vom Browser unterst\u00fctzt wird. Falls nicht, kann die Webseite benutzt werden wie immer. &nbsp;Die if-Bedingung in Zeile 2 wartet auf das \u201eload\u201c Event. Damit erreicht man, dass der ServiceWorker erst verz\u00f6gert startet. Der ServiceWorker wird so erst nach dem vollst\u00e4ndigen Laden der Webseite initialisiert und dem Benutzer entstehen so keine unn\u00f6tigen Ladezeiten. Wenn man den ServiceWorker jedoch von Anfang an ben\u00f6tigt, kann man dies aber auch weglassen.<\/p>\n\n\n\n<p>Ab Zeile 4 wird der ServiceWorker registriert. Dabei kann, wie in Zeile 6 beschrieben der Scope definiert werden. In diesem Fall wird der ServiceWorker alle Requests mit der URL \u201e\/app\u201c betrachten. Dazu z\u00e4hlen \u201e\/app\u201c, \u201eapp\/test\u201c oder \u201e\/app\/test\/test\u201c. Eine Ebene weiter oben wird jedoch nicht beachtet, z.B. \u201e\/\u201c oder \u201e\/test\u201c. Wenn die Scope Variable weggelassen wird, ist der Ordner in dem der ServiceWorker liegt der entsprechende Scope.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Install<\/h3>\n\n\n\n<p>Nachdem der ServiceWorker im Browser registriert wurde, muss er installiert werden. In diesem Schritt k\u00f6nnen ben\u00f6tigte Caches bereits aufgebaut werden. Dies kann auch mal etwas mehr sein, da hier auch gr\u00f6\u00dfere Mengen an statischen Dateien runtergeladen werden k\u00f6nnen. Hier k\u00f6nnten eventuell gr\u00f6\u00dfere Ladezeiten entstehen, wenn man nicht auf das vollst\u00e4ndige warten Laden der Webseite warten w\u00fcrde.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-2.png\"><img loading=\"lazy\" decoding=\"async\" width=\"650\" height=\"472\" data-attachment-id=\"12378\" data-permalink=\"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2021\/02\/24\/serviceworker-offline-first\/picture-2\/\" data-orig-file=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-2.png\" data-orig-size=\"650,472\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"Picture-2\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-2.png\" src=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-2.png\" alt=\"\" class=\"wp-image-12378\" srcset=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-2.png 650w, https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-2-300x218.png 300w\" sizes=\"auto, (max-width: 650px) 100vw, 650px\" \/><\/a><\/figure>\n\n\n\n<p>Damit der erstellte Cache klar identifizierbar ist, wird zuerst ein Name vergeben. Dieser kann sich in sp\u00e4teren Iterationen des ServiceWorkers \u00e4ndern, um den Cache zu erneuern. In der zweiten Zeile werden Ressourcen angegeben, welche im sp\u00e4teren Verlauf heruntergeladen werden sollen. Dies sind meistens statische Dateien, welche man immer gecached bzw. Offline verf\u00fcgbar haben m\u00f6chte. In Zeile 8 wird auf das Durchf\u00fchren aller Installationsschritte gewartet. In diesem Fall gibt es nur einen Schritt, das Runterladen der Ressourcen. Es wird der vorher definierte Cache ge\u00f6ffnet und dann alle definierten Ressourcen diesem Cache hinzugef\u00fcgt. Dadurch sind sie sp\u00e4ter im laufenden Betrieb verf\u00fcgbar. Falls auch nur einer der durchgef\u00fchrten Installationsschritte fehlschl\u00e4gt, wird der ServiceWorker verworfen und es wird sp\u00e4ter eine erneute Installation gestartet. Wenn also eine Ressource nicht verf\u00fcgbar ist, wird die Installation nicht funktionieren.<\/p>\n\n\n\n<p>Sobald alle Installationsschritte fertiggestellt wurden ist der Worker bereit, um genutzt zu werden. Auf das Aktivieren muss er eventuell trotzdem noch warten. Beim ersten \u00d6ffnen der Webseite \u00fcbernimmt er die Webseite einfach, das Warten ist also nicht notwendig. Wenn die Webseite jedoch bereits von einem ServiceWorker kontrolliert wurde, muss er warten, bis alle kontrollierten Webseiten geschlossen wurden. Dies kann auch mal etwas l\u00e4nger dauern. Um dieses Warten zu \u00fcberspringen, kann self.skipWaiting() aufgerufen werden, wie in Zeile 14. Damit wird der alte ServiceWorker entfernt und durch den neuen ersetzt. Man sollte damit aber vorsichtig sein, hier k\u00f6nnten Daten verloren gehen. Wenn man mit sensiblen Daten arbeitet, ist es das vermutlich nicht wert.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">activate<\/h3>\n\n\n\n<p>Sobald der ServiceWorker die Kontrolle \u00fcber die Webseite \u00fcbernommen hat, wird das activate Event ausgel\u00f6st. Hier ist der richtige Zeitpunkt, um alle veralteten Caches aufzur\u00e4umen. Im Installationsschritt wird der Cache eventuell noch von einem vorherigen ServiceWorker genutzt. Im activate Schritt kann man jedoch davon ausgehen, dass kein \u00e4lterer ServiceWorker auf die Caches zugreifen wird.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-3.png\"><img loading=\"lazy\" decoding=\"async\" width=\"800\" height=\"472\" data-attachment-id=\"12379\" data-permalink=\"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2021\/02\/24\/serviceworker-offline-first\/picture-3\/\" data-orig-file=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-3.png\" data-orig-size=\"800,472\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"Picture-3\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-3.png\" src=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-3.png\" alt=\"\" class=\"wp-image-12379\" srcset=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-3.png 800w, https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-3-300x177.png 300w, https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-3-768x453.png 768w\" sizes=\"auto, (max-width: 800px) 100vw, 800px\" \/><\/a><\/figure>\n\n\n\n<p>Im Beispiel ist wieder der Cache Name relevant. In diesem Beispiel sollten im Installationsschritt alle statischen Dateien im Cache \u201ev5\u201c abgespeichert werden, da hier alle anderen Caches gel\u00f6scht werden. Wenn sich also der Name des Caches \u00e4ndert, werden alle alten Versionen gel\u00f6scht.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">LifeCycle \u00dcberblick<\/h3>\n\n\n\n<p>Nochmal ein kleiner \u00dcberblick \u00fcber alle Events:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-4.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"341\" data-attachment-id=\"12380\" data-permalink=\"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2021\/02\/24\/serviceworker-offline-first\/picture-4\/\" data-orig-file=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-4.png\" data-orig-size=\"1394,464\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"Picture-4\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-4-1024x341.png\" src=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-4-1024x341.png\" alt=\"\" class=\"wp-image-12380\" srcset=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-4-1024x341.png 1024w, https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-4-300x100.png 300w, https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-4-768x256.png 768w, https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-4.png 1394w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>Im register wird der ServiceWorker im Browser registriert. Dann wird das install Event ausgel\u00f6st. Hier werden alle ben\u00f6tigten Caches aufgebaut. Daraufhin wird gewartet, bis das activate Event ausgel\u00f6st werden kann. Dies passiert sobald die alte Version des ServiceWorkers die Webseite freigibt bzw. sofort, wenn dies die erste Version ist. Im activate Event k\u00f6nnen alte Caches aufger\u00e4umt werden. Nachdem dieses Event abgeschlossen wurde, ist der ServiceWorker einsatzbereit. Er wird jedoch beendet, bis er wieder ben\u00f6tigt wird.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">fetch<\/h2>\n\n\n\n<p>Nach den LifeCycle Events kommen wir nun zum vermutlich wichtigsten Teil des ServiceWorker, dem fetch Event. In diesem Event wird jeder http Request abgefangen. Hier k\u00f6nnen Caching und Offline Nutzung implementiert werden. Um das ganze m\u00f6glichst Verst\u00e4ndlich zu machen, werde ich in den n\u00e4chsten Beispielen das fetch Event immer erweitern.<\/p>\n\n\n\n<p>Der einfachste EventListener f\u00fcr das fetch Event ist der Folgende:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-5.png\"><img loading=\"lazy\" decoding=\"async\" width=\"682\" height=\"114\" data-attachment-id=\"12381\" data-permalink=\"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2021\/02\/24\/serviceworker-offline-first\/picture-5\/\" data-orig-file=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-5.png\" data-orig-size=\"682,114\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"Picture-5\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-5.png\" src=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-5.png\" alt=\"\" class=\"wp-image-12381\" srcset=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-5.png 682w, https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-5-300x50.png 300w\" sizes=\"auto, (max-width: 682px) 100vw, 682px\" \/><\/a><\/figure>\n\n\n\n<p>e ist das Event, und mit e.request kann man auf den entsprechenden Request zugreifen. In diesem Beispiel wird nichts mit dem Request gemacht. Er wird mit der Methode fetch() an das eigentliche Ziel weitergeleitet und die Antwort wird mit e.respondeWith() zur\u00fcckgegeben.<\/p>\n\n\n\n<p>Sobald es einen solchen fetch EventListener gibt, werden alle Request durch diesen gehen. Wenn diese Funktionalit\u00e4t des ServiceWorkers nicht ben\u00f6tigt wird, kann dieser Listener auch einfach weggelassen werden. Damit spart man sich den Zwischenschritt bei jedem Request.<\/p>\n\n\n\n<p>Der n\u00e4chste Schritt ist eine einfache Offline Funktionalit\u00e4t f\u00fcr alle gecachten Inhalte:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-6.png\"><img loading=\"lazy\" decoding=\"async\" width=\"592\" height=\"248\" data-attachment-id=\"12382\" data-permalink=\"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2021\/02\/24\/serviceworker-offline-first\/picture-6\/\" data-orig-file=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-6.png\" data-orig-size=\"592,248\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"Picture-6\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-6.png\" src=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-6.png\" alt=\"\" class=\"wp-image-12382\" srcset=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-6.png 592w, https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-6-300x126.png 300w\" sizes=\"auto, (max-width: 592px) 100vw, 592px\" \/><\/a><\/figure>\n\n\n\n<p>Jetzt wird immer, wenn ein Request \u00fcber das Netzwerk fehlschl\u00e4gt, nach einer passenden Antwort im Cache geschaut. Wenn diese vorhanden ist, wird sie zur\u00fcckgegeben. Falls dies nicht der Fall ist, wird die normale Fehlerseite durch den Browser angezeigt. Hier k\u00f6nnte man aber auch eine Standard Antwort f\u00fcr einen Fehler definieren, welche man immer bei einer fehlenden Netzwerkverbindung und fehlender Ressource im Cache zur\u00fcckgeben kann.&nbsp; Hier im Beispiel werden noch keine Requests gespart, da nur im Cache geschaut wird, wenn der eigentliche Netzwerkzugriff fehlgeschlagen ist. Au\u00dferdem werden nur Ressourcen im Cache vorhanden sein, welche bereits im Installationsschritt runtergeladen wurden.<\/p>\n\n\n\n<p>Im folgenden Beispiel wird der Zugriff auf den Cache vor den Netzwerkzugriff geschoben, damit man den Netzwerkzugriff auf die bereits gespeicherten Ressourcen spart. Falls aber ein Netzwerkzugriff get\u00e4tigt werden muss, wird die Antwort davon im Cache gespeichert. &nbsp;&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-7.png\"><img loading=\"lazy\" decoding=\"async\" width=\"780\" height=\"488\" data-attachment-id=\"12383\" data-permalink=\"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2021\/02\/24\/serviceworker-offline-first\/picture-7\/\" data-orig-file=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-7.png\" data-orig-size=\"780,488\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"Picture-7\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-7.png\" src=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-7.png\" alt=\"\" class=\"wp-image-12383\" srcset=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-7.png 780w, https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-7-300x188.png 300w, https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-7-768x480.png 768w\" sizes=\"auto, (max-width: 780px) 100vw, 780px\" \/><\/a><\/figure>\n\n\n\n<p>In Zeile 3 bis 6 wird geschaut, ob eine Antwort zu dem gegebenen Request vorhanden ist. Falls dies nicht der Fall ist, wird ab Zeile 7 der Netzwerkaufruf gemacht. Falls dieser erfolgreich war (Zeile 8), wird die Antwort zuerst kopiert (Zeile 10) und dann in den Cache geschrieben (Zeile 11). Am Ende wird die Antwort dann zur\u00fcckgegeben (Zeile 14). Damit wird dieser Request das n\u00e4chste Mal im Cache vorhanden sein und ein erneuter Netzwerkzugriff gespart. Der Cache baut sich so automatisch aus und wird mit jedem neuen Request gr\u00f6\u00dfer.<\/p>\n\n\n\n<p>Jetzt fehlt z.B. noch eine Strategie, um die Ressourcen nach einer gewissen Zeit ablaufen zu lassen. Da man vollst\u00e4ndigen Zugriff auf den Request hat, kann man jedoch auch selbst entscheiden, ob gewisse Ressourcen \u00fcberhaupt erst im Cache gespeichert werden sollten. An dieser Stelle werde ich jedoch keine weiteren Beispiele zeigen, da dies nur indirekt die Performance beeinflussen w\u00fcrde.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">sync<\/h2>\n\n\n\n<p>sync ist das n\u00e4chste Event auf der Tagesordnung. Dieses Event erm\u00f6glicht eine Synchronisierung von Daten im Hintergrund. Au\u00dferdem ist es m\u00f6glich, im Offlinemodus ein sync Event zu starten, welches dann durchgef\u00fchrt wird, sobald man wieder eine funktionierende Netzwerkverbindung hat.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-8.png\"><img loading=\"lazy\" decoding=\"async\" width=\"800\" height=\"152\" data-attachment-id=\"12386\" data-permalink=\"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2021\/02\/24\/serviceworker-offline-first\/picture-8\/\" data-orig-file=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-8.png\" data-orig-size=\"800,152\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"Picture-8\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-8.png\" src=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-8.png\" alt=\"\" class=\"wp-image-12386\" srcset=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-8.png 800w, https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-8-300x57.png 300w, https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-8-768x146.png 768w\" sizes=\"auto, (max-width: 800px) 100vw, 800px\" \/><\/a><\/figure>\n\n\n\n<p>Hier sieht man wie ein solches Event ausgel\u00f6st wird. In Zeile 2 wird zuerst eine Instanz des registrierten ServiceWorker geholt. In Zeile 3 l\u00f6st man dann ein sync Event mit dem Namen \u201eextendCache\u201c aus. Im ServiceWorker kommt dieses Event im sync EventListener an. Diese Synchronisation soll jetzt, wie der Name bereits verr\u00e4t den Cache erweitern.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-9.png\"><img loading=\"lazy\" decoding=\"async\" width=\"740\" height=\"346\" data-attachment-id=\"12387\" data-permalink=\"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2021\/02\/24\/serviceworker-offline-first\/picture-9\/\" data-orig-file=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-9.png\" data-orig-size=\"740,346\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"Picture-9\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-9.png\" src=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-9.png\" alt=\"\" class=\"wp-image-12387\" srcset=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-9.png 740w, https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/Picture-9-300x140.png 300w\" sizes=\"auto, (max-width: 740px) 100vw, 740px\" \/><\/a><\/figure>\n\n\n\n<p>Im EventListener wird zuerst der entsprechende sync mit einer if Anweisung gefiltert, in unserem Beispiel suchen wir nach dem sync mit dem Tag \u201eextendCache\u201c (Zeile 2). Dann wird der Cache ge\u00f6ffnet und die Ressource \u201eabout.html\u201c hinzugef\u00fcgt (Zeile 4-7). \u201eabout.html\u201c ist ab jetzt offline verf\u00fcgbar. Die Besonderheit dabei ist, dass dieses Event im Offlinemodus ausgel\u00f6st werden kann und ausgef\u00fchrt wird, sobald der Browser wieder online ist.<br>\u00dcber diesen Weg kann man sehr gut E-Mails oder Nachrichten versenden. Selbst wenn man zum aktuellen Zeitpunkt keine aktive Netzwerkverbindung hat, wird die Nachricht versendet, sobald der Browser wieder online ist.<\/p>\n\n\n\n<p>Der ServiceWorker hat zwar noch einige weitere Funktionen, ich habe aber versucht nur die wichtigsten Funktionen bez\u00fcglich des Themas zu behandeln.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Funktionalit\u00e4t und Performance<\/h2>\n\n\n\n<p>Wie bereits erw\u00e4hnt, wird jeglicher Netzwerkverkehr durch den ServiceWorker geleitet. Es ist also offensichtlich, dass dort eine kleine Verz\u00f6gerung entsteht. Wenn man also nur eine Offlinefunktionalit\u00e4t einbauen m\u00f6chte, wird man automatisch minimale Performance Verschlechterungen haben. Diese sollte aber durch intelligentes Caching recht leicht wieder ausgleichbar sein.<\/p>\n\n\n\n<p>Zu einem Vor- und Nachteil k\u00f6nnte werden, dass der Entwickler komplett eigenverantwortlich das Caching umsetzen kann bzw. muss. Hier k\u00f6nnen einige Fehler passieren, welche die Performance verschlechtern k\u00f6nnten. Auf der anderen Seite sollte der Entwickler aber auch am besten wissen, welche Ressourcen gecached werden k\u00f6nnen und welche nicht. Man k\u00f6nnte z.B. Templates f\u00fcr die App komplett im Cache behalten und nur Inhalte innerhalb dieser Templates \u00fcber das Netzwerk abrufen. Die Grundstrukturen der Webseite bleiben in der Regel ja immer die gleichen, nur die Inhalte \u00e4ndern sich. Zus\u00e4tzlich dazu hat man dann die Offline Funktion, welche zus\u00e4tzlich auch die Inhalte der letzten Online Requests bereitstellen kann.<\/p>\n\n\n\n<p>Ein weiteres Problem ist der Start des ServiceWorkers. Er wird immer terminiert, sobald er nicht gebraucht wird. Dies f\u00fchrt dazu, dass er auch immer wieder neu gestartet werden muss, bevor er wieder arbeiten kann. Dadurch gibt es eine kleine Verz\u00f6gerung, bis er dem Besucher der Webseite Ressourcen zu Verf\u00fcgung stellen kann. Um dieser Verz\u00f6gerung entgegenzuwirken, wurde die Strategie \u201eNavigation Preload\u201c entwickelt. Es k\u00f6nnen bereits parallel zum Start eines ServiceWorkers entsprechende Requests durchgef\u00fchrt werden, damit diese bei Bedarf innerhalb des fetch Events genutzt werden k\u00f6nnen. Dies f\u00fchrt aber dazu, dass eventuell unn\u00f6tige Netzwerkzugriffe durchgef\u00fchrt werden, da der Zugriff bei einem Treffer im Cache komplett umsonst war. Aber bei Ger\u00e4ten mit schlechterer Hardware, kann man so etwas Zeit einsparen.<\/p>\n\n\n\n<p>Gerade in der heutigen Zeit, wo auch der Speicher auf mobilen Ger\u00e4ten immer gr\u00f6\u00dfer wird, k\u00f6nnten ServiceWorker eine gute Hilfe sein. Durch das gro\u00dfz\u00fcgige Caching k\u00f6nnen viele Funktionalit\u00e4ten auch Offline verf\u00fcgbar gemacht werden. Bei Ger\u00e4ten mit wenig Speicher ist dies nat\u00fcrlich problematisch. Die gespeicherten Seiten werden auf Dauer vermutlich zu viel Speicher ben\u00f6tigen.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Datenschutz<\/h2>\n\n\n\n<p>Wenn man aktuell von Webtracking h\u00f6rt, denkt man sofort an Cookies. ServiceWorker k\u00f6nnen aber im Prinzip \u00e4hnliche Dinge erreichen. Sie k\u00f6nnen Daten \u00fcber Requests sammeln oder im Hintergrund Daten synchronisieren. Zus\u00e4tzlich wei\u00df man oft nicht, dass eine Webseite einen ServiceWorker einsetzt.<\/p>\n\n\n\n<p>Um zu \u00fcberpr\u00fcfen, welche Webseiten einen ServiceWorker benutzen kann man in Chrome alle genutzten ServiceWorker unter folgender URL einsehen: \u201echrome:\/\/serviceworker-internals\u201c. In Firefox kann man dies unter der URL \u201eabout:debugging\u201c tun.<\/p>\n\n\n\n<p>Auch die Transparenz bei ServiceWorkern l\u00e4sst zu w\u00fcnschen \u00fcbrig. Viele Webseiten benutzen ServiceWorker, man wei\u00df nur nichts davon. Zum einen kann man dadurch die Funktionalit\u00e4ten nicht optimal nutzen, zum anderen wei\u00df man dann aber auch nicht, dass dort Daten gespeichert werden k\u00f6nnen.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Fazit<\/h2>\n\n\n\n<p>Schlussendlich w\u00fcrde ich sagen, dass ein ServiceWorker durchaus sehr gute Vorteile bringen kann. Man sollte aber nicht denken, dass man direkt nach dem Einsatz eine bessere Performance und ein optimales Caching hat. Ein unbedachter Einsatz kann auch schnell kontraproduktiv sein.<\/p>\n\n\n\n<p>Die verschiedenen beschriebenen Konfigurationen eines ServiceWorker habe ich getestet und auch die Performance \u00fcberpr\u00fcft. Dabei sind mir kaum Unterschiede aufgefallen, vermutlich weil meine Testanwendung zu klein und nicht komplex genug war. Der standardm\u00e4\u00dfige Caching Mechanismus im Browser war in allen F\u00e4llen gleich gut. Um klarere Ergebnisse erzielen zu k\u00f6nnen, m\u00fcsste man meiner Meinung nach zum einen eine gr\u00f6\u00dfere Anwendung testen und zum anderen klare Ziele setzen.<br>Durch das individuelle Caching setzt der Mechanismus teilweise nur an anderen Stellen an. So wird die Performance nicht verbessert oder verschlechtert, sondern die Arbeiten nur verschoben. Dies macht die Performance-\u00dcberpr\u00fcfungen etwas schwieriger. Ein ServiceWorker erm\u00f6glicht es jedoch relativ einfach, dass man den Aufruf von weiteren Seiten der Webseite beschleunigt. Dies kann man erreichen, indem man bereits w\u00e4hrend der Installation oder w\u00e4hrend eines \u201eruhigen\u201c Moments im Hintergrund, Daten runterl\u00e4dt. &nbsp;<\/p>\n\n\n\n<p>Mein Ziel war es mehr oder weniger herauszufinden, ob die Anwendung durch den Offline First Ansatz an Performance verliert. Dies ist nach meinen Untersuchungen nicht deutlich geworden.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Referenzen<\/h2>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/www.w3.org\/TR\/service-workers\/\">https:\/\/www.w3.org\/TR\/service-workers\/<\/a><\/li><li><a href=\"https:\/\/developers.google.com\/web\/fundamentals\/primers\/service-workers\">https:\/\/developers.google.com\/web\/fundamentals\/primers\/service-workers<\/a><\/li><li><a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/Service_Worker_API\">https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/Service_Worker_API<\/a><\/li><li><a href=\"https:\/\/medium.baqend.com\/the-technology-behind-fast-websites-2638196fa60a\">https:\/\/medium.baqend.com\/the-technology-behind-fast-websites-2638196fa60a<\/a><\/li><li><a href=\"https:\/\/developers.google.com\/web\/fundamentals\/primers\/service-workers\/high-performance-loading\">https:\/\/developers.google.com\/web\/fundamentals\/primers\/service-workers\/high-performance-loading<\/a><\/li><li><a href=\"https:\/\/developers.google.com\/web\/showcase\/2016\/service-worker-perf\">https:\/\/developers.google.com\/web\/showcase\/2016\/service-worker-perf<\/a><\/li><li><a href=\"https:\/\/googlechrome.github.io\/samples\/service-worker\/basic\/index.html\">https:\/\/googlechrome.github.io\/samples\/service-worker\/basic\/index.html<\/a><\/li><li><a href=\"https:\/\/developers.google.com\/web\/updates\/2015\/12\/background-sync\">https:\/\/developers.google.com\/web\/updates\/2015\/12\/background-sync<\/a><\/li><li><a href=\"https:\/\/developers.google.com\/web\/ilt\/pwa\/introduction-to-push-notifications\">https:\/\/developers.google.com\/web\/ilt\/pwa\/introduction-to-push-notifications<\/a><\/li><\/ul>\n","protected":false},"excerpt":{"rendered":"<p>In der Vorlesung Rich Media haben wir uns viel mit Performance in Web Anwendungen besch\u00e4ftigt. Dabei habe ich mich mit ServiceWorkern in Bezug auf Offlinenutzung, Funktionalit\u00e4t und Performance besch\u00e4ftigt. Zuerst habe ich mich damit befasst, wie ein ServiceWorker funktioniert. Danach habe ich geschaut, wie sich die Nutzung eines ServiceWorker und des Ansatzes Offline First auf die Performance auswirkt.<\/p>\n","protected":false},"author":999,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[649,262],"tags":[],"ppma_author":[839],"class_list":["post-12376","post","type-post","status-publish","format-standard","hentry","category-interactive-media","category-rich-media-systems"],"aioseo_notices":[],"jetpack_featured_media_url":"","jetpack-related-posts":[{"id":28654,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2026\/02\/28\/multiplayer-arena-dynamische-game-sessions-mit-docker-fastapi\/","url_meta":{"origin":12376,"position":0},"title":"Multiplayer-Arena: Dynamische Game-Sessions mit Docker &amp; FastAPI","author":"Emre Kalkan","date":"28. February 2026","format":false,"excerpt":"Game: https:\/\/46.101.127.20.sslip.io\/ (online bis 31. M\u00e4rz 2026) (beachte Readme im Git!) Git Repo: https:\/\/github.com\/ek101-collab\/ArenaGame-with-ContainerSessions Einleitung und Motivation Im Rahmen der Vorlesung \"System Engineering und Management\" bestand die Kernaufgabe darin, ein Projekt zu konzipieren und umzusetzen, das moderne Web- und Cloud-Technologien nutzt. Zu Beginn der Projektphase lag mein Fokus auf einer\u2026","rel":"","context":"In &quot;Allgemein&quot;","block_context":{"text":"Allgemein","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/allgemein\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2026\/02\/mainmenu.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2026\/02\/mainmenu.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2026\/02\/mainmenu.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2026\/02\/mainmenu.png?resize=700%2C400&ssl=1 2x"},"classes":[]},{"id":8217,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2019\/08\/29\/progressive-web-apps-wer-braucht-noch-eine-native-app\/","url_meta":{"origin":12376,"position":1},"title":"Progressive Web Apps \u2013 Wer braucht noch eine native App?","author":"Dominik Zinser","date":"29. August 2019","format":false,"excerpt":"Beispiele zum Einstieg Progressive Web Apps sind schon weiter verbreitet wie man denkt. Auch gro\u00dfe, innovative Unternehmen Twitter, Airbnb, Spotify oder Tinder setzen auf Progressive Web Apps. Abb. 1: Eine Auswahl von Progressive Web Apps [1] Wer sich ein tolles Beispiel anschauen m\u00f6chte, dem empfehle ich https:\/\/riorun.theguardian.com\/ (auf mobile) zu\u2026","rel":"","context":"In &quot;Allgemein&quot;","block_context":{"text":"Allgemein","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/allgemein\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2019\/08\/1-150x150.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2019\/08\/1-150x150.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2019\/08\/1-150x150.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2019\/08\/1-150x150.png?resize=700%2C400&ssl=1 2x"},"classes":[]},{"id":24312,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2023\/02\/28\/kann-man-einen-wissenschaftlichen-blogeintrag-rein-mithilfe-von-chatgpt-schreiben\/","url_meta":{"origin":12376,"position":2},"title":"Kann man einen wissenschaftlichen Blogeintrag rein mithilfe von ChatGPT schreiben?","author":"zack walker","date":"28. February 2023","format":false,"excerpt":"Einleitung In den letzten Jahren hat die K\u00fcnstliche Intelligenz (KI) einen enormen Aufschwung erlebt und ist zu einem wichtigen Teil unseres t\u00e4glichen Lebens geworden. KI wird f\u00fcr eine Vielzahl von Aufgaben eingesetzt - von der Bilderkennung bis hin zur Sprachverarbeitung. Eine der neuesten Anwendungen von KI ist ChatGPT, ein System\u2026","rel":"","context":"In &quot;Allgemein&quot;","block_context":{"text":"Allgemein","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/allgemein\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/02\/Screenshot-2023-02-28-at-11.39.35.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/02\/Screenshot-2023-02-28-at-11.39.35.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/02\/Screenshot-2023-02-28-at-11.39.35.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/02\/Screenshot-2023-02-28-at-11.39.35.png?resize=700%2C400&ssl=1 2x"},"classes":[]},{"id":27563,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2025\/02\/28\/die-technische-entwicklung-einer-open-source-losung-zur-bildoptimierung\/","url_meta":{"origin":12376,"position":3},"title":"Die technische Entwicklung einer Open-Source-L\u00f6sung zur Bildoptimierung","author":"Lennart Gastler","date":"28. February 2025","format":false,"excerpt":"Im Rahmen meines Systems Engineering Projektes habe ich die shuto-api entwickelt \u2013 eine in Go geschriebene Open-Source-Bildoptimierungsl\u00f6sung. Mein Ziel war es, eine flexible, self-hostable und erweiterbare API zu erstellen, welche ohne viele Probleme in bereits bestehende Systeme integriert werden kann. Der Service erm\u00f6glicht es, Bilder zu komprimieren, zu skalieren sowie\u2026","rel":"","context":"In &quot;System Designs&quot;","block_context":{"text":"System Designs","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/system-designs\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2025\/02\/image-17.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2025\/02\/image-17.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2025\/02\/image-17.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2025\/02\/image-17.png?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2025\/02\/image-17.png?resize=1050%2C600&ssl=1 3x"},"classes":[]},{"id":20593,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2021\/09\/25\/herzlichen-gluckwunsch-sie-haben-gewonnen\/","url_meta":{"origin":12376,"position":4},"title":"HERZLICHEN GL\u00dcCKWUNSCH &#8211; Sie haben gewonnen!","author":"Eric Prytulla","date":"25. September 2021","format":false,"excerpt":"\u00dcber Social Engineering und wie man sich sch\u00fctzen kann. Jeder kennt E-Mails mit Titeln wie diesem. Eine wildfremde Person verspricht Gewinne in Millionenh\u00f6he. Und alles, was daf\u00fcr ben\u00f6tigt wird, sind ein paar pers\u00f6nliche Daten. Ein Traum vieler Menschen wird wahr und man will dem Titel glauben. Doch was passiert, wenn\u2026","rel":"","context":"In &quot;Allgemein&quot;","block_context":{"text":"Allgemein","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/allgemein\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/09\/Spam.png?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":22730,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2022\/03\/09\/um-die-technik-kummern-sich-die-anderen\/","url_meta":{"origin":12376,"position":5},"title":"Um die Technik k\u00fcmmern sich die Anderen&#8230;","author":"Aliena Leonhard","date":"9. March 2022","format":false,"excerpt":"Das Ph\u00e4nomen von 'sozio-technischen Systemen' und '\u00d6kosystemen' Mammut aus Gras von Christopher Alvarenga - [4] Wenn wir uns als technisch begeisterte Computer Science Studierenden ein zu Deutsch \u201cUltra Gro\u00dfes, Skaliertes System\u201d vorstellen... Was stellen wir uns dann wirklich vor? Naja wir denken wahrscheinlich erstmal an viele Zeilen Code, Unmengen von\u2026","rel":"","context":"In &quot;Allgemein&quot;","block_context":{"text":"Allgemein","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/allgemein\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2022\/03\/christopher-alvarenga-bfqPQeidFS0-unsplash.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2022\/03\/christopher-alvarenga-bfqPQeidFS0-unsplash.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2022\/03\/christopher-alvarenga-bfqPQeidFS0-unsplash.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2022\/03\/christopher-alvarenga-bfqPQeidFS0-unsplash.png?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2022\/03\/christopher-alvarenga-bfqPQeidFS0-unsplash.png?resize=1050%2C600&ssl=1 3x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2022\/03\/christopher-alvarenga-bfqPQeidFS0-unsplash.png?resize=1400%2C800&ssl=1 4x"},"classes":[]}],"jetpack_sharing_enabled":true,"authors":[{"term_id":839,"user_id":999,"is_guest":0,"slug":"br046","display_name":"Benedikt Reuter","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/8992fca3e72b93282873be721bf0d2aa7eb02deb134f05a481f5976902a1abff?s=96&d=mm&r=g","0":null,"1":"","2":"","3":"","4":"","5":"","6":"","7":"","8":""}],"_links":{"self":[{"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/posts\/12376","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/users\/999"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/comments?post=12376"}],"version-history":[{"count":14,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/posts\/12376\/revisions"}],"predecessor-version":[{"id":12626,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/posts\/12376\/revisions\/12626"}],"wp:attachment":[{"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/media?parent=12376"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/categories?post=12376"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/tags?post=12376"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/ppma_author?post=12376"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}