{"id":6362,"date":"2020-03-07T13:54:48","date_gmt":"2020-03-07T12:54:48","guid":{"rendered":"https:\/\/www.thetawelle.de\/?p=6362"},"modified":"2020-03-08T13:07:29","modified_gmt":"2020-03-08T12:07:29","slug":"esp32-esp8266-optimizing-the-hell-out-of-espasyncwebserver","status":"publish","type":"post","link":"https:\/\/www.thetawelle.de\/?p=6362","title":{"rendered":"ESP32\/ESP8266: Optimizing the hell out of ESPAsyncWebServer"},"content":{"rendered":"<p>Das sch\u00f6ne an dem Microcontroller ist ja, dass man einen kleinen WebServer darauf laufen lassen kann. Damit hat man eine tolle M\u00f6glichkeit ein kleines aber <strong>immer verf\u00fcgbares User Interface (UI)<\/strong> bereitzustellen, das mit fast allen modernen Ger\u00e4ten die einen Webbrowser haben (Tablet, Smartphone, Laptop, PC) sofort funktioniert.<\/p>\n<h2>WebServer in klein<\/h2>\n<p><a href=\"https:\/\/www.thetawelle.de\/wp-upload\/exception_decoder_menu.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.thetawelle.de\/wp-upload\/exception_decoder_menu-192x300.png\" alt=\"Exception Decoder Menu\" width=\"192\" height=\"300\" class=\"alignright size-medium wp-image-6372\" srcset=\"https:\/\/www.thetawelle.de\/wp-upload\/exception_decoder_menu-192x300.png 192w, https:\/\/www.thetawelle.de\/wp-upload\/exception_decoder_menu.png 414w\" sizes=\"auto, (max-width: 192px) 85vw, 192px\" \/><\/a>Was man jedoch schnell vergisst, wenn man zuvor schon WebApplications mit WebServern wie <strong>nginx<\/strong> oder <strong>Apache<\/strong> ausgeliefert hat, ist der Ressourcenbedarf von so einem Server. Der Microcontroller ist halt klein deshalb ja auch &#8222;Micro&#8220;, hat <strong>wenig Speicher<\/strong> und <strong>wenig CPU-Zyklen<\/strong> die er f\u00fcr sowas entbehren kann.<\/p>\n<p>Die Kunst liegt also in der Beschr\u00e4nkung. Doch das f\u00e4llt sauschwer, wenn man erstmal einen gewissen Anspruch an seine Webseiten hatte. Niemand mag gern zur\u00fcck in die Steinzeit und eine Webseite bauen z.B. ohne Stylsheets. Klar, das geht, sieht aber so schlimm aus und funktioniert auf dem Smartphone z.B. so gar nicht.<\/p>\n<p>Zun\u00e4chst habe ich den klassischen Weg zur Gestaltung meiner Webseite gew\u00e4hlt, ich hab HTML geschrieben mit Bildern darin und JavaScript das dynamisch Bilder austauscht und platziert, ich habe CSS geschrieben, das Bilder zur Gestaltung einsetzt. Es sieht wundersch\u00f6n aus auf dem Desktop, aber&#8230; <strong>es crasht den WebServer des Microcontrollers<\/strong>. Da nutzt dann das ganze tolle Design auch nichts, wenn es letztlich nicht funktioniert.<\/p>\n<p><strong>Und ich habe zig Crashes gehabt<\/strong>. Ich habe mir m\u00fchsam den <strong>Arduino ESP8266\/ESP32 Exception Stack Trace Decoder<\/strong> in der Arduino IDE installiert (<a href=\"https:\/\/github.com\/me-no-dev\/EspExceptionDecoder\">Anleitung<\/a>). Ein dekodierter Stacktrace sieht dann z.B. so aus:<\/p>\n<p><a href=\"https:\/\/www.thetawelle.de\/wp-upload\/stack_trace_decoded_crash.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.thetawelle.de\/wp-upload\/stack_trace_decoded_crash-1024x585.png\" alt=\"\" width=\"840\" height=\"480\" class=\"aligncenter size-large wp-image-6370\" srcset=\"https:\/\/www.thetawelle.de\/wp-upload\/stack_trace_decoded_crash-1024x585.png 1024w, https:\/\/www.thetawelle.de\/wp-upload\/stack_trace_decoded_crash-300x171.png 300w, https:\/\/www.thetawelle.de\/wp-upload\/stack_trace_decoded_crash-768x439.png 768w, https:\/\/www.thetawelle.de\/wp-upload\/stack_trace_decoded_crash.png 1169w\" sizes=\"auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><\/a><\/p>\n<p>Da sieht man, dass es im konkreten Fall eher ein Speicherproblem ist bei diesem Crash, weil eine <code>alloc<\/code> Funktion involviert ist. Aber viele andere Crashes sind eben anderer Natur.<\/p>\n<h2>Optimizing the hell out of it<\/h2>\n<p>Dann beginnt man zu begreifen und optimiert. Was kann man alles tun um zu optimieren? Anfangs dachte ich die Dateigr\u00f6\u00dfe w\u00e4re der Bottleneck des Microcontrollers. Ich hab die JS, CSS und HTML Dateien mittels <strong>GZIP<\/strong> komprimiert und mit dem <strong>content-type\/gzip<\/strong> im Header ausliefern lassen. Das reduziert auch die Menge an Daten hervorragend. Oft wird nur noch ein Zehntel  der Daten \u00fcbertragen, was die Auslieferung selbst deutlich schneller macht.<\/p>\n<p>Doch die Dateigr\u00f6\u00dfe ist gar nicht das Problem beim ESPAsyncWebServer. Das eigentliche Limit ist, dass der <strong>nur maximal 3 bis 4 Requests &#8222;gleichzeitig&#8220;<\/strong> bzw. parallel bearbeiten kann. Der Rest der Requests h\u00e4ngt dann einfach und wartet ewig auf Antwort und wird verworfen oder f\u00fchrt zu einer Blockade des Webservers und einem sp\u00e4teren Crash. Es hat auch <strong>nichts<\/strong> damit zu tun, dass das <strong>SPIFFS Filesystem<\/strong> eine Obergrenze an <strong>gleichzeitig ge\u00f6ffneten Files<\/strong> hat wie mir ein Entwickler des ESPAsyncWebServer versicherte. Und darauf nun eine passende Antwort bzw. Optimierung zu finden ist gar nicht so einfach gewesen.<\/p>\n<p>Klar, man kann das CSS und das JS alles mit in das HTML-file kippen, aber dann wird es schon arg un\u00fcbersichtlich. Und des weiteren bleibt das Problem mit den vielen kleinen Icons bestehen, die alle je einen Request ausl\u00f6sen. Das kostet Zeit und trifft auf die Limitierung des Webservers. Das Hauptziel kann also zun\u00e4chst nur sein die Anzahl initialer Requests (also der Requests die ben\u00f6tigt werden die Seite einmal komplett zu laden) zu minimieren. Und zwar sollte das so passieren, dass man unterhalb des Limits bleibt von max. 3-4 gleichzeitig eintreffenden Requests. Das ist nat\u00fcrlich ein Limit, dass sobald mehr als ein Nutzer gleichzeitig auf das UI zugreift bereits zu Problemen f\u00fchren kann. Es ist schade, dass die Entwickler von ESPAsyncWebServer das nicht vorhergesehen haben und entsprechend <strong>zuviele Requests<\/strong> schlicht und einfach mit <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTTP\/Status\">Fehler 503<\/a> ablehnen sondern stattdessen den Server crashen lassen. Aber vielleicht gibt es auch einen Grund der mir nicht begreiflich ist derzeit.<\/p>\n<h2>The Magic of Data-URI&#8217;s<\/h2>\n<p>Hier kommt dann jetzt eine <strong>Optimierungsstrategie<\/strong> zum Zuge, die auch bei &#8222;normalen&#8220; Webseiten zu krass <strong>verbesserter User Experience (UX)<\/strong> f\u00fchren kann. Das Einbetten der Bilddaten als sogenannte <strong>Daten-URI<\/strong>. Was ist das eine <a href=\"https:\/\/www.wikiwand.com\/en\/Data_URI_scheme\">Daten-URI<\/a>?<\/p>\n<blockquote><p>The data URI scheme is a uniform resource identifier (URI) scheme that provides a way to include data in-line in Web pages as if they were external resources. It is a form of file literal or here document. This technique allows normally separate elements such as images and style sheets to be fetched in a single Hypertext Transfer Protocol (HTTP) request [\u2026]<\/p><\/blockquote>\n<p>Das schreibt die Wikipedia dazu. und auf <a href=\"https:\/\/css-tricks.com\/data-uris\/\">dieser Webseite<\/a> hei\u00dft es <strong>&#8222;You can embed the image data directly into the document with data URIs.&#8220;<\/strong> und genau das ist eine sehr sinnvolle Sache. Einerseits wird das Dokument (HTML, JS, CSS) in das man diese Daten dann einbettet zwar etwas gr\u00f6\u00dfer, aber daf\u00fcr unterbleiben Requests f\u00fcr Bilddaten komplett.<\/p>\n<p>Aus folgendem Code f\u00fcr ein Favicon als <strong>Meta-Link im Header<\/strong> in HTML&#8230;<\/p>\n<pre class=\"brush: xml; gutter: true; title: Source\/Snippet; toolbar: true; notranslate\" title=\"Source\/Snippet\">\r\n&lt;link rel='icon' type='image\/png' sizes='32x32' href='fav-icon-32x32.png'&gt;\r\n<\/pre>\n<p>&#8230;wird folgender Code als <strong>eingebettete URI<\/strong>:<\/p>\n<pre class=\"brush: xml; gutter: true; title: Source\/Snippet; toolbar: true; notranslate\" title=\"Source\/Snippet\">\r\n&lt;link rel='icon' type='image\/png' sizes='32x32' href='data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA9tpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw\/eHBhY2tldCBiZWdpbj0i77u\/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wUmlnaHRzPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvcmlnaHRzLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcFJpZ2h0czpNYXJrZWQ9IkZhbHNlIiB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9ImFkb2JlOmRvY2lkOnBob3Rvc2hvcDowMzhmMTQ5NC1lNGJkLTExZTEtOGQ4MC1jYjVjZDBjYjc4N2QiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6RDJDODA5ODk0RjU1MTFFQThBRjNFQkJENEQ2MUU4MDUiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6RDJDODA5ODg0RjU1MTFFQThBRjNFQkJENEQ2MUU4MDUiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjAyODAxMTc0MDcyMDY4MTE4MjJBRkREMjVGOEM5MDBBIiBzdFJlZjpkb2N1bWVudElEPSJhZG9iZTpkb2NpZDpwaG90b3Nob3A6MDM4ZjE0OTQtZTRiZC0xMWUxLThkODAtY2I1Y2QwY2I3ODdkIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+NRaoWgAAB\/5JREFUeNqMV2mInGcd\/z3vNcfOtTPZM5tjm2MTSHMQ09aA1dS0EE1oTT3QIvlSKYpBoVKoFfzQUPSLBbEIaoul6rdApbartQbEYGM0lhhr27jm2GN2Z2fnvt7reV9\/72Q22c0xk2f5MTP7\/t\/\/fT3iyJEjWHEGiCeJw8QWIknohFgmMFUVuudB83346HkCEoeoEFPEW8QviIVlAmUF8SPEX4kXiP0dZYxl4U5H8ImzZ7CnuASLv9sSfAFHKnAJKZWbFRAdHgGvjxPPd2R8dplA63weJN7oEN9qhhDImCYyVgv9EQuGLtuCffKP6C7SEROeJmBLFYVKGEJ09c048VviUeLNQIE1xMt3Eh6clqLh6\/kL2CdzsLar8Glo09TQtDXcu6WA7xw9h1rSwIdzaZx48X6kUi0oKkN0Zz3UTij2qBMTE9\/il6PdVKZIzEbjuNCfwcS2MoxhDzs3LWHfzkWMbmzAWOehqITQZLaM711EPhtDsxqCULp6IkY0tI4ruh6VpsyocRTVMBrDGgaSTWxbawH9AgUrBJn0sVRUUWfEE9uLEO+sg++Ja3Z2P4cDBTb3JAtSyfZRNXU889Yn8KWjF\/HorilkKxFU6h5ag0289oO9qOaiUDQPuqvAoPHS6NTBnc89WqfUuh7HUXH\/nhzSGROTf9yI8xfWoEAXbz44jcsXU5ib3ACnqUGncEUKNPfPw07YSP2JnlC8bqzjyopK6KKAgl1783jw4RloZHj1cgKnT40h1+dgrhLCxT9sgGeqUJl4Gq3PfyyHmU\/NQkjRi7Um2Ijuop8EUWDJJW0c+v4ZzOUjqOseFmIuKsUQKlEXJUtFk7myONrCjhd3I\/XfVC\/rb2lEXY9Ha6ymigunR3GVCkwPtrB0ZhilS0lkVVYBjTXrYQz+ZR1CpTDuQvY1BfygpXaD59O91NP1IWsaPvjJvZj+2xD7qg\/l1a1w\/pHBbNpCOaFBaaSw46UJRLMaFbbRkzehed6dVfUZ+\/D6OjLfeJ+13YdGSKLMRGvS3bXZPsx97z2oVgR6cT1UNwNhR\/lOBR89sQnNoRR2\/ug8PL27kzUpZRe\/+7BZfvm8gSXDQYWWVqiAZAXYBos8EoJRjkFxEhBUQGohFLc2qEQEWkmD9CQ90T3FxMGHD95CIVymHLPa75PtdqoWQph69t9Y3F+E9PsQXkrBC0Uho0MwSgmYg8MILcX5ZgKV7Ttx3zd\/jfT5S7CSkZ6NQBx46MAqCmFzqm2to344i\/jL41CrOrPZR2vEhBuTUNn\/i\/uiRArjr9ShmMw+RcXMFz4NreFjZPLvCOWK0Jom3+tZhgyBuzoEis1Bk2hh7oFFrDtJyywmmy1gTOsIeQYZS5S2J2DH1yP6n3N0v8vnNtwnhpiEJuL\/\/IBNKAY3EO72rgLNlaupVMasydhXLCbdcyXE3o9h4rshOGuYTEoQmirDsA1S3wlp\/hm+68K3OY7FIGNehuvW+ZtO5QiXarRnCG7xADcL+C0denkMWiUNj0yuPhlH\/6kstKqD+WMPwRodhc6YZx9\/DGrdpKAwMO9AlhXM3HeMLmRLblrI5Ca5S2grF6reHgjK0lV1OPERdpY03OE4Sg9sQuS9txGuV5H9ymMw5lnj4X4sHJqAni3B1oagTxWAWgK1tTugzjQYqjKS8o32MtM1CXfv3uVf3954Lv94Q3s+uclh9vJBCD8ON8HuRqZehNkfXgM1X4MMxvkSG8lcCY41AHW2CZQkZDHB51UEs9ktpTCcfgnJ1O\/guel2O785JPSAvLE+BktWbYhuYG37A4i9exVKix1Lvwx7bAtsNhelWYSyQAG21VZAyVWgNhUoiy16gOErOUzGGqtJIOR4fDZKtp+EjJynud4t4dBc112lgD2ymx+0emgzRp\/5NvTZLLO8ifmnn4czMMz9lq15SYdssO6zZJBX4VYGIBbJp+HBryWhizzC3Av7vQgS5UeQKnwRV8cfh6e4wYLZvRMOH\/9lm8hnHni1KqxYBIpFxtMWhFNnsgVLNb9XmeF5WlRjFZRVDCafhRZfpO4u4qXjiFvbkFaaSAoT9Ck+8lpsahK6b2DlQh8o4K7cCcTc4rVPtkCpax3nePByFNQi6TzdXZhn07kCv8rvTo1MGBYxw8orsBxtLiYfIkK7xhwOKy0LUzMx3tqKsrqEgpZneK\/PBzcYRgwo0jc6kbixh3UGlc+O4mUjRAoyO4S49yri2q\/gGUxEg3QxesiPsgfo7XvMQvwV7ggpfHX2FE4mfo7TsZN498oUXo\/9Bj\/MnOD7iWVptcAD\/1ulwO1mNq3y5yyGIod+7WmoygIcP81Rrdx0CZKdy4rBfcDAoFpElE1NccM4PnAMBaWAsBthI7se9iuBB4ILyb7b1qgImKlkm2GCWdDsPPTMWf6PTGQQntuPchlkOwVnmEscnu2peE4\/x+2atyupBwFdJn0zMOFnxNxtV2HB1ipHUJ4\/iz7jHaQyTzEqsbZSd2qxQa23hAWTfxuZXlHfpjiWpBfifVJbmYBBsv00MCNHfK1zNbuxyQsHbuPLTLB1GFNnYQfLqR\/qOVwshutw60EMu0k8l3oB\/zKmEPKN211anyKyy0GcJD5HTK8YCoi0DiNtHsQGWhzi+ng3a54tJA6YW3CodQ9e63sbl7UcS2\/V4h14+\/PE6207146tXflwpOONzxCbFGhBuuqCDd0TLu7qQt5xo2ib0H4hKPOg0i4Rv++EfHaZ9v8CDAAdk8qMFQmJHgAAAABJRU5ErkJggg=='&gt;\r\n<\/pre>\n<p>Der entscheidende Teil ist, dass man statt einer Hyperlink-URI eine Data-URI nutzt, die eben so ausschaut:<br \/>\n<code>data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAA<\/code><\/p>\n<p><a href=\"https:\/\/www.thetawelle.de\/wp-upload\/data_uri_chris_yip.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.thetawelle.de\/wp-upload\/data_uri_chris_yip-269x300.png\" alt=\"\" width=\"269\" height=\"300\" class=\"alignright size-medium wp-image-6365\" srcset=\"https:\/\/www.thetawelle.de\/wp-upload\/data_uri_chris_yip-269x300.png 269w, https:\/\/www.thetawelle.de\/wp-upload\/data_uri_chris_yip.png 396w\" sizes=\"auto, (max-width: 269px) 85vw, 269px\" \/><\/a>Als Werkzeug zur Umwandlung gibt es zahlreiche Online Tools daf\u00fcr, wie z.B. den <a href=\"https:\/\/websemantics.uk\/tools\/image-to-data-uri-converter\/\">Image to data-URI converter<\/a>. Dort kann man seine Grafikdateien umwandeln lassen. Es gibt auch apps z.B. f\u00fcr macOS den <a href=\"https:\/\/www.macupdate.com\/app\/mac\/46143\/data-uri-converter\">Data URI Converter<\/a> von Chris Yip.<br \/>\nMit dem richtigen Tool ist es jedenfalls schnell gemacht.<\/p>\n<h2>Ergebnis: Schnell, schneller, embedded Data-URI<\/h2>\n<p>Die Ergebnisse sprechen absolut f\u00fcr sich. Nachfolgend habe ich mit zwei Screenshots im Safari Browser festgehalten, die initialen Requests und deren Laufzeit und Datenumfang, die gegen den Controller gehen im zeitlichen Verlauf. Die Ergebnisse sind absolut eindeutig: Data-URI schl\u00e4gt den klassischen Weg um L\u00e4ngen.<\/p>\n<p><a href=\"https:\/\/www.thetawelle.de\/wp-upload\/webpage_image_normal_uri.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.thetawelle.de\/wp-upload\/webpage_image_normal_uri.png\" alt=\"\" width=\"987\" height=\"1080\" class=\"aligncenter size-full wp-image-6366\" srcset=\"https:\/\/www.thetawelle.de\/wp-upload\/webpage_image_normal_uri.png 987w, https:\/\/www.thetawelle.de\/wp-upload\/webpage_image_normal_uri-274x300.png 274w, https:\/\/www.thetawelle.de\/wp-upload\/webpage_image_normal_uri-936x1024.png 936w, https:\/\/www.thetawelle.de\/wp-upload\/webpage_image_normal_uri-768x840.png 768w\" sizes=\"auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><\/a><\/p>\n<p>Man erkennt sofort, dass nach dem Laden der initialen HTML Seite <code>core.html<\/code> weitere Requests ausgel\u00f6st werden, klar ist die <code>core.css<\/code> und <code>core.js<\/code> werden ben\u00f6tigt, um die Seite \u00fcberhaupt korrekt anzuzeigen. Aber allein schon die erste Seite auszuliefern ben\u00f6tigt 1,14 Sekunden Zeit, und dann wird es problematisch, da gleich <strong>f\u00fcnf weitere Requests<\/strong> losgehen <strong>gleichzeitig<\/strong>, unter anderem eben auch requests wegen Grafiken. Das schafft der Server eben manchmal nicht. Und dann sieht man auch noch, dass jedes Bild ca. 300 bis 700 Millisekunden Zeit ben\u00f6tigt, und das ist sehr lang!! Die gesamte Seite ist erst nach <strong>\u00fcber sechs Sekunden geladen<\/strong>.<\/p>\n<p><a href=\"https:\/\/www.thetawelle.de\/wp-upload\/webpage_inline_image_data_uri.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.thetawelle.de\/wp-upload\/webpage_inline_image_data_uri.png\" alt=\"\" width=\"985\" height=\"1073\" class=\"aligncenter size-full wp-image-6367\" srcset=\"https:\/\/www.thetawelle.de\/wp-upload\/webpage_inline_image_data_uri.png 985w, https:\/\/www.thetawelle.de\/wp-upload\/webpage_inline_image_data_uri-275x300.png 275w, https:\/\/www.thetawelle.de\/wp-upload\/webpage_inline_image_data_uri-940x1024.png 940w, https:\/\/www.thetawelle.de\/wp-upload\/webpage_inline_image_data_uri-768x837.png 768w\" sizes=\"auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><\/a><\/p>\n<p>Die gleiche Seite optimiert mit Data-URI&#8217;s verh\u00e4lt sich deutlich besser. Zwar wird der initiale Download der <code>core.html<\/code> um etwa 15KB gr\u00f6\u00dfer, interessanterweise aber kostet das kaum Zeit. Und der initiale Download f\u00fchrt zu lediglich zwei weiteren Requests f\u00fcr die <code>core.css<\/code> und <code>core.js<\/code>. Beide Dateien enthalten selbst wiederum ausschlie\u00dflich Data-URI&#8217;s und f\u00fchren somit zu keinen Folgerequests.<\/p>\n<p>Die Auswirkung ist enorm. Die Bilddaten sind nun in 10 bis 20 Millisekunden geladen statt wie vorher in 300 bis 700. Eine Verbesserung um Faktor zehn. Insgesamt ist die ganze Seite vollst\u00e4ndig geladen nach nur <strong>etwas \u00fcber zwei Sekunden<\/strong>. Das <strong>erspart satte 4 Sekunden Wartezeit<\/strong>.<\/p>\n<h2>Fazit<\/h2>\n<p>Wer Webseiten auf dem Microcontroller ausliefert, der sollte <strong>ausschlie\u00dflich inline Data-URI&#8217;s<\/strong> f\u00fcr grafische Inhalte verwenden und die Anzahl der Requests soweit wie m\u00f6glich senken. F\u00fcr mein Setup best\u00fcnde jetzt noch die Option auch die <code>core.css<\/code> und <code>core.js<\/code> in die <code>core.html<\/code> zu integrieren. Dann w\u00e4re nur <strong>noch eine gro\u00dfe Datei<\/strong> n\u00f6tig.<\/p>\n<p>Aus Gr\u00fcnden der Code-\u00dcbersicht sehe ich davon aber erstmal ab. Sollte es aber nochmal Probleme mit dem WebServer geben, dann kann ich hier gezielt weiter optimieren.<\/p>\n<p><small><strong>Why do I blog this?<\/strong> Das Problem des instabilen und st\u00e4ndig crashenden ESPAsyncWebServer hat mich einige endlos erscheinende Stunden des Debuggens gekostet. Weil ich auch einfach nicht wusste was den WebServer crasht und\/oder blockiert und Serial.print() statements haben nicht wesentlich geholfen. Ich hoffe es hilft anderen nicht in die gleiche Falle zu tappen. Sehr hilfreiche Hinweise zum Thema ESPAsyncWebServer habe ich \u00fcberigens im <a href=\"https:\/\/gitter.im\/me-no-dev\/ESPAsyncWebServer\">Diskussionsforum\/Chat<\/a> zu dem Server gefunden. Das hat mir sehr geholfen.<\/small><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Das sch\u00f6ne an dem Microcontroller ist ja, dass man einen kleinen WebServer darauf laufen lassen kann. Damit hat man eine tolle M\u00f6glichkeit ein kleines aber immer verf\u00fcgbares User Interface (UI) bereitzustellen, das mit fast allen modernen Ger\u00e4ten die einen Webbrowser haben (Tablet, Smartphone, Laptop, PC) sofort funktioniert. WebServer in klein Was man jedoch schnell vergisst, &hellip; <a href=\"https:\/\/www.thetawelle.de\/?p=6362\" class=\"more-link\"><span class=\"screen-reader-text\">\u201eESP32\/ESP8266: Optimizing the hell out of ESPAsyncWebServer\u201c <\/span>weiterlesen<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[17,88,80,9,68,4,114],"tags":[],"class_list":["post-6362","post","type-post","status-publish","format-standard","hentry","category-best-practice","category-coding","category-crazeekywf","category-studien","category-hardware","category-learning","category-microcontroller"],"_links":{"self":[{"href":"https:\/\/www.thetawelle.de\/index.php?rest_route=\/wp\/v2\/posts\/6362","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.thetawelle.de\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.thetawelle.de\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.thetawelle.de\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.thetawelle.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=6362"}],"version-history":[{"count":0,"href":"https:\/\/www.thetawelle.de\/index.php?rest_route=\/wp\/v2\/posts\/6362\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.thetawelle.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=6362"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.thetawelle.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=6362"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.thetawelle.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=6362"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}