You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何计算Spring MVC中JSP模板的渲染耗时?

计算Spring MVC中JSP模板渲染耗时的可行方案

当然有靠谱的办法!针对Spring MVC搭配JSP开发的场景,我给你几个精准计算JSP模板渲染耗时的方案,都是实际项目里验证过的,完全能满足你只关注模板渲染阶段的需求:

方案1:JSP页面内直接埋点(快速验证用)

这个方案最直接,适合临时验证单个页面的渲染耗时,不需要修改后端代码:

  • 在JSP的最顶部(页面指令<%@ page ... %>之后)添加时间戳记录:
    <% long renderStart = System.currentTimeMillis(); %>
    
  • 在JSP的最末尾(所有页面内容结束后)计算耗时并输出/记录:
    <%
    long renderEnd = System.currentTimeMillis();
    long renderTime = renderEnd - renderStart;
    // 可以用日志框架输出,比如SLF4J
    // org.slf4j.LoggerFactory.getLogger(getClass()).info("当前JSP渲染耗时:{}ms", renderTime);
    // 或者简单打印到控制台
    System.out.println("JSP [" + request.getRequestURI() + "] 渲染耗时:" + renderTime + "ms");
    %>
    
  • 优点:零后端代码修改,快速上手;缺点:需要给每个要监控的JSP手动加代码,维护成本高,嵌套include的页面如果也加埋点会重复计算。

方案2:扩展Spring的InternalResourceView(全局统一监控)

Spring MVC默认用InternalResourceView处理JSP视图,我们可以继承这个类,重写渲染方法来全局监控所有JSP的耗时:

  1. 自定义View类:
    import org.springframework.web.servlet.view.InternalResourceView;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.util.Map;
    
    public class TimedInternalResourceView extends InternalResourceView {
        private static final Logger logger = LoggerFactory.getLogger(TimedInternalResourceView.class);
    
        @Override
        protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
            long start = System.currentTimeMillis();
            // 调用父类的渲染逻辑,也就是实际的JSP渲染
            super.renderMergedOutputModel(model, request, response);
            long end = System.currentTimeMillis();
            // 获取视图名称(优先取BeanName,没有的话取URL)
            String viewName = getBeanName() != null ? getBeanName() : getUrl();
            logger.info("JSP视图 [{}] 渲染耗时:{}ms", viewName, end - start);
        }
    }
    
  2. 配置视图解析器使用自定义View:
    • 如果是XML配置:
      <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
          <property name="viewClass" value="com.yourpackage.TimedInternalResourceView"/>
          <property name="prefix" value="/WEB-INF/jsp/"/>
          <property name="suffix" value=".jsp"/>
      </bean>
      
    • 如果是Java配置:
      import org.springframework.context.annotation.Bean;
      import org.springframework.context.annotation.Configuration;
      import org.springframework.web.servlet.view.InternalResourceViewResolver;
      
      @Configuration
      public class WebMvcConfig {
          @Bean
          public ViewResolver viewResolver() {
              InternalResourceViewResolver resolver = new InternalResourceViewResolver();
              resolver.setViewClass(TimedInternalResourceView.class);
              resolver.setPrefix("/WEB-INF/jsp/");
              resolver.setSuffix(".jsp");
              return resolver;
          }
      }
      
  • 优点:全局生效,所有JSP的渲染耗时自动记录,不需要修改任何JSP;缺点:需要自定义View类,对Spring MVC视图机制有一点基础认知。

方案3:Spring AOP拦截渲染方法(解耦式监控)

如果不想修改View类,用AOP切面来拦截JSP渲染的核心方法,实现解耦式的耗时监控:

  1. 编写切面类:
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.springframework.stereotype.Component;
    import org.springframework.web.servlet.view.InternalResourceView;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    @Aspect
    @Component
    public class JspRenderTimeAspect {
        private static final Logger logger = LoggerFactory.getLogger(JspRenderTimeAspect.class);
    
        // 拦截InternalResourceView的renderMergedOutputModel方法
        @Around("execution(* org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(..))")
        public Object recordRenderTime(ProceedingJoinPoint joinPoint) throws Throwable {
            long start = System.currentTimeMillis();
            // 执行原有的渲染逻辑
            Object result = joinPoint.proceed();
            long end = System.currentTimeMillis();
            // 获取当前视图对象
            InternalResourceView view = (InternalResourceView) joinPoint.getTarget();
            String viewName = view.getBeanName() != null ? view.getBeanName() : view.getUrl();
            logger.info("JSP视图 [{}] 渲染耗时:{}ms", viewName, end - start);
            return result;
        }
    }
    
  2. 开启Spring AOP支持:在你的Spring配置类上添加@EnableAspectJAutoProxy注解。
  • 优点:完全解耦,不需要修改View类和JSP,全局监控;缺点:需要熟悉AOP语法,确保切面能覆盖所有JSP视图的渲染方法。

注意事项

  • 以上方案计算的都是服务器端JSP生成HTML的时间,不包含浏览器请求静态资源(图片、CSS、JS)的时间,正好符合你只关注模板渲染阶段的需求。
  • 如果用日志记录耗时,建议用SLF4J+Logback/Log4j2这类成熟的日志框架,方便后续分析。

内容的提问来源于stack exchange,提问作者Sabrina

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 09:04:01