web-dev-qa-db-ger.com

JSF Leistungsverbesserung

Ich arbeite an einer WebApp mit JSF 2.2 + Primefaces ... Das Projekt wächst schnell, und der erste Leistungstest war sehr schlecht (aufgrund meines schlechten Wissens zu JSF LifeCylce in Kombination mit nicht funktionalen Anforderungen - also vollständig ajax-Website) Wir könnten ein wenig verbessern, aber die Ergebnisse sind nicht wie erwartet. (Wir haben eine Zeit von 300 bis 1500 ms, abhängig von der Aktion, die Idee ist eine Performance von etwa 500 ms, geben oder nehmen). Hauptsächlich die Wiederherstellungsansicht -Phase und die Render-Antwort sind die Zeitkonsumenten (in anderen Fällen ist die aufgewendete Zeit wertlos). Für einige Aktionen benötigt Invoke Aplication auch Zeit (aufgrund von DB-Aufrufen).

Nachdem ich viele Artikel im Web gelesen hatte, gab es viele tolle Tipps (viele natürlich von stackoverflow), wie zum Beispiel:

  • DB-Abfragen verbessern

wir haben einige komplexe, die mit zwei Hibernate Criterias-Abfragen erstellt werden, sodass wir hier arbeiten können. (Verwenden Sie möglicherweise reine SQL-Abfragen und bei komplexen Abfragen?)

  • Definieren Sie niemals Geschäftslogik auf Beans Getter

Ich habs!

  • Legen Sie die entsprechenden Bereiche fest, um sie zu speichern und nur das Nötigste zu speichern

Wir haben eine vollständige Ajax-Site, also sind View-Scope fast so wie Session-Scopes für uns. Wir verwenden die SessionBeans als eine Art 'Cache', um Schlüsseldaten zu speichern, die wir nicht jedes Mal von der DB erhalten möchten + Geschäftslogik definieren Hier.

  • Auswahl der richtigen Methode zum Speichern des Status von JSF - Client Vs Server

Dazu muss ich noch etwas recherchieren, die Möglichkeiten mit ihren Vor- und Nachteilen prüfen und dann die Leistung jedes einzelnen prüfen.

Soweit sehr klar, nun einige Extratipps, an denen ich einige Zweifel habe.

  • Verwenden Sie möglichst viel Vanilla-HTML und vorzugsweise h: -Tags anstelle von p: -Tags

Einfacher HTML-Code ist klar und sinnvoll, jetzt zwischen h: und p: Wie viel ist es wert? Zum Beispiel.

<p:commandButton value="Value" 
             styleClass="class" 
             actionListener="#{myBean.doStuff()}"
             ajax="true" process="@form" update="@form" 
             onsuccess="jsFunction()" />

vs

<h:commandButton value="Value" 
             styleClass="class" 
             actionListener="#{myBean.doStuff()}" >
       <f:ajax execute="@form" render="@form" event="onclick" />
</h:commandButton>

oder

<ui:fragment... vs <p:fragment...

oder

<p:outputLabel value="#{myBean.value}" rendered="#{myBean.shouldRender}" />

vs

<ui:fragment rendered="#{myBean.shouldRender}">
    <label>#{myBean.value}</label>
</ui:fragment>

Ich verwende hier und da schon seit einiger Zeit eine Mischung aus Primefaces mit Jsf-Tags und einigem einfachen HTML-Code (hauptsächlich aufgrund der Komponentenmerkmale der Komponenten). Jetzt wird einfaches HTML immer schneller sein, aber zwischen JSF und einem anderen Framework. Wenn ich das anstrebe, wird das Ändern viel Zeit in Anspruch nehmen, und ich möchte nicht, dass das Ergebnis der Erkenntnis keinen relevanten Unterschied macht.

  • Benutzerdefinierte Facelets-Tags vs. Verbundkomponenten

Ich denke hier ist der Schlüssel. Habe noch einige Zweifel bezüglich ihrer Unterschiede, hinsichtlich der Implementierung von beiden.CCsind ziemlich einfach und flexibel zu verwenden, haben aber den Nachteil, dass sie vollständig in ViewTree enthalten sind und JSF für jede Anforderung neu generiert (wenn ich mich nicht irre), während custom tags etwas komplizierter zu sein scheint (nicht so viel), hat aber den Vorteil, dass nur das, was tatsächlich gerendert wird, im ViewTree enthalten ist und nichts mehr. RESTORE VIEW ist weniger zeitaufwändig. Wir haben mehrere zusammengesetzte Komponenten und keine Facelets-Tags, daher wird hier viel Arbeit geleistet. Ich habe immer noch keinen guten Artikel gefunden, in dem die Unterschiede erläutert werden, wann einer verwendet werden soll und wann der andere (gelesen haben, dass Nachrichten für Eingaben TAGS und für komplexere Dinge CC verwenden). Wenn die Idee ist, Tags vs. CC zu bevorzugen, was wäre der Fall, bei dem ich keine Option hätte, anstatt CC zu verwenden? Ist es in Ordnung, benutzerdefinierte Tags in CC zu verwenden, um sie für die Verarbeitung von JSF leichter zu machen?

Ich bin gerade dabei, eine Reise des Modifizierens des Bohrungsprojekts zu unternehmen, um eine bessere Leistung zu erzielen, was mich einige Tage in Anspruch nehmen wird. Die Idee ist, dieses Mal bessere Ergebnisse zu erzielen. Daher sind alle Tipps, Ratschläge und Vorschläge sehr willkommen! Danke für deine Zeit, Jungs!

12

RenderResponse nimmt 98% Ihrer Zeit in Anspruch, weil JSF dies hauptsächlich tut. Ich würde mir Sorgen machen, wenn JSF 50% der Bearbeitungszeit einer Anfrage für andere Zwecke als die Antwort aufwenden würde! Sie müssen tiefer graben. Betrachten Sie dieses Beispiel. 

Angenommen, Sie haben eine Seite, auf der eine Tabelle angezeigt wird. Sie verwenden die p: dataTable PrimeFaces-Komponente wie folgt:

<h:html>
   <h:body>
       <p:dataTable value="#{myBean.data}">
       </p:dataTable>
   </h:body>
</h:html>

Und du hast diesen @ManagedBean:

@ManagedBean(name="myBean")
public class MyBean {

    public List<MyObject> getData() { 
        return // fetch list from database;
    }
}

Bei jedem Aufruf von getData() gibt es einen Datenbankzugriff, und diese Zeit erhöht die globale Zeit der Renderphase. Darüber hinaus erfordert das Rendern von p: dataTable möglicherweise viele Aufrufe von getData. 

Auch hier müssen Sie tiefer in Ihre Anwendung einsteigen und feststellen, wo genau während der Renderphase Zeit aufgewendet wird. Nach meiner Erfahrung haben naive Implementierungen von @ManagedBeans eine Menge datenbankabfragenden Code in denselben Gettern, auf die in xhtmls verwiesen wird, wie in meinem vorherigen Beispiel. JSF (oder eine Komponente wie p: dataTable von PrimeFaces) ruft diese Getter oft auf, während ein einzelnes Xhtml gerendert wird. Eine übliche Strategie besteht darin, Daten nur einmal abzurufen. Verwenden Sie dazu das preRenderView-Ereignis:

In Ihrem Xhtml:

<h:html>
   <f:metadata>
       <f:event type="preRenderView" listener="#{myBean.fetchDAta}"/>
   </f:metadata>
   <h:body>
       <p:dataTable value="#{myBean.data}">
       </p:dataTable>
   </h:body>
</h:html>

In deiner verwalteten Bohne:

@ManagedBean(name="myBean")
public class MyBean {
    private List<MyObject> data;

    public void fetchData() {
         data = // fetch data from database.
    }

    public List<MyObject> getData() { 
        return data; 
    }
 }
1
Martín Straus

Es gibt einige Möglichkeiten, die Leistung Ihrer Bildschirme zu verbessern

  1. GZIP-Filter verringert die anfängliche Ladezeit erheblich. Es komprimiert den Seiteninhalt während der Übertragung zum Client-Browser. Siehe https://stackoverflow.com/a/35567295/5076414
  2. Sie können zusätzlich ein cacheFilter implementieren, um die Leistung von Ihrer Bildschirme auf eine Stufe zu bringen, die der auf JavaScript basierenden Benutzeroberfläche entspricht. Dadurch werden die statischen Inhalte Ihres Bildschirms wie Symbole, Bilder, Stylesheets, Javascripts usw. zwischengespeichert. Sie können steuern, was zwischengespeichert und ausgeschlossen werden soll. Siehe https://stackoverflow.com/a/35567540/5076414
  3. Für clientseitige Benutzeroberflächenkomponenten können Sie Primefaces verwenden. Dies ist eine auf JQuery Basierende Benutzeroberfläche. 

Wie überprüfe ich, ob mein Bildschirm gzip und cache verwendet?

Um zu sehen, ob Ihre Inhalte bereits gzip und cache enthalten, klicken Sie mit der rechten Maustaste auf den Bildschirm Ihres Google Chrome Browser -> -> Inspect -> Klicken Sie auf die Registerkarte Netzwerk -> Bildschirm aktualisieren. Klicken Sie auf auf den Bildern, Symbolen, Stylesheets und sehen Sie, ob Sie Folgendes in Antwortheader sehen

Cache-Control:max-age=2592000 wenn der Status des Elements 304 ist (vom Cache kommt)

Content-Encoding:gzip wenn der Status des Elements 200 ist

1
Sacky San

Ich war vor einem halben Jahr mit demselben Problem konfrontiert. Die meiste Zeit in RestoreView und RenderResponse phase. Wenn Ihr Problem das gleiche ist, dann Können Sie nicht viel tun:

  1. Verwenden Sie partialSubmit="true" so oft wie möglich
  2. Reduzieren Sie die Anzahl der Komponenten
  3. Verwenden Sie nicht häufig Verbundkomponenten

In meinem speziellen Fall hatte ich viel dynamisches HTML ohne Eingabesteuerelemente und Verwendete Composite-Komponente als Vorlage für das bedingte Rendern. Um die Leistung zu steigern, habe ich freemarker verwendet, um dynamisches HTML zu generieren.

PS. Meiner Meinung nach ist es nicht, JSF zu verwenden, wenn Sie komplexe Seiten mit vielen Komponenten haben. Ich denke, Tapisserie ist dafür mehr optimiert. Komponenten werden nicht wie JSF bei jeder Anforderung neu erstellt.

1
Sergiy Uvarov