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 über JSF LifeCylce in Kombination mit nicht funktionalen Anforderungen - dh vollständig ajax-Website) ), dann könnten wir ein wenig verbessern, aber die Ergebnisse sind immer noch nicht wie erwartet. (Wir haben eine Zeit von 300 ~ 1500 ms abhängig von der Aktion, Idee ist eine Leistung um 500ms zu haben, geben oder nehmen). Hauptsächlich die Phase Ansicht wiederherstellen und die Render Response sind die Zeitkonsumenten (bei anderen Phasen ist die verbrachte Zeit wertlos). Bei einigen Aktionen benötigt Anwendung aufrufen auch Zeit (aufgrund von DB-Aufrufen).
Nachdem wir viele Artikel im Internet gelesen hatten, gab es eine Menge toller Tipps (viele natürlich von stackoverflow) wie:
- Verbesserung von DB-Abfragen
Wir haben einige komplexe Abfragen, die mit zwei Hibernate Criteria-Abfragen durchgeführt werden, sodass wir hier arbeiten können. (Vielleicht verwenden Sie reine SQL-Abfragen, und bei komplexen verwenden Sie Sub-Abfragen?)
- Nie Geschäftslogik auf Bean's Getter definieren
Bekam es!
- Setzen Sie die entsprechenden Bereiche auf Bean und speichern Sie auf ihnen nichts mehr als die notwendigen Dinge
Wir haben eine vollständige Ajax-Site, so dass View Scoped fast wie Session Scoped für uns ist. Wir verwenden die SessionBeans als eine Art "Cache", um wichtige Daten zu speichern, die wir nicht jedes Mal von der Datenbank bekommen wollen Definieren Sie hier die Geschäftslogik.
- Auswahl der richtigen Methode zum Speichern von JSF - Client Vs Server
Dafür muss ich noch mehr recherchieren, die Möglichkeiten mit ihren Vor- und Nachteilen prüfen und dann die Leistung testen.
Bis jetzt sehr klar, jetzt einige zusätzliche Tipps, an denen ich einige Zweifel habe.
- Verwenden Sie so oft wie möglich Vanilla-HTML und verwenden Sie vorzugsweise h: tags statt p: tags
Plain HTML ist klar und sinnvoll, jetzt zwischen h: und p: wie viel ist es wert? Zum Beispiel.
%Vor%vs
%Vor%oder
%Vor%oder
%Vor%vs
%Vor%Ich habe schon seit einiger Zeit eine Mischung aus Primefaces mit Jsf-Tags und etwas plainem HTML hier und da benutzt (hauptsächlich PF aufgrund ihrer Komponentenfeatures) Ich jetzt, dass einfaches HTML immer schneller sein wird, aber zwischen JSF und ein anderer Rahmen? Wenn ich das tue, wird es viel Zeit in Anspruch nehmen, es zu ändern, und ich würde nicht gerne wissen, dass es keinen relevanten Unterschied macht.
- Benutzerdefinierte Facelet-Tags und Composite-Komponenten
Ich denke, hier ist der Schlüssel. Noch haben einige Zweifel über ihre Unterschiede, auf die Implementierung von beiden, CC sind ziemlich einfach und flexibel zu verwenden, haben aber den Nachteil, dass sie vollständig in den ViewTree und JSF für jede Anfrage neu generiert werden ( wenn ich mich nicht irre), während benutzerdefinierte Tags etwas komplexer 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, die RESTORE VIEW weniger zeitaufwendig machen. Wir haben mehrere zusammengesetzte Komponenten und keine Facelets Tags, also wird es hier viel Arbeit zu tun geben. Ich habe immer noch keinen guten Artikel gefunden, der Unterschiede auf ihnen erklärt, wenn man benutzt werden sollte und wenn der andere (habe das für Eingaben gelesen, Nachrichten verwenden TAGS und für komplexere Dinge CC). Wenn die Idee ist, Tags vs CC zu bevorzugen, was wäre der Fall, auf den 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 in JSF leichter zu machen?
Ich bin dabei, mich auf eine Reise zu begeben, um das Loch-Projekt zu modifizieren, um eine bessere Leistung zu erreichen, die mich einige Tage in Anspruch nehmen wird, die Idee ist, diesmal bessere Ergebnisse zu erzielen; So ist jeder Tipp, Rat und Vorschlag sehr willkommen! Danke für deine Zeit Leute!
RenderResponse benötigt 98% Ihrer Zeit, weil ... das ist hauptsächlich JSF. Ich wäre besorgt, wenn JSF 50% der Bearbeitungszeit einer Anfrage dediziert, um andere Dinge zu tun, als die Antwort zu rendern! 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:
%Vor% Und Sie haben dieses @ManagedBean
:
Jedes Mal, wenn getData()
aufgerufen wird, gibt es einen Datenbankzugriff und diese Zeit addiert sich zu der globalen Zeit der Render-Phase. Darüber hinaus erfordert das Rendern von p: dataTable möglicherweise viele Aufrufe von getData.
Auch hier müssen Sie tiefer in Ihre Anwendung eintauchen und herausfinden, wo während der Render-Phase genau die Zeit verbracht wird. Meiner Erfahrung nach haben naive Implementierungen von @ManagedBean
s eine Menge Datenbankabfragungscode in denselben Gettern, auf die in xhtml
s verwiesen wird, wie in meinem vorherigen Beispiel. JSF (oder eine Komponente wie PrimeFaces 'p: dataTable) ruft diese Getter oft beim Rendern eines einzelnen xhtml auf. Eine allgemeine Strategie besteht darin, Daten nur einmal mithilfe des preRenderView-Ereignisses wie folgt abzurufen:
In Ihrem xhtml:
%Vor%In Ihrer verwalteten Bean:
%Vor%Ich hatte vor einem halben Jahr das gleiche Problem. Die meiste Zeit verbrachte in RestoreView und RenderResponse -Phase. Wenn dein Problem dann gleich ist Es gibt nicht viel, was du tun kannst:
partialSubmit="true"
so viel wie möglich In meinem speziellen Fall hatte ich eine Menge dynamisches HTML ohne Eingabesteuerelemente und Ich habe die Composite-Komponente als Vorlage für das bedingte Rendering verwendet. Um die Leistung zu steigern, habe ich freemarker verwendet, um dynamisches HTML zu generieren.
PS. Meine Meinung ist nicht, JSF zu verwenden, wenn wir komplexe Seiten mit vielen Komponenten haben. Ich denke, Tapestry ist dafür optimiert. Es erstellt keine Komponenten bei jeder Anforderung wie JSF.
Es gibt einige Dinge, die Sie tun können, um die Leistung Ihrer Bildschirme zu verbessern.
Um zu sehen, ob Ihre Inhalte bereits gzip und cache usign sind, In Ihrem Google Chrome Browser - & gt; Rechtsklick auf den Bildschirm - & gt; inspizieren - & gt; Klicken Sie auf Netzwerkregisterkarte - & gt; Aktualisiere deinen Bildschirm. Klicken Sie auf die Bilder, Symbole und Stylesheets und sehen Sie, ob Sie in Response Header
sehen Cache-Control:max-age=2592000
wenn der Status des Elements 304 ist (kommt vom Cache)
Content-Encoding:gzip
wenn der Status von Element 200 ist
Ich bin nicht sicher, ob es einen großen Unterschied zwischen "p" und "h" gibt, da beide am Ende als html gerendert werden. Ich sehe, Sie verwenden viel das Prozessattribut. Sie können auf bestimmte IDs in diesem Attribut abzielen, um die Leistung zu verbessern, indem Sie nur Teile des Formulars senden. Eine andere Idee, um die Leistung zu erhöhen, ist die Verwendung des "Cache". Ссылка für nicht dynamische Inhalte, die sehr häufig gerendert werden sollen (siehe Dokumentation). Ich denke, "Cache" wird versuchen, die Baumansicht aus dem Cache zu holen, anstatt sie zu rekonstruieren.
Ich habe einen interessanten Artikel über JSF-Beschleunigung gelesen. In der Wiederherstellungsphase rekonstruiert JSF den Komponentenbaum einschließlich der Bindung von Daten an Datentabellen, wodurch unnötige Datenabrufe aus der Datenbank verursacht werden. Der Artikel befasst sich mit einer Möglichkeit, die zusätzliche Arbeit zum Abrufen der Daten zu vermeiden.
Ich berichte hier die mögliche Lösung und den ganzen Artikel als Referenz.
Eine Lösung für das Problem besteht darin, das Abrufen der Daten beim ersten Mal ganz zu überspringen. Es wird nicht benötigt, es wird nicht einmal verwendet und es sind nicht einmal die richtigen Daten (mach dir keine Sorgen, ich werde das später erklären). Im FacesContext-Objekt gibt es eine Methode namens getRenderResponse (), die true zurückgibt, wenn die Render-Response-Methode aufgerufen wurde und wir uns in der Rendering-Phase befinden. Bis wir die Seite gerendert haben, brauchen wir unsere Daten nicht wirklich, also laden wir sie nur, wenn diese Methode true zurückgibt.
Zum Beispiel:
%Vor%Wir bekommen also nur einen Datenabruf pro Seitenanforderung, sogar bei Postbacks, weil wir die Daten nicht so lange laden, bis wir sie wirklich in der Renderantwort brauchen. Und wenn Sie das Timing betrachten, werden unsere Seiten doppelt so schnell geladen Wir holen nur die Hälfte der Daten.
Sie können also die Geschwindigkeit Ihrer JSF-Seiten erhöhen, indem Sie nur Daten laden, wenn Sie sie wirklich brauchen. Ich denke, es ist eine Art faules, langsames Laden von Daten.
Verdopple die Geschwindigkeit von (einigen) deiner JSF-Seiten (und weiche auch Bugs aus)
Ich hoffe, es ist nützlich für andere.
Wenn Sie JSF-Anwendung mit anderen Framework machen möchten, ist Ihre Anwendung als Leistung für Benutzer schlecht. Weil JSF-Anwendung 6-phasig wurde, warte die Renderphase zu sehr. So können Sie Micro-Services für das Backend verwenden und Javascript für das Frontend verwenden. Ergebnis können Sie so gute Anwendung wie Leistung und Architektur machen. Sie können Spring-Boot-Micro-Dienste für Java-ee-Anwendungen suchen
Tags und Links performance jsf jsf-2 primefaces