在服务器请求之后测量 JSF 视图的呈现时间 [英] Measure the render time of a JSF view after a server request

查看:19
本文介绍了在服务器请求之后测量 JSF 视图的呈现时间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想测量 JSF 应用程序的渲染时间.由于我的权力原因,该应用程序无法填充日志.

I would like to measure the rendering time of a JSF application. Because of out of my power reasons, the application can't be populated with logs.

因此,我的问题是,在使用任何浏览器执行包括后端(服务器)调用的特定操作后,有没有什么方法可以测量应用程序的渲染时间?

Therefore, my question would be, is there any way in which I can measure the rendering time of the application after doing a certain action that includes a back-end(server) call using any browser?

到目前为止,在使用 Chrome 开发者工具后,我发现了以下内容.在网络选项卡上,每个请求都显示了时间".此外,选择某个条目后,在计时"选项卡上,会显示更详细的可视化.现在,我可以从等待"中看出它在此处捕获到服务器的往返行程,但实际渲染时间呢.

So far,after using the Chrome Developer Tools,I spotted the following. On the Network tab, each request has the "Time" displayed. In addition, after selecting a certain entry, on the "Timing" tab, a more detailed visualization it's displayed. Now, I can tell from that that the "Waiting" that the round-trip to the server it's captured here, but what about the actual rendering time.

假设整个请求用了 1 秒,而等待部分用了 500 毫秒,我可以推断渲染是 1 秒-500 毫秒吗?我认为不是,这就是我问这个问题的原因.

Assuming that the whole request took 1sec, and the Waiting section it's 500ms, can I deduct that the rendering it's the 1sec-500ms ? I assume not, thats why I am asking this question.

长话短说,对于某个请求,我需要从浏览器知道服务器处理多长时间以及实际 UI 渲染多长时间.

Long story short, I would need to know from the browser, for a certain request how long was the server processing and how long was the actual UI rendering.

任何提示将不胜感激.谢谢.

Any tips would be greatly appreciated. Thank you.

推荐答案

您可以使用自定义 ViewDeclarationLanguage,您可以借此衡量 createView(), buildView(), renderView() 如有必要 restoreView() 方法.

You can do that with a custom ViewDeclarationLanguage whereby you measure the createView(), buildView(), renderView() and if necessary restoreView() methods.

这是一个启动示例:

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;
    }

}

要让它运行,请创建以下工厂:

To get it to run, create the below factory:

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;
    }

}

并在faces-config.xml中注册如下:

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

createView() 是基于<f:view>< 创建具体的UIViewRoot 实例的步骤;f:metadata> 存在于视图文件中.当使用 Facelets (XHTML) 作为视图时,在此步骤中,所有关联的 XHTML 文件将由 SAX 解析器解析并缓存一段时间,如 javax.faces.FACELETS_REFRESH_PERIOD 中定义的那样.所以它可能会发生一次相对较慢,另一次非常快的情况.

The createView() is the step of creating the concrete UIViewRoot instance based on <f:view> and <f:metadata> present in the view files. When using Facelets (XHTML) as view, during this step all associated XHTML files will be parsed by the SAX parser and cached for a time as defined in javax.faces.FACELETS_REFRESH_PERIOD. So it may happen that it's one time relatively slow and the other time blazing fast.

buildView() 是基于视图(XHTML) 组成.在此步骤中,所有标记处理程序(JSTL 和朋友)都被执行,并且这些标记处理程序和组件的 idbinding 属性中的所有 EL 表达式都会被评估(有关详细信息,另请参见 JSF2 Facelets 中的 JSTL ......有意义吗?).因此,如果在视图构建期间第一次构建支持 bean 并在 @PostConstruct 期间调用业务逻辑,那么这可能会很耗时.

The buildView() is the step of populating the JSF component tree (the getChildren() of UIViewRoot) based on the view (XHTML) composition. During this step, all taghandlers (JSTL and friends) are executed and all EL expressions in those taghandlers and component's id and binding attributes are evaluated (for detail, see also JSTL in JSF2 Facelets... makes sense?). So if backing beans are constructed for first time during view build time and invoking business logic during @PostConstruct, then it may happen that this is time consuming.

renderView() 是基于 JSF 组件树和模型生成 HTML 输出的步骤,从 UIViewRoot#encodeAll() 开始.因此,如果在视图渲染期间第一次构建支持 bean 并在 @PostConstruct 期间调用业务逻辑,那么这可能会很耗时.

The renderView() is the step of generating the HTML output based on JSF component tree and the model, starting with UIViewRoot#encodeAll(). So if backing beans are constructed for first time during view render time and invoking business logic during @PostConstruct, then it may happen that this is time consuming.

如果支持 bean 在 getter 方法中而不是在 @PostConstruct 或任何其他一次性发生的生命周期事件侦听器中错误地执行业务逻辑,那么这可能会消耗更多时间.另请参阅为什么 JSF 多次调用 getter.

If backing beans are incorrectly performing business logic in getter methods instead of in @PostConstruct or any other one-time-occurring life cycle event listener, then it may happen that this consumes yet more time. See also Why JSF calls getters multiple times.

这篇关于在服务器请求之后测量 JSF 视图的呈现时间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆