Aber schnell!
Performanceaspekte in Cross-Plattform-HTML5-
Anwendungen
Gregor Biswanger | CEO von CleverSocial.de, Freier ...
Bitte warten… Sprecher wird geladen…
Über mich
 Gründer von CleverSocial.de
 Freier Dozent, Berater und Trainer
 Schwerpunkte .NET-Architektur, Agile Prozes...
Unsere gemeinsame Reise
 Performance messen
 Welche Probleme gibt es bei Hybrid-Apps
 Wie funktioniert der Browser
 Za...
HTML5 ist langsam?
Nein, das stimmt nicht!
Was genau bedeutet schnell?
100 ms ist ein gutes und realistisches Ziel
Das ist unser Ziel!
Was ist Apache Cordova?
Wie Hybrid-App Entwicklung mit HTML5?
Die Lösung: Hybrid-Apps mit Apache Cordova
 Cordova ist ein JavaScript-Framework für lokal installierbare WebApps
auf mob...
Der Cordova Build
Cloud Compiler
JS
CSS
HTML
oder
AppsWWW Projekt
Local Compiler
Plattform (Betriebssystem)
Native App (Android, WP, iOS)
WebView (Browser)
Hybrid-App Architektur
WWWProjekt
Frontend – HT...
Plattform (Betriebssystem)
Native App (Android, WP, iOS)
WebView (Browser)
Cordova Plugin Architektur
Frontend – HTML5 und...
Wie können wir die Performance testen?
Wichtig! Am besten auf alten Geräten testen…
Dann bringt ein Test auf neuer Hardware…
Okay, also eine Web-Browser-App im Vollbildmodus…
Problem!
!=
Das Crosswalk Project
 Open-Source (BSD Lizenz)
 Embedded Chrome Chromium
 Für Android und Tizen
 Ab Android Version 4...
Kostenlos Builden via Intel XDK
xdk.intel.com
WKWebView
 Cordova Plug-In
 Ersetzt die Standard
UIWebView
 Ab iOS 8 verfügbar
Einbinden ganz einfach via Cordova Plug-In
 Über die Plugin ID:
 com.telerik.plugins.wkwebview
Beim Intel XDK ganz einfa...
Dann müssen wir analysieren, wie ein Browser unter
der Haube arbeitet…
Erst wird alles geladen…
BÖSE!
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="css/bootstrap.css">
<script src="js/jquery.js"></script>
...
Gut… 
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="css/bootstrap.css">
</head>
<body>
...
<script src="js/j...
Get auch für HTML5 Browser mit async-Tag…
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="css/bootstrap.css">
<...
Unterschiede bei der Script-Ausführung
Auch BÖSE!
<body>
<style>
.item { color: white; }
<style>
<div class="item" style="background-color: red;"></div>
</body>
Die richtige Reihenfolge der HTML-Struktur
 CSS-Code immer beim Header unterbringen
 Vermeide Embedded und Inline Styles...
Und wieder BÖSE!
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="css/bootstrap.css">
</head>
<body>
...
<script...
Gut… 
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="css/bootstrap.min.css">
</head>
<body>
...
<script src="...
Minifying von Dateien
 Das Laden der Daten ist kürzer
 CSS-Styles werden schneller gerendert
 App-Paket wird kompakter
Falls man Ressourcen nicht lokal ablegen kann, dann
lieber CDN nutzen…
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet...
Das Content Delivery Network (CDN)
 Ressourcen werden automatisch gecached
 jsdelivr.com
Quiz: Welcher Download ist schneller?
a) 10 x 1 KB Große Bilddateien
b) 1 x 10 KB Große Bilddatei
Die Lösung ist B
 Die HTTP-Spezifikation kann nur wenige parallele
Downloadvorgänge ausführen.
CSS Sprite Bilder verwenden
Icons.png: 1 x 13 KB Große Datei
 Alle nötigen Grafiken auf
einem Bild enthalten
 Kommt ursp...
CSS Sprite Bilder verwenden
240px
40px
40px
Scenario #1 – Multiple Files Scenario #2 - Image Sprite
40px
6 Bilder
6 Verbin...
BÖSE!
.iconGlas {
width: 20px;
height: 20px;
background-image: url(img/glas.png);
}
.iconHeart {
width: 20px;
height: 20px...
Gut… 
.spriteIcon {
width: 20px;
height: 20px;
background-image: url(img/icons.png);
}
.spriteIconGlas {
background-posit...
Quiz: Was ist besser? JPEG oder PNG?
a) JPEG
b) PNG
c) Je nach Anwendungsfall
Die Lösung ist C
 JPEG für Fotografien: Landschaften oder Gesichter
 PNG: Logo, Diagramme, Screenshots (verbraucht mehr
...
Bilder vom Download bis zur Anzeige
Okay, die Daten wurden geladen. Was steckt noch
hinter dem Browser?
Zwei „Threads“ teilen sich die Arbeit…
Main Thread
 Er führt den JavaScript-Code aus
 Berechnet HTML-Elemente
 Gemeinsa...
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
D...
Die meiste Arbeit steckt beim „Reflow“
Okay, verstanden.. Jetzt sind wir bereit für weitere
Top Performance-Tipps!
Gefährliche Animation! Warum?
@keyframes drive {
from {
margin-top: 0px;
margin-left: -400;
}
to {
margin-top: 50px;
margi...
Erst recht, BÖSE!
$("#element").animate({
"margin-left": "200px",
"margin-top": "50px"
}, 2000);
Finger weg von JQuery!
Perfekt! So geht’s ab… 
@keyframes drive {
from {
transform: translate(-400px, 0px);
}
to {
transform: translate(200px, 5...
Animationen GPU beschleunigen mit CSS-Transitions
 Compositor-Thread übernimmt die Animation einmalig,
der Rest wird von ...
Waaahhh!
-ms-gradient(linear, 50% 50%, 0% 34%, from(#666666), to(#666666), color-stop(.3,#333333))
-webkit-gradient(linear...
Ein Herz für JPEG! <3
Verwende Bilder anstatt CSS3 Gradients oder
Border Radius
 Bilder werden immer direkt von der GPU verarbeitet
 Am besten...
EventListener können zu unangenehmen Events führen
function createElements() {
for (var i = 0; i < 100; ++i) {
var xBtn = ...
Unnötige EventListener wieder abbestellen
function createElements() {
for (var i = 0; i < 100; ++i) {
var xBtn = document....
Zuviel des Guten…
for (i = 0; i < 100; i++){
img[i].addEventListener("click", function clickListener(e) {
var clickedItem ...
Besser: Bubbling Events nutzen
var theParent = document.querySelector("#theDude");
theParent.addEventListener("click", doS...
Best Practices für EventListener
 Minimiere unnötige Events
 Teile Events übergreifend wenn möglich
Der Timer vom Performanceteufel…
setInterval(function() {
// Mach irgendwas...
}, 2000);
Im Einklang, mit dem Powerengel…
var start = null;
function step(timestamp) {
if (!start) start = timestamp;
var progress ...
Am Rendering festhalten
 Timer unterbricht den Standard Prozess und sorgt für einen Reflow
 window.requestAnimationFrame...
Quiz: Welche Variable bekommt den schnellsten
Zugriff?
var a = 1;
var b = "ich";
var c = 0.1;
var d = 0x1;
Richtig ist A
var a = 1;
var b = "ich";
var c = 0.1;
var d = 0x1;
STACK
0x00000003a:
0x005e4148b:
0x005e4160c:
String
“ich...
Number in JavaScript
 Alle Zahlen in JavaScript sind IEEE 64-Bit floating numbers
 Gute für den flexiblen Einsatz
 Eine...
Best Practices für Number
 Verwende eine 31-Bit Zahl wenn möglich
 Verwende nur floats wenn nötig
Böses Array! Aber warum?
var bad = new Array();
bad[0] = 1;
bad[1] = 5.6;
bad[2] = "Will nicht böse sein";
Es entstehen Kopien im Speicher und Konvertierungen
var bad = new Array();
bad[0] = 1;
bad[1] = 5.6;
bad[2] = "Will nicht ...
Immer noch Schmerzen! Aber warum?
var bad = new Array();
bad[0] = 1;
bad[1] = 5.6;
bad[2] = "Will nicht böse sein";
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(...
Verwende Typed Arrays wenn möglich
var value = 5;
var a = new Float64Array(100);
a[0] = value; // 5.0 - no tagging require...
Tödliche Schleifen…
var a = new Array(100);
var total = 0;
for (var item in a) {
total += item;
};
a.forEach(function(item...
Nutze eine Schleife effizient
var a = new Array(100);
var total = 0;
var cachedLength = a.length;
for (var i = 0; i < cach...
Best Practices für Arrays
 Gebe eine fixe Größe mit
 Verwende Typed Arrays wenn möglich
 Nutze eine Schleife effizient
The DOOM of DOM
...
//for each rotation
document.getElementById("myDiv").classList.remove(oldClass)
document.getElementByI...
DOM Kommunikation findet jetzt nur einmalig statt
var element = document.getElementById(elID).classList;
//for each rotati...
DOM Kommunikation findet jetzt nur einmalig statt
var elems = ['img1.jpg', … 'img6.jpg'];
var fragment = document.createDo...
Mhhh.. Was ist daran schlimm?
this.boardSize = document.getElementById("benchmarkBox").value;
for (var i = 0; i < this.boa...
DOM-Elemente sind immer ein String.
Ein direktes parseInt ist 25% schneller!
this.boardSize = parseInt(document.getElement...
Wollt ihr noch das beste zum Schluss?
Touchverzögerung entfernen mit FastClick
 Bei Klick oder Touch findet
eine 300 ms Verzögerung
statt
 Entfernen mit FastC...
Vieeeelll besser….
<script src='/path/to/fastclick.js'></script>
...
document.addEventListener('DOMContentLoaded', functio...
Fazit 1 von 3
 Die UI ist für den Benutzer schnell, wenn sie unter 100 ms reagiert
 Setze moderne WebViews für die Hybri...
Fazit 2 von 3
 Verwende die GPU so viel wie nur möglich
 Bilder anstatt CSS Features
 Animationen via transform: transl...
Fazit 3 von 3
 Erspare JavaScript unnötige Arbeit mit Konvertierungen
 Nutze JavaScript Arrays effektiv
 Verwende Schle...
Kostenloses Video-Training für alle!
http://goo.gl/BQb8ul
Kostenloser Artikel auf Entwickler.de für alle!
https://goo.gl/vwWysC
FRAGEN?
http://about.me/Gregor.Biswanger
Ich freue mich auf Feedback!
Vielen Dank!
Nächste SlideShare
Wird geladen in …5
×

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

742 Aufrufe

Veröffentlicht am

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!

Veröffentlicht in: Software
0 Kommentare
3 Gefällt mir
Statistik
Notizen
  • Als Erste(r) kommentieren

Keine Downloads
Aufrufe
Aufrufe insgesamt
742
Auf SlideShare
0
Aus Einbettungen
0
Anzahl an Einbettungen
20
Aktionen
Geteilt
0
Downloads
6
Kommentare
0
Gefällt mir
3
Einbettungen 0
Keine Einbettungen

Keine Notizen für die Folie

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!

×