8

Chciałbym zmierzyć czas renderowania aplikacji JSF. Z powodu moich powodów braku mocy aplikacja nie może być wypełniona dziennikami.Zmierz czas renderowania widoku JSF po żądaniu serwera

W związku z tym moje pytanie byłoby, czy istnieje sposób, w jaki można zmierzyć czas renderowania aplikacji po wykonaniu określonej czynności, która obejmuje wywołanie back-end (serwer) za pomocą dowolnej przeglądarki?

Do tej pory po korzystaniu z Narzędzi dla programistów w Chrome zauważyłem następujące. Na karcie Sieć każde żądanie wyświetla wyświetlany czas. Ponadto, po wybraniu określonej pozycji, w zakładce "Timing" wyświetlana jest bardziej szczegółowa wizualizacja. Teraz mogę powiedzieć, że "Czekanie", że w obie strony do serwera jest tu zrobione, ale co z faktycznym czasem renderowania.

Zakładając, że cała prośba zajęła 1 sek, a sekcja oczekiwania ma 500ms, czy mogę odliczyć, że renderowanie to 1sec-500ms? Zakładam, że nie, właśnie dlatego zadaję to pytanie.

Krótko mówiąc, potrzebowałbym informacji z przeglądarki, dla określonego żądania, jak długo trwało przetwarzanie serwera i jak długo trwało renderowanie UI.

Wszelkie wskazówki będą mile widziane. Dziękuję Ci.

Odpowiedz

10

Można to zrobić ze zwyczajem ViewDeclarationLanguage czym zmierzyć createView(), buildView(), renderView() a jeśli niezbędne restoreView() metod.

Oto przykład kickoff:

public class VdlLogger extends ViewDeclarationLanguageWrapper { 

    private static final Logger logger = Logger.getLogger(VdlLoggerFactory.class.getName()); 

    private ViewDeclarationLanguage wrapped; 

    public VdlLogger(ViewDeclarationLanguage wrapped) { 
     this.wrapped = wrapped; 
    } 

    @Override 
    public UIViewRoot createView(FacesContext context, String viewId) { 
     long start = System.nanoTime(); 
     UIViewRoot view = super.createView(context, viewId); 
     long end = System.nanoTime(); 
     logger.info(String.format("create %s: %.6fms", viewId, (end - start)/1e6)); 
     return view; 
    } 

    @Override 
    public void buildView(FacesContext context, UIViewRoot view) throws IOException { 
     long start = System.nanoTime(); 
     super.buildView(context, view); 
     long end = System.nanoTime(); 
     logger.info(String.format("build %s: %.6fms", view.getViewId(), (end - start)/1e6)); 
    } 

    @Override 
    public void renderView(FacesContext context, UIViewRoot view) throws IOException { 
     long start = System.nanoTime(); 
     super.renderView(context, view); 
     long end = System.nanoTime(); 
     logger.info(String.format("render %s: %.6fms", view.getViewId(), (end - start)/1e6)); 
    } 

    @Override 
    public ViewDeclarationLanguage getWrapped() { 
     return wrapped; 
    } 

} 

Aby go uruchomić, należy utworzyć poniższego fabryczne:

public class VdlLoggerFactory extends ViewDeclarationLanguageFactory { 

    private ViewDeclarationLanguageFactory wrapped; 

    public VdlLoggerFactory(ViewDeclarationLanguageFactory wrapped) { 
     this.wrapped = wrapped; 
    } 

    @Override 
    public ViewDeclarationLanguage getViewDeclarationLanguage(String viewId) { 
     return new VdlLogger(wrapped.getViewDeclarationLanguage(viewId)); 
    } 

    @Override 
    public ViewDeclarationLanguageFactory getWrapped() { 
     return wrapped; 
    } 

} 

i zarejestrować go jako poniżej faces-config.xml:

<factory> 
    <view-declaration-language-factory>com.example.VdlLoggerFactory</view-declaration-language-factory> 
</factory> 

createView() to krok tworzenia konkretnego egzemplarza instancji UIViewRoot sed na <f:view> i <f:metadata> obecnych w plikach widoku. Podczas używania Facelets (XHTML) jako widoku, podczas tego kroku wszystkie skojarzone pliki XHTML będą analizowane przez analizator składni SAX i buforowane przez czas określony w javax.faces.FACELETS_REFRESH_PERIOD. Może się więc zdarzyć, że jest to jeden czas stosunkowo powolny, a drugi czas szybko się rozpala.

Numer buildView() jest etapem wypełniania drzewa komponentów JSF (getChildren() z UIViewRoot) na podstawie kompozycji widoku (XHTML). Podczas tego kroku wykonywane są wszystkie znaczniki (JSTL i przyjaciele) i wszystkie wyrażenia EL w tych znacznikach i atrybutach składnika id i binding są oceniane (szczegóły, patrz także JSTL in JSF2 Facelets... makes sense?). Jeśli więc fasola jest tworzona po raz pierwszy podczas budowania widoku i wywoływania logiki biznesowej podczas @PostConstruct, może się zdarzyć, że jest to czasochłonne.

renderView() jest etapem generowania wyjścia HTML na podstawie drzewa komponentów JSF i modelu, zaczynając od UIViewRoot#encodeAll(). Jeśli więc fasola jest tworzona po raz pierwszy podczas renderowania czasu wyświetlania i wywoływania logiki biznesowej podczas @PostConstruct, może się zdarzyć, że jest to czasochłonne.

Jeśli fasola jest nieprawidłowo wykonująca logikę biznesową w metodach getter zamiast w @PostConstruct lub innym jednorazowym detektorze zdarzeń cyklu życia, może się zdarzyć, że zajmie to jeszcze więcej czasu. Zobacz także Why JSF calls getters multiple times.

+0

To po prostu ... niesamowite. Dziękuję Ci! – user2271933

+0

Nie ma za co. – BalusC

+0

[ViewDeclarationLanguageWrapper] (http://docs.oracle.com/javaee/7/api/javax/faces/view/ViewDeclarationLanguageWrapper.html) został dodany w wersji 2.2. Czy uważasz, że byłoby łatwo zmodyfikować to, aby działało z wersją 2.1, czy lepiej byłoby, gdyby szukałem innego sposobu na jego implementację? –