Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.

Aber schnell! Top HTML5 Performance Tipps für Hybrid- und Web-Apps

1 109 vues

Publié le

HTML5 ist langsam, oder? Nein, in der Tat zeigt sich die grundlegende Geschwindigkeit von Cross-Plattform-HTML5-Anwendungen heutzutage in einem sehr positiven Licht. Es gibt aber doch ein paar Fallstricke, in denen sich der Entwickler schnell verfängt, wenn er nicht auf ein paar Punkte achtet. Der Vortrag geht zuerst auf die Vorgehensweise der Performancemessung ein. Anschließend werden die Top Performance-Tipps gezeigt, um nochmal einen ordentlichen Schub an Power herausholen zu können. Lassen Sie uns Gas geben!

Publié dans : Logiciels
  • Soyez le premier à commenter

Aber schnell! Top HTML5 Performance Tipps für Hybrid- und Web-Apps

  1. 1. Aber schnell! Performanceaspekte in Cross-Plattform-HTML5- Anwendungen Gregor Biswanger | CEO von CleverSocial.de, Freier Dozent, Berater, Trainer und Autor about.me/gregor.biswanger
  2. 2. Bitte warten… Sprecher wird geladen…
  3. 3. Über mich  Gründer von CleverSocial.de  Freier Dozent, Berater und Trainer  Schwerpunkte .NET-Architektur, Agile Prozesse, XAML, Web und Cloud  Technologieberater für die Intel Developer Zone  Sprecher auf Konferenzen und User Groups  Freier Autor für heise.de, dotnetpro, WindowsDeveloper und viele weitere Fachmagazine  Video-Trainer bei video2brain und Microsoft Gregor Biswanger Microsoft MVP, Intel Black Belt & Intel Software Innovator dotnet-blog.net about.me/gregor.biswanger
  4. 4. Unsere gemeinsame Reise  Performance messen  Welche Probleme gibt es bei Hybrid-Apps  Wie funktioniert der Browser  Zahlreiche Performance-Tipps für Web-Entwickler
  5. 5. HTML5 ist langsam?
  6. 6. Nein, das stimmt nicht!
  7. 7. Was genau bedeutet schnell?
  8. 8. 100 ms ist ein gutes und realistisches Ziel Das ist unser Ziel!
  9. 9. Was ist Apache Cordova? Wie Hybrid-App Entwicklung mit HTML5?
  10. 10. Die Lösung: Hybrid-Apps mit Apache Cordova  Cordova ist ein JavaScript-Framework für lokal installierbare WebApps auf mobilen Endgeräten  Ist Open-Source und liegt auf GitHub  Unterstützte Plattformen: iOS, Android, LG webOS, Symbian OS, BlackBerry, Tizen, Firefox OS, Windows Phone, Windows 8  Features  Zugriff auf Sensoren  Plattformspezifische Funktionen (Notifications)  Zugriff auf Kontakte  Zugriff auf lokale Dateien  Cordova bietet kein UI Framework! cordova.apache.org
  11. 11. Der Cordova Build Cloud Compiler JS CSS HTML oder AppsWWW Projekt Local Compiler
  12. 12. Plattform (Betriebssystem) Native App (Android, WP, iOS) WebView (Browser) Hybrid-App Architektur WWWProjekt Frontend – HTML5 und CSS (Twitter Bootstrap) Backend - JavaScript (Apache Cordova)
  13. 13. Plattform (Betriebssystem) Native App (Android, WP, iOS) WebView (Browser) Cordova Plugin Architektur Frontend – HTML5 und CSS (Twitter Bootstrap) Backend - JavaScript (Apache Cordova) API Sensoren (Hardware) Plugin Plugin Android und Windows Phone benötigen Zugriffsberechtigungen und/oder Hardware nicht vorhanden.
  14. 14. Wie können wir die Performance testen?
  15. 15. Wichtig! Am besten auf alten Geräten testen…
  16. 16. Dann bringt ein Test auf neuer Hardware…
  17. 17. Okay, also eine Web-Browser-App im Vollbildmodus…
  18. 18. Problem! !=
  19. 19. Das Crosswalk Project  Open-Source (BSD Lizenz)  Embedded Chrome Chromium  Für Android und Tizen  Ab Android Version 4  Ab Tizen Version 3  Nachteil: Paketgröße circa 15-20 MB  An Crosswalk Lite wird aktuell gearbeitet  Paketgröße circa 7 MB crosswalk-project.org
  20. 20. Kostenlos Builden via Intel XDK xdk.intel.com
  21. 21. WKWebView  Cordova Plug-In  Ersetzt die Standard UIWebView  Ab iOS 8 verfügbar
  22. 22. Einbinden ganz einfach via Cordova Plug-In  Über die Plugin ID:  com.telerik.plugins.wkwebview Beim Intel XDK ganz einfach über den Plug-In Manager
  23. 23. Dann müssen wir analysieren, wie ein Browser unter der Haube arbeitet…
  24. 24. Erst wird alles geladen…
  25. 25. BÖSE! <!DOCTYPE html> <html> <head> <link rel="stylesheet" href="css/bootstrap.css"> <script src="js/jquery.js"></script> <script src="js/bootstrap.js"></script> </head> <body> ... </body> </html>
  26. 26. Gut…  <!DOCTYPE html> <html> <head> <link rel="stylesheet" href="css/bootstrap.css"> </head> <body> ... <script src="js/jquery.js"></script> <script src="js/bootstrap.js"></script> </body> </html>
  27. 27. Get auch für HTML5 Browser mit async-Tag… <!DOCTYPE html> <html> <head> <link rel="stylesheet" href="css/bootstrap.css"> <script async src="js/jquery.js"></script> <script async src="js/bootstrap.js"></script> </head> <body> ... </body> </html>
  28. 28. Unterschiede bei der Script-Ausführung
  29. 29. Auch BÖSE! <body> <style> .item { color: white; } <style> <div class="item" style="background-color: red;"></div> </body>
  30. 30. Die richtige Reihenfolge der HTML-Struktur  CSS-Code immer beim Header unterbringen  Vermeide Embedded und Inline Styles  JavaScript-Code immer am Ende vom Body  Ab HTML5 Hilft der async-Tag für die Verarbeitung zum richtigen Zeitpunkt
  31. 31. Und wieder BÖSE! <!DOCTYPE html> <html> <head> <link rel="stylesheet" href="css/bootstrap.css"> </head> <body> ... <script src="js/jquery.js"></script> <script src="js/bootstrap.js"></script> </body> </html>
  32. 32. Gut…  <!DOCTYPE html> <html> <head> <link rel="stylesheet" href="css/bootstrap.min.css"> </head> <body> ... <script src="js/jquery.min.js"></script> <script src="js/bootstrap.min.js"></script> </body> </html>
  33. 33. Minifying von Dateien  Das Laden der Daten ist kürzer  CSS-Styles werden schneller gerendert  App-Paket wird kompakter
  34. 34. Falls man Ressourcen nicht lokal ablegen kann, dann lieber CDN nutzen… <!DOCTYPE html> <html> <head> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/... ...3.3.5/css/bootstrap.min.css"> </head> <body> ... <script src="https://ajax.googleapis.com/ajax/... ...libs/jquery/1.11.3/jquery.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/... ...bootstrap/3.3.5/js/bootstrap.min.js"></script> </body> </html>
  35. 35. Das Content Delivery Network (CDN)  Ressourcen werden automatisch gecached  jsdelivr.com
  36. 36. Quiz: Welcher Download ist schneller? a) 10 x 1 KB Große Bilddateien b) 1 x 10 KB Große Bilddatei
  37. 37. Die Lösung ist B  Die HTTP-Spezifikation kann nur wenige parallele Downloadvorgänge ausführen.
  38. 38. CSS Sprite Bilder verwenden Icons.png: 1 x 13 KB Große Datei  Alle nötigen Grafiken auf einem Bild enthalten  Kommt ursprünglich aus der Spieleentwicklung  Ein Download für alle nötigen Grafiken  Austausch von Grafiken ohne Verzögerung (Flackern)
  39. 39. CSS Sprite Bilder verwenden 240px 40px 40px Scenario #1 – Multiple Files Scenario #2 - Image Sprite 40px 6 Bilder 6 Verbindungen 96 KB 1 Bild 1 Verbindung 21 KB 40px40px40px40px40px40px
  40. 40. BÖSE! .iconGlas { width: 20px; height: 20px; background-image: url(img/glas.png); } .iconHeart { width: 20px; height: 20px; background-image: url(img/heart.png); }
  41. 41. Gut…  .spriteIcon { width: 20px; height: 20px; background-image: url(img/icons.png); } .spriteIconGlas { background-position: 0 0; } .spriteIconHeart { background-position: -90px 0; }
  42. 42. Quiz: Was ist besser? JPEG oder PNG? a) JPEG b) PNG c) Je nach Anwendungsfall
  43. 43. Die Lösung ist C  JPEG für Fotografien: Landschaften oder Gesichter  PNG: Logo, Diagramme, Screenshots (verbraucht mehr Memory und Decodierung)  Bitte vermeiden: GIF, TIFF, BMP, WebP, etc.
  44. 44. Bilder vom Download bis zur Anzeige
  45. 45. Okay, die Daten wurden geladen. Was steckt noch hinter dem Browser?
  46. 46. Zwei „Threads“ teilen sich die Arbeit… Main Thread  Er führt den JavaScript-Code aus  Berechnet HTML-Elemente  Gemeinsam mit CSS-Styles (Layouten)  Verarbeitet die Elemente in Bitmaps Composition Thread  Zeichnet Bitmaps mit der GPU (Circa 60 mal die Sekunde)  Berechnung der Sichtbaren Elemente  Berechnung für die Bewegung von Elementen (Scrollen) Arbeit für dich Fertig! Überprüf mal bitte… Hier mal bitte Zeichnen… NEIN Nur wenn ich gerade nichts zu tun hab!
  47. 47. Web Runtime Architektur Networking / Cache Parsers 1 2 7 43 8 9 5 6 DOM Tree Formatting Layout Painting 1 2 7 43 8 9 5 6 Display Tree Compositing DOM API & Capabilities JavaScript CSS Cascade
  48. 48. Die meiste Arbeit steckt beim „Reflow“
  49. 49. Okay, verstanden.. Jetzt sind wir bereit für weitere Top Performance-Tipps!
  50. 50. Gefährliche Animation! Warum? @keyframes drive { from { margin-top: 0px; margin-left: -400; } to { margin-top: 50px; margin-left: 200px; } }
  51. 51. Erst recht, BÖSE! $("#element").animate({ "margin-left": "200px", "margin-top": "50px" }, 2000);
  52. 52. Finger weg von JQuery!
  53. 53. Perfekt! So geht’s ab…  @keyframes drive { from { transform: translate(-400px, 0px); } to { transform: translate(200px, 50px); } }
  54. 54. Animationen GPU beschleunigen mit CSS-Transitions  Compositor-Thread übernimmt die Animation einmalig, der Rest wird von der GPU verarbeitet  Tipp: Anstatt display:none oder visibility:hidden, mit Transitions die Elemente außerhalb vom Screen ablegen. Das ist 3-5 x schneller.
  55. 55. Waaahhh! -ms-gradient(linear, 50% 50%, 0% 34%, from(#666666), to(#666666), color-stop(.3,#333333)) -webkit-gradient(linear, 50% 50%, 0% 34%, from(#666666), to(#666666), color-stop(.3,#333333)) -moz-gradient(linear, 50% 50%, 0% 34%, from(#666666), to(#666666), color-stop(.3,#333333)) gradient(linear, 50% 50%, 0% 34%, from(#666666), to(#666666), color-stop(.3,#333333))
  56. 56. Ein Herz für JPEG! <3
  57. 57. Verwende Bilder anstatt CSS3 Gradients oder Border Radius  Bilder werden immer direkt von der GPU verarbeitet  Am besten JPEG verwenden
  58. 58. EventListener können zu unangenehmen Events führen function createElements() { for (var i = 0; i < 100; ++i) { var xBtn = document.createElement('button'); xBtn.setAttribute('value', 'AA'); xBtn.addEventListener('click', hi, false); containerDiv.appendChild(xBtn); xBtn = null; } } function clearElements() { containerDiv.innerHTML = ""; }
  59. 59. Unnötige EventListener wieder abbestellen function createElements() { for (var i = 0; i < 100; ++i) { var xBtn = document.createElement('button'); xBtn.setAttribute('value', 'AA'); xBtn.addEventListener('click', hi, false); containerDiv.appendChild(xBtn); xBtn = null; } } function clearElements() { var els = containerDiv.childNodes; for (var i = 0; i < els.length; i++) { els[i].removeEventListener('click', hi, false); containerDiv.removeChild(els[i]); } }
  60. 60. Zuviel des Guten… for (i = 0; i < 100; i++){ img[i].addEventListener("click", function clickListener(e) { var clickedItem = e.target.id; alert("Hello " + clickedItem); }); }
  61. 61. Besser: Bubbling Events nutzen var theParent = document.querySelector("#theDude"); theParent.addEventListener("click", doSomething, false); function doSomething(e) { if (e.target !== e.currentTarget) { var clickedItem = e.target.id; alert("Hello " + clickedItem); } e.stopPropagation(); }
  62. 62. Best Practices für EventListener  Minimiere unnötige Events  Teile Events übergreifend wenn möglich
  63. 63. Der Timer vom Performanceteufel… setInterval(function() { // Mach irgendwas... }, 2000);
  64. 64. Im Einklang, mit dem Powerengel… var start = null; function step(timestamp) { if (!start) start = timestamp; var progress = timestamp - start; // Mach irgendwas... if (progress < 2000) { window.requestAnimationFrame(step); } } window.requestAnimationFrame(step);
  65. 65. Am Rendering festhalten  Timer unterbricht den Standard Prozess und sorgt für einen Reflow  window.requestAnimationFrame hängt direkt am Render- Prozess und ist somit im Einklang vom Standard Prozess
  66. 66. Quiz: Welche Variable bekommt den schnellsten Zugriff? var a = 1; var b = "ich"; var c = 0.1; var d = 0x1;
  67. 67. Richtig ist A var a = 1; var b = "ich"; var c = 0.1; var d = 0x1; STACK 0x00000003a: 0x005e4148b: 0x005e4160c: String “ich” Number 0.1 Number 0x1 0x005e4170d: HEAP 0x005e4148: 0…01001000 0x03 represents 1: 0…00000011
  68. 68. Number in JavaScript  Alle Zahlen in JavaScript sind IEEE 64-Bit floating numbers  Gute für den flexiblen Einsatz  Eine Performance Herausforderung 31bits 31-bit (tagged) Integers 1bit 1 31bits Object pointer 1bit 0 32bits 32bits Floats 32-bit Integers STACK HEAP FIXE LÄNGE, SCHNELLER ZUGRIFF VARIABLE LÄNGE, LANGSAMER ZUGRIFF Boxed
  69. 69. Best Practices für Number  Verwende eine 31-Bit Zahl wenn möglich  Verwende nur floats wenn nötig
  70. 70. Böses Array! Aber warum? var bad = new Array(); bad[0] = 1; bad[1] = 5.6; bad[2] = "Will nicht böse sein";
  71. 71. Es entstehen Kopien im Speicher und Konvertierungen var bad = new Array(); bad[0] = 1; bad[1] = 5.6; bad[2] = "Will nicht böse sein"; Type: Int Array 1 Type: Float Array Type: Var Array 1 2.3 “Will..” 1 5.6
  72. 72. Immer noch Schmerzen! Aber warum? var bad = new Array(); bad[0] = 1; bad[1] = 5.6; bad[2] = "Will nicht böse sein";
  73. 73. Pre-allocate Arrays var bad = new Array(); bad[0] = 1; bad[1] = 5.6; bad[2] = "Will nicht böse sein"; var bad = new Array(100); bad[0] = 1; bad[1] = 5.6; bad[2] = "Will nicht böse sein"; 0 ? ?+1 ?? Langsam Schnell …0 100
  74. 74. Verwende Typed Arrays wenn möglich var value = 5; var a = new Float64Array(100); a[0] = value; // 5.0 - no tagging required a[1] = value / 2; // 2.5 - no boxing required a[2] = "text"; // 0.0 var a = new Int32Array(100); a[0] = value; // 5 - no tagging required a[1] = value / 2; // 2 - no tagging required a[2] = "text"; // 0
  75. 75. Tödliche Schleifen… var a = new Array(100); var total = 0; for (var item in a) { total += item; }; a.forEach(function(item){ total += item; }); for (var i = 0; i < a.length; i++) { total += a[i]; }
  76. 76. Nutze eine Schleife effizient var a = new Array(100); var total = 0; var cachedLength = a.length; for (var i = 0; i < cachedLength; i++) { total += a[i]; }
  77. 77. Best Practices für Arrays  Gebe eine fixe Größe mit  Verwende Typed Arrays wenn möglich  Nutze eine Schleife effizient
  78. 78. The DOOM of DOM ... //for each rotation document.getElementById("myDiv").classList.remove(oldClass) document.getElementById("myDiv").classList.add(newClass) ... JavaScript DOM
  79. 79. DOM Kommunikation findet jetzt nur einmalig statt var element = document.getElementById(elID).classList; //for each rotation element.remove(oldClass) element.add(newClass) ... JavaScript DOM
  80. 80. DOM Kommunikation findet jetzt nur einmalig statt var elems = ['img1.jpg', … 'img6.jpg']; var fragment = document.createDocumentFragment(); for (var i=0; i < elems.length; i++) { var newNode = document.createElement('img'); newNode.setAttribute('src', elems[i]); fragment.appendChild(newNode); } target.appendChild(fragment); JavaScript DOM
  81. 81. Mhhh.. Was ist daran schlimm? this.boardSize = document.getElementById("benchmarkBox").value; for (var i = 0; i < this.boardSize; i++) { //this.boardSize is “25” for (var j = 0; j < this.boardSize; j++) { //this.boardSize is “25” ... } }
  82. 82. DOM-Elemente sind immer ein String. Ein direktes parseInt ist 25% schneller! this.boardSize = parseInt(document.getElementById("benchmarkBox").value); for (var i = 0; i < this.boardSize; i++) { //this.boardSize is 25 for (var j = 0; j < this.boardSize; j++) { //this.boardSize is 25 ... } }
  83. 83. Wollt ihr noch das beste zum Schluss?
  84. 84. Touchverzögerung entfernen mit FastClick  Bei Klick oder Touch findet eine 300 ms Verzögerung statt  Entfernen mit FastClick  github.com/ftlabs/fastclick
  85. 85. Vieeeelll besser…. <script src='/path/to/fastclick.js'></script> ... document.addEventListener('DOMContentLoaded', function() { FastClick.attach(document.body); }, false);
  86. 86. Fazit 1 von 3  Die UI ist für den Benutzer schnell, wenn sie unter 100 ms reagiert  Setze moderne WebViews für die Hybrid-Apps ein  Crosswalk und WKWebView  Verwende eine saubere HTML-Struktur  Regeln für Head und Body beachten  Daten müssen schnell bereitstehen  Styles und Skripte direkt ins App-Paket legen
  87. 87. Fazit 2 von 3  Verwende die GPU so viel wie nur möglich  Bilder anstatt CSS Features  Animationen via transform: translate3D  Auf JQuery verzichten  Natives JavaScript nutzen  Gehe sparsam und durchdacht mit Events um  Hänge dich an den Render-Prozess für eine Timer-Funktion  window.requestAnimationFrame
  88. 88. Fazit 3 von 3  Erspare JavaScript unnötige Arbeit mit Konvertierungen  Nutze JavaScript Arrays effektiv  Verwende Schleifen  Gehe beachtlich mit dem DOM Zugriff um  Unnötige „Reflows“ ersparen  Touchverzögerung entfernen
  89. 89. Kostenloses Video-Training für alle! http://goo.gl/BQb8ul
  90. 90. Kostenloser Artikel auf Entwickler.de für alle! https://goo.gl/vwWysC
  91. 91. FRAGEN?
  92. 92. http://about.me/Gregor.Biswanger Ich freue mich auf Feedback! Vielen Dank!

×