{"id":12187,"date":"2021-02-08T17:48:20","date_gmt":"2021-02-08T16:48:20","guid":{"rendered":"https:\/\/blog.mi.hdm-stuttgart.de\/?p=12187"},"modified":"2023-06-18T18:08:27","modified_gmt":"2023-06-18T16:08:27","slug":"perfomante-animationen","status":"publish","type":"post","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2021\/02\/08\/perfomante-animationen\/","title":{"rendered":"Perfomante Animationen"},"content":{"rendered":"\n<p>Animationen sind sehr ansprechend und bringen User dazu, \u00fcber eine l\u00e4ngere Zeit auf einer Webseite zu bleiben oder von dort aus nach weiteren Informationen des Anbieters zu suchen. Aus diesem Grund ist es wichtig, dass sie ihre Funktion erf\u00fcllen und fl\u00fcssig laufen. Trotzdem st\u00f6\u00dft man immer wieder auf Animationen, die ruckeln und nicht gut performen. Insbesondere bei mobilen Endger\u00e4ten mit ihrer vergleichsweise geringen Rechenleistung fallen solche Probleme auf &#8211; und damit ausgerechnet in einem Bereich, der immer bedeutsamer wird. Laut eines Google-Berichtes stehen bereits hinter mehr als f\u00fcnfzig Prozent des Datenverkehrs mobile Endger\u00e4te. Animationen sollten daher auf jeden Fall optimiert werden.<\/p>\n\n\n\n<p>Um die perfekte Animation zu erstellen, gibt es nicht die eine L\u00f6sung. Doch dieser Artikel versucht, einige Punkte zu vermitteln, die man als Entwickler beachten sollte. Grundlage daf\u00fcr ist das Verst\u00e4ndnis von CSS, JavaScript und HTML.<\/p>\n\n\n\n<!--more-->\n\n\n\n<p>Was ist eine Animation? Mit einer Animation kann die \u00c4nderung von CSS Properties dargestellt werden. Wenn sich eine solche Property \u00e4ndert, zeigt der Browser diese bei einer Animation nicht abrupt, sondern als \u00dcbergang an. Wenn ein Element eine volle Deckkraft hat und entfernt wird, w\u00fcrde es normalerweise verschwinden. Mit einem \u00dcbergang verliert das Element \u00fcber Zeit die Deckkraft, bis es komplett verschwunden ist. Entwickler k\u00f6nnen den Verlauf (z.B. lineare \u00c4nderung der CSS Property) und die Dauer der \u00dcberg\u00e4nge anpassen.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Animations oder Transitions oder JavaScript?<\/h2>\n\n\n\n<p>Grunds\u00e4tzlich gibt es verschiedene M\u00f6glichkeiten, \u00dcberg\u00e4nge zu erstellen. Auf drei davon, soll an dieser Stelle eingegangen werden: Transitions, Animations bzw. Keyframes und JavaScript.<\/p>\n\n\n\n<p>Transitions sind die einfachere Variante von \u00dcberg\u00e4ngen. Entwickler k\u00f6nnen mit ihnen den Wechsel von Zustand A zu B definieren. Am h\u00e4ufigsten sind Transitions zu sehen, wenn zwischen solchen Zust\u00e4nden gewechselt werden muss. Beispiele sind Effekte beim Hovern eines Elements oder das \u00d6ffnen eines Side-Men\u00fcs. Das Definieren einer Transition funktioniert folgenderma\u00dfen:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\" data-line=\"\">.btn {\n  opacity: 1;\n  transition: opacity 0.5s;\n}\n\n.btn:hover {\n  opacity: 0.5;\n}<\/code><\/pre>\n\n\n\n<p>In diesem Beispiel l\u00e4sst sich ein Button mit voller Deckkraft erkennen. In der zweiten Zeile der Definition des Buttons ist die Transition festgehalten. Immer wenn sich die Deckkraft des Elements \u00e4ndert, wird dies \u00fcber einen Zeitraum von 0,5s gemacht. Wenn der Button gehovert wird, \u00e4ndert sich die opacity auf 0,8. Dementsprechend kommt es zu einer Animation des \u00dcbergangs.<\/p>\n\n\n\n<p>Keyframes hingegen sind m\u00e4chtiger, aber auch komplizierter. Sie erm\u00f6glichen es dem Entwickler, mehr Zust\u00e4nde zu definieren. So kann eine Animation den Wechsel von A &#8211;&gt; B &#8211;&gt; C &#8211;&gt; D darstellen. Durch ihre Komplexit\u00e4t ist die Definition auch aufwendiger:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\" data-line=\"\">@keyframes foo {\n  0% { opacity: 1; }\n  50% { opacity: 0.5; }\n  100% { opacity: 1; }\n}\n\n.btn {\n  opacity: 1;\n  animation: foo 0.5s;\n}<\/code><\/pre>\n\n\n\n<p>In dem <em>@keyframes <\/em>werden die einzelnen Zust\u00e4nde definiert. Dieses Keyframe wird dann \u00fcber das CSS-Attribut <em>animation <\/em>dem Element zugewiesen.<\/p>\n\n\n\n<p>JavaScript Animationen sind eine weitere M\u00f6glichkeit, \u00dcberg\u00e4nge zu erstellen. Dazu muss der Entwickler die Styles in kurzer Zeit oft anpassen. Das folgende Beispiel stammt aus w3schools (<a href=\"https:\/\/www.w3schools.com\/howto\/howto_js_animate.asp\">https:\/\/www.w3schools.com\/howto\/howto_js_animate.asp<\/a>):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\" data-line=\"\">function myMove() {\n  var elem = document.getElementById(&quot;myAnimation&quot;);\n  var pos = 0;\n  var id = setInterval(frame, 10);\n  function frame() {\n    if (pos == 350) {\n      clearInterval(id);\n    } else {\n      pos++;\n      elem.style.top = pos + &#039;px&#039;;\n      elem.style.left = pos + &#039;px&#039;;\n    }\n  }\n}<\/code><\/pre>\n\n\n\n<p>Hier wird das Styling des Elements alle 10ms angepasst. Daf\u00fcr verwendet die Funktion die <em>setInterval<\/em>-Methode. Das f\u00fchrt dazu, dass das Element \u201eanimiert\u201c wird. Sobald das Element 350-mal bewegt wurde, endet die Animation bzw. das Intervall.<\/p>\n\n\n\n<p>In der JavaScript-Welt gibt es noch mehr Wege, \u00dcberg\u00e4nge umzusetzen. Viele Libraries (wie z.B. JQuery) haben Schnittstellen, mit denen Animationen erstellt und ausgel\u00f6st werden k\u00f6nnen. Zus\u00e4tzlich gibt es die Web Animations API, die es erm\u00f6glicht, Keyframes Animationen \u00fcber JavaScript zu erstellen. Eine detaillierte Beschreibung der Web Animations API l\u00e4sst sich hier finden: <a href=\"https:\/\/css-tricks.com\/css-animations-vs-web-animations-api\/\">https:\/\/css-tricks.com\/css-animations-vs-web-animations-api\/<\/a>.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Alle Varianten haben ihre Vorz\u00fcge und eignen sich f\u00fcr jeweils verschiedene Anwendungen. Man sollte Transitions verwenden, wenn man zwischen zwei Zust\u00e4nden hin und her wechseln will und daf\u00fcr einen \u00dcbergang braucht.<\/li><li>Man sollte Animations verwenden, wenn man mehr als zwei Zust\u00e4nde hat und daf\u00fcr \u00dcberg\u00e4nge braucht. Animations erlauben auch \u00dcberg\u00e4nge, die unendlich laufen.<\/li><li>Man sollte JavaScript verwenden, wenn man die volle Kontrolle \u00fcber die Animation braucht. Das ist der Fall bei Effekten wie Pausieren oder Stoppen. Die Umsetzung der \u00dcberg\u00e4nge kann hierbei selbst implementiert werden (s.o.) oder Entwickler k\u00f6nnen die Schnittstellen der Web Animations API bzw. von Libraries verwenden.<\/li><\/ul>\n\n\n\n<p>Der Einfachheit halber werden im Folgenden alle Varianten der \u00dcberg\u00e4nge als Animationen bezeichnet.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Was macht eine gute Performance aus?<\/h2>\n\n\n\n<p>Das Ziel bei der Umsetzung aller genannten Varianten ist eine fl\u00fcssige und performante Animation. Um dies zu erreichen, m\u00fcssen 60FPS erreicht werden. FPS steht f\u00fcr \u201eframes per second\u201c. Pro Sekunde soll also das gew\u00e4hlte Element 60-mal angepasst werden. Denn: wenn Bilder sehr oft pro Sekunde ge\u00e4ndert werden, sieht es f\u00fcr den Menschen wie eine fl\u00fcssige Bewegung aus. Umgerechnet bedeutet das: der Browser hat 16,67ms, um ein Frame zu berechnen. Das ist nicht viel Zeit. Das muss dem Entwickler klar sein. Besonders wichtig ist dies, wenn die Nutzer auf Endger\u00e4ten sind, die eine schlechtere Rechenleistung besitzen. Dazu z\u00e4hlen zum Beispiel mobile Endger\u00e4te. Wenn die genannten 60FPS nicht m\u00f6glich sind bzw. die Berechnung eines Frames l\u00e4nger als 16,67ms dauert, nennt man das <strong>Jank<\/strong>. Es werden Frames \u00fcbersprungen. Da sich die Bilder nicht mehr in der gew\u00fcnschten Rate \u00e4ndern, kann der Mensch dies wahrnehmen. Die Folge ist, dass die Animation ruckelt. In Zukunft ist es wahrscheinlich, dass die erw\u00fcnschten FPS noch weiter ansteigen, da die Rechner immer mehr Rechenkapazit\u00e4ten bekommen. Dies wird eine noch geringere Zeit zur Berechnung eines Frames zur Folge haben. Eine Optimierung von Animationen wird also in der Zukunft noch wichtiger sein.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Die Optimierung einer Animation: Was passiert im Browser?<\/h2>\n\n\n\n<p>Bevor wir uns an die Optimierung einiger Beispiele setzen, will ich noch erkl\u00e4ren, wie der Browser Inhalte anzeigt. Dadurch soll klarer werden, wie wir unser Ziel &#8211; 60FPS \u2013 erreichen. Was macht der Browser also? Hierbei gibt es verschiedene Phasen, die er durchl\u00e4uft:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>Styling: <\/strong>In dieser Phase berechnet der Browser das Styling der einzelnen Elemente anhand der CSS-Klassen, der IDs usw. Der Browser bestimmt welche \u00c4nderungen er am aktuellen Inhalt vornehmen muss, um diese umzusetzen. Nach dieser Phase folgt entweder Layout, Paint oder Composite.<\/li><\/ul>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>Layout:<\/strong> Der Browser berechnet an welche Position die einzelnen Elemente stehen. Folgende CSS-Attribute sind hier unter anderem relevant:<ul><li>Margin<\/li><\/ul><ul><li>Padding<\/li><\/ul><ul><li>Width und Height<\/li><\/ul><ul><li>Left, Top, Bottom, Right<\/li><\/ul><\/li><\/ul>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>Paint:<\/strong> Nun muss der Browser die einzelnen Bereiche \u201ebemalen\u201c. Er bef\u00fcllt also die Pixel. Das betrifft unter anderem folgende CSS-Attribute:<ul><li>Color<\/li><\/ul><ul><li>Background-color<\/li><\/ul><ul><li>Visibility<\/li><\/ul><\/li><\/ul>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>Composite: <\/strong>Zuletzt geht es an die Anordnung. Dabei werden die einzelnen Bereiche zusammengebaut. Falls dabei mehrere Ebenen notwendig sind (z.B. absolute Elemente), ordnet der Browser diese korrekt an. Er achtet dabei unter anderem auf folgende CSS-Attribute:<ul><li>Transform<\/li><\/ul><ul><li>Opacity<\/li><\/ul><ul><li>Z-Index<\/li><\/ul><ul><li>Pointer<\/li><\/ul><\/li><\/ul>\n\n\n\n<p>Hierbei ist wichtig zu verstehen, dass Layout &#8211;&gt; Paint &#8211;&gt; Composite in ihrer Reihenfolge festgelegt sind. Das hei\u00dft: Wenn der Browser ein Layout durchf\u00fchren muss, dann m\u00fcssen auch ein Paint und ein Composite folgen. Wenn hingegen nur ein Composite stattfindet, ist kein Layout notwendig.<\/p>\n\n\n\n<p>Wenn JavaScript auf einer Seite nun z.B. die Breite eines Elements \u00e4ndert, hat dies zur Folge, dass die Schritte Layout &#8211;&gt; Paint &#8211;&gt; Composite notwendig sind. Eine einmalige \u00c4nderung im Layout ist dabei kein Problem. Wenn man dies allerdings 60-mal in der Sekunde versucht, kann es zu Jank kommen. Viel besser ist es also, im Bereich Composite zu bleiben, da der Browser weniger Rechenschritte durchf\u00fchren muss.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Die Optimierung einer Animation: Side-Men\u00fc mit Transitions<\/h2>\n\n\n\n<p>Wie sich eine Animation optimieren l\u00e4sst, l\u00e4sst sich am besten Anhand eines Beispiels zeigen: ein Side-Men\u00fc. Ausgangspunkt soll dabei zun\u00e4chst der folgende Code sein:<\/p>\n\n\n\n<p>HTML<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\" data-line=\"\">&lt;body&gt;\n&lt;div id=\u201cmenu\u201c&gt;&lt;button onclick=\u201dtoggleMenu()\u201d&gt;Schlie\u00dfen&lt;\/button&gt;&lt;div&gt;\n&lt;main&gt;\n   &lt;h1&gt;Mein Inhalt&lt;\/h1&gt;\n   &lt;div class=\u201dbtn-wrapper\u201d&gt;\n      &lt;button onclick=\u201dtoggleMenu()\u201d&gt;Men\u00fc \u00f6ffnen&lt;\/button&gt;\n   &lt;div&gt;\n&lt;\/main&gt;\n&lt;\/body&gt;<\/code><\/pre>\n\n\n\n<p>JavaScript<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\" data-line=\"\">function toggleMenu() {\n  var menu = document.getElementById(\u201cmenu\u201d);\n  menu.classList.toggle(\u201cmenu-open\u201d);\n}<\/code><\/pre>\n\n\n\n<p>CSS<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\" data-line=\"\">#menu {\n    height: 100%;\n    width: 260px;\n    position: absolute;\n    margin-left: -310px;\n    background-color: indianred;\n    display: flex;\n    padding: 20px;\n    flex-direction: column;\n    align-items: flex-end;\n    transition: margin-left 1s;\n}\n\n.open-menu {\n    margin-left: 0 !important;\n}\n\nbutton {\n    transition: background-color .3s;\n    padding: 10px;\n    background-color: #2c3e50;\n    color: white;\n    cursor: pointer;\n    border: none;\n}\n\nbutton:hover {\n    background-color: #44596e;\n}<\/code><\/pre>\n\n\n\n<p>Wenn der Nutzer auf einen der Buttons klickt, wird das Men\u00fc entweder ge\u00f6ffnet oder geschlossen. Das Men\u00fc ist normalerweise nicht sichtbar, da es mit margin-left aus dem Bild geschoben ist. Wenn das Men\u00fc die Klasse \u201eopen-menu\u201c erh\u00e4lt, setzt man margin-left auf 0. Dadurch ist das Men\u00fc sichtbar. Neben dem Men\u00fc bekommen die Buttons noch etwas Styling und einen Hover-Effekt. Die Animationen sind hier also die Bewegung des Men\u00fcs und das \u00c4ndern der Hintergrundfarbe. Erkennbar ist dies im CSS durch das Attribut <em>transition<\/em>.<\/p>\n\n\n\n<p>Ein Ansatzpunkt zur Optimierung der Animation w\u00e4re in diesem Fall das \u00d6ffnen des Men\u00fcs. Hier sind folgende CSS-Styles relevant:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\" data-line=\"\">#menu {\n    \/* restliche Styles... *\/\n    transition: margin-left 1s;\n}\n\n.open-menu {\n    margin-left: 0 !important;\n}<\/code><\/pre>\n\n\n\n<p>In diesem Beispiel m\u00fcsste der Browser also immer wieder Layout, Paint und Composite durchlaufen, denn margin-left geh\u00f6rt zum Layout-Schritt. Besser w\u00e4re Folgendes:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\" data-line=\"\">#menu {\n    \/* restliche Styles... *\/\n    transition: transform 1s;\n}\n\n.open-menu {\n    transform: translateX(300px);\n}<\/code><\/pre>\n\n\n\n<p>Mit dieser Animation m\u00fcsste der Browser nur das Composite anpassen.<\/p>\n\n\n\n<p>Neben dieser Ma\u00dfnahme gibt es noch weiter M\u00f6glichkeiten, um Animationen zu optimieren. Man kann dem Browser mit folgendem CSS Attribut mitteilen, dass sich bestimmte Attribute \u00e4ndern werden:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\" data-line=\"\">will-change: transform;<\/code><\/pre>\n\n\n\n<p>Der Browser stellt sich dann auf die \u00c4nderungen ein und optimiert diese, indem er mehr Ressourcen als sonst in die Animation steckt. Allerdings kann sich will-change auch negativ auf die Performance auswirken. Wenn eine Seite das Attribut zu h\u00e4ufig verwendet, steckt der Browser insgesamt zu viele Ressourcen in die genannten Animationen. Dadurch kann die Performance der restlichen Seite leiden. Das Attribut sollte also nur als letztes Mittel genutzt werden. Falls man dem Men\u00fc noch mehr Ressourcen zuweisen m\u00f6chte, \u00e4ndern sich die Styles folgenderma\u00dfen:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\" data-line=\"\">#menu {\n   \/* restliche Styles... *\/\n   will-change: transform;\n}<\/code><\/pre>\n\n\n\n<p>Generell gilt: Weniger ist mehr. Wenn der Browser viele Animationen gleichzeitig berechnen muss oder mit anderen Dingen besch\u00e4ftigt ist, ist die Wahrscheinlichkeit h\u00f6her, dass es zu Jank kommt. Aus diesem Grund sollte die Seite auch keine Animationen anzeigen, wenn die Seite noch nicht komplett geladen ist. Das Binden von Animationen an bestimmte Events, etwa an das Srolling, ist aus Sicht der Performance ebenfalls kritisch, denn der Browser sendet beim Scrolling viele Events. Man muss bei entsprechenden Animationen sehr vorsichtig sein.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Die Optimierung einer Animation: Side-Men\u00fc mit JavaScript<\/h2>\n\n\n\n<p>Ein zweites Beispiel soll zeigen, wie sich JavaScript Animationen optimieren lassen. Um das Men\u00fc zu \u00f6ffnen, nutzt man hier nicht CSS, sondern JavaScript. Als Orientierung f\u00fcr die Funktion dient an dieser Stelle das obige Beispiel. Das Styling des Men\u00fcs bleibt quasi gleich. Die Funktion zum \u00d6ffnen\/ Schlie\u00dfen des Men\u00fcs sieht so aus:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\" data-line=\"\">function jsMenuToggle(open) {\n  var menu = document.getElementById(&#039;menu&#039;);\n\n  var id = setInterval(function () {\n    var marginLeft = menu.style.marginLeft || &#039;-310px&#039;;\n    var marginLeftInt = parseInt(marginLeft.replace(&#039;px&#039;, &#039;&#039;));\n\n    if (marginLeftInt === 0 &amp;&amp; open || marginLeftInt === -310 &amp;&amp; !open) {\n      clearInterval(id);\n    } else if (!open) {\n      menu.style.marginLeft = (marginLeftInt - 1) + &#039;px&#039;;\n    } else {\n      menu.style.marginLeft = (marginLeftInt + 1) + &#039;px&#039;;\n    }\n  }, 10);\n}<\/code><\/pre>\n\n\n\n<p>Es passiert folgendes:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><em>Open<\/em> teilt der Funktion mit, ob sie das Men\u00fc \u00f6ffnen oder schlie\u00dfen soll.<\/li><li><em>Menu <\/em>enth\u00e4lt die Referenz zum Side-Men\u00fc<\/li><li>Anschlie\u00dfend erstellt man ein Intervall. Die mitgegebene Funktion wird alle 10ms aufgerufen.<\/li><li>In den n\u00e4chsten beiden Zeilen wird der aktuelle Wert von <em>margin-left extrahiert<\/em>.<\/li><li>Am Ende kontrolliert man, ob das Men\u00fc seine Endzust\u00e4nde erreicht hat. Wenn ja, wird das Intervall beendet. Wenn nein, \u00e4ndert sich der der Wert von margin-left.<\/li><\/ul>\n\n\n\n<p>In diesem Beispiel erf\u00fcllen Intervalle grunds\u00e4tzlich ihren Zweck. Der Code manipuliert immer wieder in kurzen Zeitabst\u00e4nden die Styles des Elements. Allerdings f\u00fchren die Intervalle zu einigen Problemen:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Sie laufen auch im Hintergrund weiter. Das f\u00fchrt zu einem h\u00f6heren Batterieverbrauch beim Client.<\/li><li>Verschiedene Ger\u00e4te haben unterschiedliche Framerates. Somit kann der Code entweder zu wenige oder zu viele Aufrufe generieren. 10ms k\u00f6nnten je nach Ger\u00e4t stimmen &#8211; oder auch nicht.<\/li><li>Der Code ist nicht mit dem Rendering des Browsers synchronisiert. Wenn der Browser bereits angefangen hat, einen Frame zu berechnen, und anschlie\u00dfend dieser Code ausgel\u00f6st wird, bleibt f\u00fcr seine Ausf\u00fchrung unter Umst\u00e4nden noch weniger Zeit als 16ms. Die Berechnung dauert zu lange und es entsteht Jank.<\/li><li>In diesem Intervall wird das Styling von mergin-left manipuliert. Wie wir bereits erl\u00e4utert haben, ist dies nicht optimal.<\/li><\/ul>\n\n\n\n<p>Die L\u00f6sung f\u00fcr die genannten Probleme liefert die Funktion: <strong>requestAnimationFrame<\/strong>. Sie teilt dem Browser mit, dass man eine Funktion ausf\u00fchren will, wenn der n\u00e4chste Frame berechnet wird. Die Funktion passt sich an die Framerates der einzelnen Ger\u00e4te an und spart dadurch Akkuladung. Die optimierte Funktion sieht dann folgenderma\u00dfen aus:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\" data-line=\"\">function jsMenuToggle(open) {\n  var menu = document.getElementById(&#039;menu&#039;);\n\n  var frame = function () {\n    var transform = menu.style.transform || &#039;translateX(0px)&#039;;\n    var transformInt = parseInt(transform.replace(&#039;translateX(&#039;, &#039;&#039;).replace(&#039;px)&#039;, &#039;&#039;));\n\n    if (transformInt === 300 &amp;&amp; open || transformInt === 0 &amp;&amp; !open) {\n      return;\n    } else if (!open) {\n      menu.style.transform = &#039;translateX(&#039; + (transformInt - 1) + &#039;px)&#039;;\n    } else {\n      menu.style.transform = &#039;translateX(&#039; + (transformInt + 1) + &#039;px)&#039;;\n    }\n    window.requestAnimationFrame(frame);\n  }\n  window.requestAnimationFrame(frame);\n}<\/code><\/pre>\n\n\n\n<p>Im Zuge der Optimierung haben sich folgende Dinge ge\u00e4ndert:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Man definiert kein Intervall mehr, sondern eine einfache innere Funktion <em>frame<\/em>.<\/li><li>Diese Funktion \u00e4ndert nun transform und nicht mehr margin-left.<\/li><li>Falls das Men\u00fc noch nicht komplett ge\u00f6ffnet oder geschlossen ist, ruft sie am Ende <em>requestAnimationFrame <\/em>auf. Als Parameter gibt die Funktion sich selber mit. Es ist also eine Art rekursiver Aufruf.<\/li><li>Am Ende der \u00e4u\u00dferen Funktion startet die Animation, indem die innere Funktion <em>frame <\/em>an <em>requestAnimationFrame <\/em>gegeben wird.<\/li><\/ul>\n\n\n\n<p>Der Browser kann nun die innere Funktion zum optimalen Zeitpunkt aufzurufen. Au\u00dferdem muss er nicht mehr das Layout berechnen.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Die Optimierung einer Animation: Die Buttons des Side-Men\u00fcs<\/h2>\n\n\n\n<p>Des Weiteren zu beachten sind die Buttons. Ihre Hintergrundfarbe wird animiert, wenn der Nutzer sie hovert. Und das f\u00fchrt zu einem Painting &#8211;&gt; Composite. Daraus ergeben sich keine gro\u00dfen Probleme, aber optimal ist es nicht.<\/p>\n\n\n\n<p>Doch wie l\u00e4sst sich das Problem l\u00f6sen &#8211; zumal weder transform noch opacity die Farbe des Elements \u00e4ndern k\u00f6nnen. Hier lohnt es sich, in die Trickkiste zu greifen. Zun\u00e4chst der Code:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\" data-line=\"\">button {\n    \/* removed transition: background-color *\/\n    position: relative;\n}\n\nbutton::after {\n    content: &quot;&quot;;\n    position: absolute;\n    left: 0;\n    top: 0;\n    right: 0;\n    bottom: 0;\n    background-color: #fff;\n    opacity: 0;\n    transition: opacity 0.3s;\n}\n\nbutton:hover::after {\n    opacity: 0.1;\n}<\/code><\/pre>\n\n\n\n<p>Folgendes hat sich nun ge\u00e4ndert:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Zun\u00e4chst hat der Button keine Transition mehr. Sie wird durch position: relative ersetzt.<\/li><li>Anschlie\u00dfend nutzt man das Pseudo-Element <em>after<\/em>, um in dem Button einen absoluten Kasten einzuf\u00fcgen, der sich \u00fcber die gesamte Gr\u00f6\u00dfe des Buttons erstreckt. Dieser Kasten hat eine wei\u00dfe Hintergrundfarbe und ist zun\u00e4chst nicht sichtbar.<\/li><li>Wenn der Button nun gehovert wird, \u00e4ndert sich die opacity des Kastens. Da er eine Transition hat, wird dieser Kasten nun \u00fcber dem Button gezeigt. Er simuliert so das \u00c4ndern der Hintergrundfarbe. Den Button selber kann man immer noch sehen, da der Kasten nur eine leichte Deckkraft hat.<\/li><\/ul>\n\n\n\n<p>So erh\u00e4lt man eine performante Animation, mit der sich Farben \u201e\u00e4ndern\u201c k\u00f6nnen. Und auch wenn dieser Form der Optimierung nicht in jedem Fall unerl\u00e4sslich ist, kann sie doch gerade bei komplexen Animationen zu einem guten Ergebnis f\u00fchren.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Wie l\u00e4sst sich der Erfolg einer Animations-Optimierung kontrollieren?<\/h2>\n\n\n\n<p>Ob die Optimierung einer Animation tats\u00e4chlich den gew\u00fcnschten Effekt hat, l\u00e4sst sich mit Developer-Tools in Chrome kontrollieren. Sie helfen bei der Entwicklung von Animationen und k\u00f6nnen in Chrome zum Beispiel mit F12 ge\u00f6ffnet werden.<\/p>\n\n\n\n<p>Einige Fenster in den Developer Tools, die nicht per Default ge\u00f6ffnet sind, lassen sich hier finden:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/01\/Bildschirmfoto-2021-01-18-um-19.45.08.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1000\" height=\"452\" data-attachment-id=\"12188\" data-permalink=\"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2021\/02\/08\/perfomante-animationen\/bildschirmfoto-2021-01-18-um-19-45-08\/\" data-orig-file=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/01\/Bildschirmfoto-2021-01-18-um-19.45.08.png\" data-orig-size=\"1000,452\" 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=\"Bildschirmfoto-2021-01-18-um-19.45.08\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/01\/Bildschirmfoto-2021-01-18-um-19.45.08.png\" src=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/01\/Bildschirmfoto-2021-01-18-um-19.45.08.png\" alt=\"\" class=\"wp-image-12188\" srcset=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/01\/Bildschirmfoto-2021-01-18-um-19.45.08.png 1000w, https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/01\/Bildschirmfoto-2021-01-18-um-19.45.08-300x136.png 300w, https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/01\/Bildschirmfoto-2021-01-18-um-19.45.08-768x347.png 768w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/a><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/01\/Bildschirmfoto-2021-01-18-um-19.46.10.png\"><img loading=\"lazy\" decoding=\"async\" width=\"422\" height=\"452\" data-attachment-id=\"12189\" data-permalink=\"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2021\/02\/08\/perfomante-animationen\/bildschirmfoto-2021-01-18-um-19-46-10\/\" data-orig-file=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/01\/Bildschirmfoto-2021-01-18-um-19.46.10.png\" data-orig-size=\"422,452\" 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=\"Bildschirmfoto-2021-01-18-um-19.46.10\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/01\/Bildschirmfoto-2021-01-18-um-19.46.10.png\" src=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/01\/Bildschirmfoto-2021-01-18-um-19.46.10.png\" alt=\"\" class=\"wp-image-12189\" srcset=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/01\/Bildschirmfoto-2021-01-18-um-19.46.10.png 422w, https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/01\/Bildschirmfoto-2021-01-18-um-19.46.10-280x300.png 280w\" sizes=\"auto, (max-width: 422px) 100vw, 422px\" \/><\/a><\/figure>\n\n\n\n<p>Um die Performance der Animationen mithilfe des Fensters <strong>Performance <\/strong>in den Developer-Tools zu untersuchen, sollte man auf Aufnehmen klicken, anschlie\u00dfend die Animation abspielen und dann die Aufnahme beenden. F\u00fcr die nicht optimierte Animation des Side-Men\u00fcs liefert das Tool dann folgendem Bericht:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/01\/Bildschirmfoto-2021-01-18-um-19.55.10.png\"><img loading=\"lazy\" decoding=\"async\" width=\"847\" height=\"1024\" data-attachment-id=\"12190\" data-permalink=\"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2021\/02\/08\/perfomante-animationen\/bildschirmfoto-2021-01-18-um-19-55-10\/\" data-orig-file=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/01\/Bildschirmfoto-2021-01-18-um-19.55.10.png\" data-orig-size=\"1156,1398\" 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=\"Bildschirmfoto-2021-01-18-um-19.55.10\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/01\/Bildschirmfoto-2021-01-18-um-19.55.10-847x1024.png\" src=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/01\/Bildschirmfoto-2021-01-18-um-19.55.10-847x1024.png\" alt=\"\" class=\"wp-image-12190\" srcset=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/01\/Bildschirmfoto-2021-01-18-um-19.55.10-847x1024.png 847w, https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/01\/Bildschirmfoto-2021-01-18-um-19.55.10-248x300.png 248w, https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/01\/Bildschirmfoto-2021-01-18-um-19.55.10-768x929.png 768w, https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/01\/Bildschirmfoto-2021-01-18-um-19.55.10.png 1156w\" sizes=\"auto, (max-width: 847px) 100vw, 847px\" \/><\/a><\/figure>\n\n\n\n<p>In den rot umrandeten Bereichen lassen sich die wichtigsten Informationen ablesen:<\/p>\n\n\n\n<ol class=\"wp-block-list\" type=\"1\"><li>Um das Ergebnis besser zeigen zu k\u00f6nnen, wurde die CPU 6x langsamer gemacht.<\/li><li>Bei den Frames ist zu erkennen, dass die gr\u00fcnen Balken unterschiedlich dick sind. Die Berechnung f\u00fcr einzelne Frames schwankt stark. Das f\u00e4llt besonders im rechten Bereich auf.<\/li><li>Der Browser ist bei einer einsek\u00fcndigen Animation fast 400ms damit besch\u00e4ftigt das Men\u00fc zu rendern. Weitere 160ms sind dem Painting zuzurechnen. Wie bereits erw\u00e4hnt: Bei der nicht optimierten Version der Seite muss der Browser immer wieder Layout, Paint und Composite durchlaufen.<\/li><\/ol>\n\n\n\n<p>Der Bericht f\u00fcr die optimierte Animation s\u00e4he demgegen\u00fcber so aus:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/01\/Bildschirmfoto-2021-01-18-um-20.02.17.png\"><img loading=\"lazy\" decoding=\"async\" width=\"860\" height=\"1024\" data-attachment-id=\"12191\" data-permalink=\"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2021\/02\/08\/perfomante-animationen\/bildschirmfoto-2021-01-18-um-20-02-17\/\" data-orig-file=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/01\/Bildschirmfoto-2021-01-18-um-20.02.17.png\" data-orig-size=\"1156,1376\" 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=\"Bildschirmfoto-2021-01-18-um-20.02.17\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/01\/Bildschirmfoto-2021-01-18-um-20.02.17-860x1024.png\" src=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/01\/Bildschirmfoto-2021-01-18-um-20.02.17-860x1024.png\" alt=\"\" class=\"wp-image-12191\" srcset=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/01\/Bildschirmfoto-2021-01-18-um-20.02.17-860x1024.png 860w, https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/01\/Bildschirmfoto-2021-01-18-um-20.02.17-252x300.png 252w, https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/01\/Bildschirmfoto-2021-01-18-um-20.02.17-768x914.png 768w, https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/01\/Bildschirmfoto-2021-01-18-um-20.02.17.png 1156w\" sizes=\"auto, (max-width: 860px) 100vw, 860px\" \/><\/a><\/figure>\n\n\n\n<p>Die Frames zeigen konstant 60 FPS und der Unterschied bei den Zusammenfassungen ist gigantisch. Der Browser muss in der optimierten Version viel weniger Rendering und Painting betreiben.<\/p>\n\n\n\n<p>Ebenfalls n\u00fctzlich ist das Fenster <strong>Rendering <\/strong>mit der Option Paint Flashing. Wenn sie aktiv ist, blinken Bereiche der Seite, die erneut ein Painting erhalten. Bei der inperformanten Variante der Side-Men\u00fcs ist das Blinken im gesamten Verlauf der Animation zu sehen, bei der optimierten Version nur am Ende der Animation.<\/p>\n\n\n\n<p>Als weiteres hilfreiches Tool soll an dieser Stelle auch das <strong>Animations-Fenster <\/strong>erw\u00e4hnt werden. Damit k\u00f6nnen Animationen in verschiedenen Geschwindigkeiten abgespielt werden, wodurch fehlende Frames oder eine schlechte Performance deutlich sichtbar werden.<\/p>\n\n\n\n<p>Die genannten Tools k\u00f6nnen auf dieser Seite ausprobiert werden: <a href=\"https:\/\/niklassy.github.io\/animation-performance\/index.html\">https:\/\/niklassy.github.io\/animation-performance\/index.html<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Zusammenfassung<\/h2>\n\n\n\n<p>Zusammenfassend lassen sich folgende Kernaussagen zur erfolgreichen Entwicklung einer performanten Animation festhalten:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Am besten nur <strong>transform<\/strong> und <strong>opacity<\/strong> animieren.<\/li><li><strong>RequestAnimationFrame<\/strong> f\u00fcr JavaScript Animationen verwenden.<\/li><li><strong>Bedenken, dass weniger meist mehr ist.<\/strong><\/li><li><strong>Will-change<\/strong> nur als letzte M\u00f6glichkeit der Optimierung nutzen.<\/li><\/ul>\n\n\n\n<p>W\u00e4hrend des Prozesses der Entwicklung ist es au\u00dferdem wichtig, die Animationen auf verschiedenen und vor allem mobilen Endger\u00e4ten zu testen. Um zu testen, ob eine Animation optimal l\u00e4uft, bieten sich die Developer-Tools in Chrome an. Am wichtigsten sind hier die Fenster <strong>Rendering, Performance und Animations<\/strong>.<\/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:\/\/developers.google.com\/web\/fundamentals\/performance\/rendering\/simplify-paint-complexity-and-reduce-paint-areas\">https:\/\/developers.google.com\/web\/fundamentals\/performance\/rendering\/simplify-paint-complexity-and-reduce-paint-areas<\/a><\/li><li><a href=\"https:\/\/www.statista.com\/statistics\/277125\/share-of-website-traffic-coming-from-mobile-devices\/#:~:text=Mobile%20accounts%20for%20approximately%20half,since%20the%20beginning%20of%202017\">https:\/\/www.statista.com\/statistics\/277125\/share-of-website-traffic-coming-from-mobile-devices\/<\/a><\/li><li><a href=\"https:\/\/medium.com\/engineerbabu\/a-detailed-guide-to-css-animations-and-transitions-b544502c089c\">https:\/\/medium.com\/engineerbabu\/a-detailed-guide-to-css-animations-and-transitions-b544502c089c<\/a><\/li><li><a href=\"https:\/\/www.html5rocks.com\/en\/tutorials\/speed\/animations\/\">https:\/\/www.html5rocks.com\/en\/tutorials\/speed\/animations\/<\/a><\/li><li><a href=\"https:\/\/www.afasterweb.com\/2015\/08\/29\/what-the-jank\/\">https:\/\/www.afasterweb.com\/2015\/08\/29\/what-the-jank\/<\/a><\/li><li><a href=\"https:\/\/css-tricks.com\/css-animations-vs-web-animations-api\/\">https:\/\/css-tricks.com\/css-animations-vs-web-animations-api\/<\/a><\/li><li><a href=\"https:\/\/developers.google.com\/web\/fundamentals\/design-and-ux\/animations\/css-vs-javascript\">https:\/\/developers.google.com\/web\/fundamentals\/design-and-ux\/animations\/css-vs-javascript<\/a><\/li><li><a href=\"https:\/\/medium.com\/chegg\/performance-monitoring-in-css-animations-f11a21d0054f\">https:\/\/medium.com\/chegg\/performance-monitoring-in-css-animations-f11a21d0054f<\/a><\/li><li><a href=\"https:\/\/medium.com\/outsystems-experts\/how-to-achieve-60-fps-animations-with-css3-db7b98610108\">https:\/\/medium.com\/outsystems-experts\/how-to-achieve-60-fps-animations-with-css3-db7b98610108<\/a><\/li><li><a href=\"https:\/\/blog.gyrosco.pe\/smooth-css-animations-7d8ffc2c1d29\">https:\/\/blog.gyrosco.pe\/smooth-css-animations-7d8ffc2c1d29<\/a><\/li><li><a href=\"https:\/\/openclassrooms.com\/en\/courses\/5625816-create-modern-css-animations\/5995831-create-more-peformant-color-animations-using-the-css-opacity-property\">https:\/\/openclassrooms.com\/en\/courses\/5625816-create-modern-css-animations\/5995831-create-more-peformant-color-animations-using-the-css-opacity-property<\/a><\/li><\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Animationen sind sehr ansprechend und bringen User dazu, \u00fcber eine l\u00e4ngere Zeit auf einer Webseite zu bleiben oder von dort aus nach weiteren Informationen des Anbieters zu suchen. Aus diesem Grund ist es wichtig, dass sie ihre Funktion erf\u00fcllen und fl\u00fcssig laufen. Trotzdem st\u00f6\u00dft man immer wieder auf Animationen, die ruckeln und nicht gut performen. [&hellip;]<\/p>\n","protected":false},"author":1000,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[1,649,662],"tags":[],"ppma_author":[678],"class_list":["post-12187","post","type-post","status-publish","format-standard","hentry","category-allgemein","category-interactive-media","category-web-performance"],"aioseo_notices":[],"jetpack_featured_media_url":"","jetpack-related-posts":[{"id":21967,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2022\/01\/23\/neue-bildformate-im-vergleich\/","url_meta":{"origin":12187,"position":0},"title":"Neue Bildformate im Vergleich","author":"Regina Dietrich","date":"23. January 2022","format":false,"excerpt":"Bilder und andere Medienelemente gelten im Internet heute als selbstverst\u00e4ndlich. Wie aus dem HTTP Archive hervorgeht, generieren 99,9% aller Webseiten mindestens eine Anfrage f\u00fcr eine Bildressource und 95,9% enthalten mindestens ein <img>-Element [1]. Die restlichen 4% entfallen beispielsweise auf Favicons und Hintergrundbilder. F\u00fcr die breite Verwendung von Bildern gibt es\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\/01\/neue_bildformate_abbildung_06.webp?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2022\/01\/neue_bildformate_abbildung_06.webp?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2022\/01\/neue_bildformate_abbildung_06.webp?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2022\/01\/neue_bildformate_abbildung_06.webp?resize=700%2C400&ssl=1 2x"},"classes":[]},{"id":12717,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2021\/02\/28\/flutter-code-optimierung\/","url_meta":{"origin":12187,"position":1},"title":"Flutter Code Optimierung","author":"Rafael Janetzko","date":"28. February 2021","format":false,"excerpt":"Dieser Blogeintrag befasst sich mit Optimierungsm\u00f6glichkeiten des Flutter Frameworks. Innerhalb des Blogeintrag wird darauf eingegangen was Flutter ist, warum Applikationen optimiert werden sollen und die Vorgehensweise anhand von Beispielen erl\u00e4utert. Was ist Flutter? Flutter ist ein Framework von Google, welches auf den Programmiersprachen Dart, C, C++ basiert und zur Entwicklung\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\/02\/image5.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/image5.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/02\/image5.png?resize=525%2C300&ssl=1 1.5x"},"classes":[]},{"id":23834,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2023\/02\/01\/designing-for-performance\/","url_meta":{"origin":12187,"position":2},"title":"Designing for Performance","author":"Nadine Schuler","date":"1. February 2023","format":false,"excerpt":"Verbesserung der Performance\u00a0durch Optimierung der User Experience F\u00fcr ein besseres Lesegef\u00fchl wird in diesem Artikel das generische Maskulinum verwendet. Dies schlie\u00dft nat\u00fcrlich alle Geschlechter ein. 1. Einleitung \u201eIf you are making decisions about the look and feel of a website, you are making decisions that directly impact the performance of\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":"","width":0,"height":0},"classes":[]},{"id":26085,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2024\/02\/04\/optimierung-einer-vuejs-webseite-ladezeitenreduktion\/","url_meta":{"origin":12187,"position":3},"title":"Optimierung einer VueJS-Webseite: Ladezeitenreduktion","author":"Andreas Nicklaus","date":"4. February 2024","format":false,"excerpt":"Performance einer Webseite ist wichtig f\u00fcr Nutzer und Suchmaschinen, aber im Entwicklungsprozess nicht immer ersichtlich. Diese Hausarbeit untersucht M\u00f6glichkeiten zur automatischen Optimierung der Webperformance w\u00e4hrend der Entwicklung mit VueJS.","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\/2024\/02\/PageWeight.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2024\/02\/PageWeight.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2024\/02\/PageWeight.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2024\/02\/PageWeight.png?resize=700%2C400&ssl=1 2x"},"classes":[]},{"id":21753,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2021\/09\/26\/the-way-of-system-thinking\/","url_meta":{"origin":12187,"position":4},"title":"The Way of System Thinking &#8211; Was Systemdenken ausmacht","author":"Julia Grimm","date":"26. September 2021","format":false,"excerpt":"Ein Artikel von Jessica Hofmann und Julia Grimm In unserem Leben, egal ob im Privaten oder Beruf, m\u00fcssen wir Entscheidungen treffen. Diese Entscheidungen haben so gut wie immer eine Konsequenz. Bei allt\u00e4glichen Entscheidungen ist uns das oft nicht bewusst. Erst bei gro\u00dfen und schweren Entscheidungen sind wir Menschen uns dar\u00fcber\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\/systems-thinking.jpg?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/09\/systems-thinking.jpg?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/09\/systems-thinking.jpg?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/09\/systems-thinking.jpg?resize=700%2C400&ssl=1 2x"},"classes":[]},{"id":23945,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2023\/02\/05\/jamstack-und-astro-vor-und-nachteile-einer-serverless-architektur\/","url_meta":{"origin":12187,"position":5},"title":"JAMStack und Astro:  Vor- und Nachteile einer serverless Architektur","author":"zack walker","date":"5. February 2023","format":false,"excerpt":"Einleitung Seit den fr\u00fchen Tagen der Web-Entwicklung hat die Performance von Websites eine wichtige Rolle gespielt. W\u00e4hrend sich das Internet im Laufe der Jahre weiterentwickelt hat, haben sich auch die Anforderungen an die Performance von Websites erh\u00f6ht. Benutzer erwarten eine schnelle und reibungslose Nutzererfahrung, unabh\u00e4ngig von der Gr\u00f6\u00dfe ihres Ger\u00e4ts\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-05-at-22.08.11.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-05-at-22.08.11.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/02\/Screenshot-2023-02-05-at-22.08.11.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-05-at-22.08.11.png?resize=700%2C400&ssl=1 2x"},"classes":[]}],"jetpack_sharing_enabled":true,"authors":[{"term_id":678,"user_id":1000,"is_guest":0,"slug":"nb119","display_name":"Niklas Brocker","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/d5d893f0b8025411e6ff7d5b8283a3a7ba65fd1314e81c351deb910fadb98d76?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\/12187","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\/1000"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/comments?post=12187"}],"version-history":[{"count":3,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/posts\/12187\/revisions"}],"predecessor-version":[{"id":12194,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/posts\/12187\/revisions\/12194"}],"wp:attachment":[{"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/media?parent=12187"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/categories?post=12187"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/tags?post=12187"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/ppma_author?post=12187"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}