Nie mehr weltweites Warten Performancetuning für JSF-Anwendungen Orientation in Objects GmbH Weinheimer Str. 68 68309 Mannheim Version: www.oio.de info@oio.de Ihr Sprecher Thomas Asel Trainer, Berater, Entwickler Schwerpunkte Frontend-Architektur, Entwicklung von Web-Anwendungen, Web-Performance-Optimierung http://blog.oio.de @Tom_Asel thomas.asel@oio.de 2 1
Das war in der Schachtel Lifecycle Resource Handling Komponenten- Modell Architektur- Modell Programmier- Modell viele, viele, Bibliotheken 3 Fear, Uncertainty, Doubt JSF ist doch oldschool schwerfällig schwierig langsam 4 2
Performance optimieren Auf welcher Ebene? JVM- Ebene JSF-Ebene Web- Ebene Heap-Size Garbage Collection Lifecycle Komponenten Requests Caching 5 Only 10%-20% of End-User Response-Time is spent donwloadingthe HTML document. Steve Souders - Web-Performance Guru, Yahoo 6 3
Welt-Weites-Warten Browser Servlet-Container GET /index.jsf JSF-Lifecycle "LATENZ" JSF Response Time Resource Loading GET stylesheet.css GET script.js GET logo.png RestoreView Render Response 7 Optimierungsmassnahmen - Anforderungen Postiver Effekt auf JSF Response Time Resource Loading Netzwerk Latenzen Geringe Auswirkungen auf Anwendungs-Architektur Programmiermodell Deployment Tooling: Integration in bestehenden Toolstack (JSF) Bordmittel 8 4
Optimierungsmassnahmen Easy Winner Browser Servlet-Container JSF Response Time Kompontenbaum Implementierungsunterschiede GET /index.jsf JSF-Lifecycle RestoreView Render Response Resource-Loading Combined Resources Caching Ressourcen auslagern Komprimierung GET stylesheet.css GET script.js GET logo.png 9 Gliederung Browser Servlet-Container JSF Response Time Kompontenbaum Implementierungsunterschiede GET /index.jsf JSF-Lifecycle RestoreView Render Response Resource-Loading Combined Resources Caching Ressourcen auslagern Komprimierung GET stylesheet.css GET script.js GET logo.png 10 5
JSF - Komponentenbaum UIViewRoot HtmlForm HtmlOutputText HtmlInputText HtmlOutcomeTargetLink 11 Apply Request Values Restore View Validation JSF Lifecycle Render Response Update Model Invoke Application 12 6
JSF - Komponentenbaum Wird im Lifecycle mehrfach traversiert Besonders aufwendig: Phase1: Erzeugung / Wiederherstellung Client-Side State-Saving: Deserialisierung Phase 6: Rendering 13 Dauer der Lifecylce-Phasen - Vergleichsmessung 60 50 Duration [ms] 40 30 20 10 C=1000 C=500 0 C=250 1 2 3 4 5 6 C=100 C=10 Phase Quelle: http://bit.ly/myfaces-vs-mojarra 14 7
Dauer der Lifecylce-Phasen Anteilig 50 45 40 Render Response % of Lifecycle Duration 35 30 25 20 15 Restore View Validation 10 Update Apply Model Request 5 Values Invoke 0 Application 0 1 2 3 4 5 6 7 Lifecycle Phase 15 Anzahl Components / View Beobachtet: < 50 eher selten Mittelwert ca. 250 Ausnahmefälle > 3000 Ursache: Unnötiger Gebrauch von JSF-Komponenten Falscher Gebrauch von Composite Components "Dead Code": rendered="false" Trotzdem Teil des Komponentenbaumes Komplexität z.b.: verschachtelte Tabbed Panes 54 Components! 16 8
Brauchen wir dafür JSF Komponenten? <ol id="ordered_list" class="ui-datalist-data"> <li class="ui-datalist-item"> Chrysler, 1965 </li>... <ol> 17 Lösung: Es müssen nicht immer Composites sein Custom-Tags <my:spacer height="100" /> Decorator <my:infobox type="warning" > <h:message for="selection" /> </my:infobox> Includes <ui:include src="footer.xhtml" /> Composite-Components <my:orderform value="#{order}" showall="true"> <f:validaterequired for="address" /> </my:orderform> 18 9
Gliederung Browser Servlet-Container JSF Response Time Kompontenbaum Implementierungsunterschiede GET /index.jsf JSF-Lifecycle RestoreView Render Response Resource-Loading Combined Resources Caching Ressourcen auslagern Komprimierung GET stylesheet.css GET script.js GET logo.png 19 JSF - Implementierungen 2 Implementierungen: Oracle Mojarra (Referenzimplementierung) Apache MyFaces Prinzipiell Austauschbar Servlet-Container: Implementierung typischerweise Teil der Anwendung Freie Wahl der Implementierung Java EE - Application-Server: "Full-Stack-Falle" Implementierung zwingend Teil des Auslieferumfangs Dadurch Festlegung auf Implementierung Version Änderung der JSF-Implementierung möglich Konfiguration notwendig Ggf. Auswirkung auf Garantie/Support 20 10
Vergleich: MyFaces vs Mojarra 1000 900 800 700 600 [ms] 500 400 300 200 100 0 0 200 400 600 800 1000 1200 1400 # of Components in Tree 21 Vergleich: MyFaces vs Mojarra 1000 900 800 700 600 [ms] 500 400 300 200 100 0 0 200 400 600 800 1000 1200 1400 # of Components in Tree 22 11
Fazit Vergleichsstudie 1. Größe des Komponentenbaum hat direkten Einfluss auf Performance 2. MyFaces durchläuft den Lifecycle schneller als Mojarra 3. Anwendungen mit großen Komponentenbäumen profitieren von einem Umstieg auf MyFaces bit.ly/myfaces-vs-mojarra 23 Gliederung Browser Servlet-Container JSF Response Time Kompontenbaum Implementierungsunterschiede GET /index.jsf JSF-Lifecycle RestoreView Render Response Resource-Loading Combined Resources Caching Ressourcen auslagern Komprimierung GET stylesheet.css GET script.js GET logo.png 24 12
JSF - Resource Handling Organisation in WebContent/resources: Rendering: Deklaration: <h:head> <h:outputstylesheet library="css" name="styleb.css" /> <h:outputscript library="js" name="scriptc.js" target="head" /> </h:head> <link rel="stylesheet" href="/myapp/javax.faces.resource/styleb.css.jsf?ln=css"> <script src="/myapp/javax.faces.resource/scriptc.js.jsf?ln=js"> </script> 25 Combined Resources 26 13
Combined Resources: Anforderungen Umsetzungsvarianten Build-Prozess/Deployment Maven Ant Jawr JSF Eigenimplementierung / Erweiterung Bibliothek Programmiermodell: Ressourcen zur Entwicklungszeit nicht kombinieren Staging-Konzept berücksichtigen Rendering: Nur ein Verweis pro Typ Gerenderte Links müssen kombinierte Ressource referenzieren 27 Combined Resources: Rendering <link rel="stylesheet" href="/myapp/javax.faces.resource/stylea.css.jsf?ln=css"> <link rel="stylesheet" href="/myapp/javax.faces.resource/styleb.css.jsf?ln=css"> <script src="/myapp/javax.faces.resource/scripta.js.jsf?ln=js"></script> <script src="/myapp/javax.faces.resource/scriptb.js.jsf?ln=js"></script> <script src="/myapp/javax.faces.resource/jquery- 1.9.1.min.js.jsf?ln=js"></script> <link rel="stylesheet" href="/myapp/resources/packed.css"> <script src="/myapp/resources/packed.js"></script> 28 14
JSF - Resource Handler Verantwortlich für De/Encoding von Resourcen Liefert Ressource anhand Library und Resourcename Behandelt Resource Requests 29 OmniFaces - CombinedResourceHandler faces-config.xml: <application> <resource-handler> org.omnifaces.resourcehandler.combinedresourcehandler </resource-handler> </application> 30 15
Combined Resources: Problem scripta.js (<1kB) view1.xhtml jquery.js (~91 kb) view2.xhtml scriptc.js (<1kB) 31 Combined Resources: Problem Ungepackt: Requests 9 of 12 3 from Cache 97,1 kb transferred 32 16
Combined Resources : Problem Ungepackt: Requests 9 of12 3 from Cache 97,1 kb transferred Gepackt: Requests 6 of 6 0 from Cache 186,9 kb transferred 33 Combined Resources : Problem Lösung: Caching - Strategie 34 17
Combined Resources Ausnahmen jquery.js [from Cache] view1.xhtml a1.js a2.js view2.xhtml b1.js b2.js 35 OmniFaces - CombinedResourceHandler Ausschluß seitenweise konfigurieren: view.xhtml: <!-- Packed Ressources --> <h:outputscript library="js" name="scriptb.js" target="head" /> <h:outputscript library="js" name="scriptc.js" target="head" /> <!-- Excluded from packing --> <h:outputscript library="js" name="jquery-1.9.1.min.js"/> 36 18
OmniFaces: CombinedResourceHandler Ausschluß global konfigurieren: web.xml: <context-param> <param-name> org.omnifaces.combined_resource_handler_excluded_resources </param-name> <param-value> javax.faces:jsf.js </param-value> </context-param> 37 OmniFaces: CombinedResourceHandler Auslieferung vollständig unterdrücken: web.xml: <context-param> <param-name> org.omnifaces.combined_resource_handler_suppressed_resources </param-name> <param-value> primefaces:primefaces.css </param-value> </context-param> 38 19
Combined Resources - Bibliotheken Omnifaces "Combined ResourceHandler" ICEfaces 3.3 "Resource Coalescing" RichFaces 4 "Resource Optimization" 39 Gliederung Browser Servlet-Container JSF Response Time Kompontenbaum Implementierungsunterschiede GET /index.jsf JSF-Lifecycle RestoreView Render Response Resource-Loading Combined Resources Caching Ressourcen auslagern Komprimierung GET stylesheet.css GET script.js GET logo.png 40 20
Standardverhalten: Caching- Response Header Production-Stage: HTTP/1.1 200 OK Server: Apache-Coyote/1.1 Expires: Thu, 11 Apr 2013 13:51:12 GMT Last-Modified: Wed, 03 Apr 2013 08:52:01 GMT Content-Type: application/javascript Content-Length: 176 Date: Thu, 04 Apr 2013 13:51:12 GMT 41 Expires Header "The Expires entity-header field gives the date/time after which the response is considered stale." RFC 2616 - Hypertext Transfer Protocol -- HTTP/1.1 Wird von JSF automatisch gesetzt Production-Stage: 7 Tage Development-Stage: 0 Probleme: Zu kurzer Zeitraum: Ressource wird redundant ausgeliefert Zu langer Zeitraum Client verpasst Update 42 21
Idee: Expires: Fri, 01 Jan 2100 12:00:00 GMT JSF Resourcehandling unterstützt Versionierung Version mit jedem Deployment erhöhen JSF verwendet standardmässig höchste Version Angabe von niedriger Version möglich, aber <h:outputscript library="js" name="1_0/scripta.js" target="head" /> Mojarra: erlaubt MyFaces: Warnung: Resource referenced by resourcename 1_0/scriptA.js and libraryname js not found in call to ResourceHandler.createResource. It will be silenty ignored. 43 Response Header anpassen Servlet-Filter geht immer, unabhängig von JSF Nachteil: Kein Zugriff auf FacesContext, Scopes, etc JSF: 44 22
Gliederung Browser Servlet-Container JSF Response Time Kompontenbaum Implementierungsunterschiede GET /index.jsf JSF-Lifecycle RestoreView Render Response Resource-Loading Combined Resources Caching Ressourcen auslagern Komprimierung GET stylesheet.css GET script.js GET logo.png 45 Statische Ressourcen auslagern http://www.oio.de http://static.oio.de Apache httpd 46 23
CDN Content Delivery Network 47 CDN - Vorteile Transfer von statischen Ressourcen schont Application Server Unternehmensnetzwerk Erzeugt (vermutlich) geringere Kosten ab 0,12 $ / GB und Beispiel $0,0090 / 10.000 Requests CDN übernimmt Auslieferung Load-Balancing Skalierung 48 24
JSF und CDN Deployment Extra-Step Maven Ant JSF <link rel="stylesheet" href="/myapp/javax.faces.resource/stylea.css.jsf?ln=css"> <link rel="stylesheet" href="http://mycdn.com/oio/myapp/stylea.css"> 49 JSF Resource Handler 50 25
OmniFaces: CDNResourceHandler faces-config.xml: <application> <resource-handler> org.omnifaces.resourcehandler.cdnresourcehandler </resource-handler> </application> web.xml: <context-param> <param-name> org.omnifaces.cdn_resource_handler_urls </param-name> <param-value> js:jquery.js=http://code.jquery.com/jquery.js </param-value> </context-param> 51 OmniFaces: CDNResourceHandler from CDN Packed 52 26
CDN und Caching Response Header: Access-Control-Allow-Origin:* Content-Encoding:gzip Content-Length:32819 Content-Type:application/x-javascript; charset=utf-8 Date:Fri, 05 Apr 2013 14:02:24 GMT Cache-Control:max-age=2592000 Expires:Sun, 05 May 2013 14:02:24 GMT Last-Modified:Tue, 05 Feb 2013 00:56:40 GMT Vary:Accept-Encoding X-Cache:HIT Server:ECS (fcn/41b6) 53 Gliederung Browser Servlet-Container JSF Response Time Kompontenbaum Implementierungsunterschiede GET /index.jsf JSF-Lifecycle RestoreView Render Response Resource-Loading Combined Resources Caching Ressourcen auslagern Komprimierung GET stylesheet.css GET script.js GET logo.png 54 27
Konfiguration - Tomcat Server.xml <Connector port="8080" protocol="http/1.1" connectiontimeout="20000" redirectport="8443" compression="on" compressionminsize="1024" compressablemimetype="text/css,application/javascript" /> 55 Zusammenfassung Browser Servlet-Container JSF Response Time Kompontenbaum Implementierungsunterschiede GET /index.jsf JSF-Lifecycle RestoreView Render Response Resource-Loading Combined Resources Caching Ressourcen auslagern Komprimierung GET stylesheet.css GET script.js GET logo.png 56 28
Fazit Einfluss auf JSF-Performance: Größe des Komponentenbaumes Wahl der Implementierung # Requests statischer Resourcen verringern: Combined Resources Resource Caching Auslagern (CDN / dedicated Webserver) Netzwerk-Latenz verringern: GZip Kompression nutzen Der Browser kann das schon lange Alle vorgestellten Massnahmen lassen sich mit JSF umsetzen Es existieren außerdem hilfreiche Bibliotheken 57 Mehr von OIO zum Thema Schulung: JavaServer Faces http://www.oio.de/java-server-faces.htm Schulung: JSF Komponenten selbst entwickeln http://www.oio.de/seminar/java/kurs-jsf-schulung-komponenten-javaserver-faces-seminar-entwicklung-components.htm Vergleichsstudie der Implementierungen Oracle Mojarra und Apache MyFaces http://www.oio.de/public/java/studie-jsf-mojarra-myfaces-performancevergleich.htm Artikel: JSF Best Practices (englischer Artikel) http://www.oio.de/public/java/jsf-best-practices-javaserver-facessession-tips.htm 58 29
?? Fragen??? Orientation Objects GmbH Weinheimer Str. 68 68309 Mannheim www.oio.de info@oio.de?? Vielen Dank für ihre Aufmerksamkeit! Orientation in Objects GmbH Weinheimer Str. 68 68309 Mannheim www.oio.de info@oio.de 30