Pergunta
Estou pensando em criar algumas JSP-tags que sempre dão a mesma saída. Por exemplo:
<foo:bar>baz</foo:bar>
sempre de saída:
<div class="bar">baz</div>
Existe alguma maneira de obter um JSP-tag se comportar apenas como saída estática no servlet gerado?
Por exemplo:
out.write("<div class=\"bar\">");
...
out.write("</div>");
em vez de
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...
Fundo
Estou preocupado com o desempenho. Eu não testei isso ainda, mas parece que o servlet gerado faz um monte de algo muito simples, eo desempenho é muito importante.
Mas se se comporta servlet como se a saída foi escrito diretamente na JSP, o custo da produção será zero.
Eu vejo algumas vantagens, fazendo isso. Eu posso mudar o HTML estático ou até mesmo a mudança para algo mais dinâmico, sem editar cada portlet. Em nossa configuração é fácil mudar uma tag, mas muito demorado para mudar a cada JSP que utiliza um elemento específico.
Isto também significa que eu posso forçar os desenvolvedores a algo que não é escrita como
<div class="bar" style="whatever">...</div>
Há ainda mais vantagens, mas se ele custa desempenho nos servidores de produção, provavelmente não vale a pena.
Solução 2
Eu fiz uma performance-teste. Há muito pouca diferença na performance, de modo que não é problema.
Como eu fiz o teste
Eu criei 500 marcas individuais (programaticamente) em uma de nossas bibliotecas de tags. (Por isso, é envolto em um frasco, etc.) todos eles se parecem com isso, com o número como a única diferença:
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();
}
}
e depois de 500 entradas no TLD como este:
<tag>
<name>test0001</name>
<tagclass>XX.XX.XX.XX.Test0001Tag</tagclass>
<bodycontent>JSP</bodycontent>
</tag>
Então eu peguei uma JSP com um pouco de código nele, e fez duas cópias:. Um com HTML estático, e um com as tags
O único com estática 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);%>
-->
O único com 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);%>
-->
O loop foi introduzida porque ambos saíram com zero milissegundos. (Infelizmente eu executar o Windows no trabalho, então eu não obter muita precisão aqui.) O fato de que 500 marcas não fez um atraso de medida de poder poderia ser resposta suficiente, mas eu queria mais, mesmo se a repetição pode permitir alguma otimização.
O resultado por 500 000 tags:
- JSP-tags: 15-19 segundos
- HTML-tags: 12-16 segundos
Portanto, há uma diferença, mas eu acho que é insignificante em comparação com tudo que estava acontecendo a partir dos cliques do usuário para a resposta é processado na tela.
Outros pensamentos
Tanto quanto eu sei a granularidade no Windows é de cerca de 15-16 milissegundos. Então "0 milissegundos" na verdade significa "<16 milissegundos". Um atraso de menos de 16/500 milissegundos pr. tag é bastante aceitável.
Eu tentei com 1000 tags, mas o JSP-compiler estava muito infeliz com isso. I reduzido a 500 etiquetas porque a alternativa era mudar a configuração que invalidaria os meus resultados.
Eu fiz o HTML gerado um HTML-comentário, porque o navegador está na mesma máquina física que o teste-servidor, e eu estava com medo que o navegador levaria muito renderização em tempo CPU, mesmo com um dual-core CPU. A solução mais fácil era para comentar o HTML.
Outras dicas
Estou bastante certo de que o acerto de desempenho será negligeble considerando o código apenas mostrou.
Eu estava pensando ... por que não usar apenas uma planície antiga incluir ?