tags:

views:

456

answers:

3

I am considering creating some JSP-tags that will always give the same output. For example:

<foo:bar>baz</foo:bar>

Will always output:

<div class="bar">baz</div>

Is there any way to get a JSP-tag to behave just like static output in the generated servlet?

For example:

out.write("<div class=\"bar\">");
...
out.write("</div>");

in stead of

x.y.z.foo.BarTag _jspx_th_foo_bar_0 = new x.y.z.foo.BarTag();
_jspx_th_foo_bar_0.setPageContext(pageContext);
_jspx_th_foo_bar_0.setParent(null);
_jspxTagObjects.push(_jspx_th_foo_bar_0);
int _jspx_eval_foo_bar_0 = _jspx_th_foo_bar_0.doStartTag();
etc...
etc...
etc...

Background

I'm worried about performance. I haven't tested this yet, but it looks like the generated servlet does a lot for something very simple, and performance is very important.

But if the servlet behaves as if the output was written directly in the JSP, the cost in production will be zero.

I see a few advantages by doing this. I can change the static HTML or even change to something more dynamic, without editing every portlet. In our setup it's easy to change a tag, but very time-consuming to change every JSP that uses a specific element.

This also means I can force developers to not write something like

<div class="bar" style="whatever">...</div>

There is even more advantages, but if it costs performance on the production servers, it's probably not worth it.

A: 

I was wondering... why not use just a plain old include?

abahgat
The short answer: It has very few advantages, compared to using jsp-tags.If I explained our setup in detail, I'm sure you would think so too. But I do see your point, includes are very "cheap".
myplacedk
+2  A: 

I am quite certain the performance hit will be negligeble considering the code you just showed.

Jonas Klemming
A: 

I made a performance-test. There is very little difference in performace, so that is no problem.

How I made the test

I created 500 individual tags (programmatically) in one of our tag libraries. (So it is wrapped in a jar etc.) They all look like this, with the number as the only difference:

package XX.XX.XX.XX

import java.io.IOException;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;

public class Test0001Tag extends TagSupport {

    public Test0001Tag() {
    }

    public int doStartTag() throws JspException {

     try {
      pageContext.getOut().print("<div class=\"Test0001\">");
     } catch (IOException e) {
      throw new JspException(e);
     }
     return EVAL_BODY_INCLUDE;
    }

    public int doEndTag() throws JspException {
     try {
      pageContext.getOut().print("</div>");
     } catch (IOException e) {
      throw new JspException(e);
     }
     return EVAL_PAGE;
    }

    public void release() {
        super.release();
    }
}

And then 500 entries in the TLD like this:

<tag>
   <name>test0001</name>
   <tagclass>XX.XX.XX.XX.Test0001Tag</tagclass>
   <bodycontent>JSP</bodycontent> 
</tag>

Then I grabbed a JSP with a little code in it, and made two copies: One with static HTML, and one with tags.

The one with static HTML:

<!-- 
<%long start = System.currentTimeMillis();%>
<% for (int i = 0; i < 1000; i++) { %>
<div class="Test0001">X</div>
<div class="Test0002">X</div>
<div class="Test0003">X</div>
...
<div class="Test0498">X</div>
<div class="Test0499">X</div>
<div class="Test0500">X</div>
<% } %>
<%System.out.println(System.currentTimeMillis()-start);%>
 -->

The one with tags:

<!-- 
<%long start = System.currentTimeMillis();%>
<% for (int i = 0; i < 1000; i++) { %>
<bddesign:test0001>X</bddesign:test0001>
<bddesign:test0002>X</bddesign:test0002>
<bddesign:test0003>X</bddesign:test0003>
...
<bddesign:test0498>X</bddesign:test0498>
<bddesign:test0499>X</bddesign:test0499>
<bddesign:test0500>X</bddesign:test0500>
<% } %>
<%System.out.println(System.currentTimeMillis()-start);%>
 -->

The loop was introduced because both came out with zero milliseconds. (Unfortunately I run Windows at work, so I don't get much precision here.) The fact that 500 tags didn't make a measure-able delay could be answer enough, but I wanted more, even if the repetition may allow for some optimization.

The result for 500 000 tags:

  • JSP-tags: 15-19 seconds
  • HTML-tags: 12-16 seconds

So there is a difference, but I think it's insignificant compared to everything else going on from the user clicks to the answer is rendered on the screen.

Other thoughts

As far as I know the granularity in Windows is about 15-16 milliseconds. So "0 milliseconds" actually means "<16 milliseconds". A delay of less than 16/500 milliseconds pr. tag is quite acceptable.

I tried with 1000 tags, but the JSP-compiler was very unhappy with that. I reduced to 500 tags because the alternative was to change the setup which would invalidate my results.

I made the generated HTML a HTML-comment, because the browser is on the same physical machine as the test-server, and I was afraid that the browser would take too much CPU-time rendering, even with a dual-core CPU. The easy solution was to comment the HTML.

myplacedk