Qual é a diferença entre essas abordagens?
Modelos de facelet
Use Facelet templates (como em <ui:composition>
, <ui:include>
e <ui:decorate>
) se você quer dividir principais fragmentos de layout de página em modelos reutilizáveis. Por exemplo, cabeçalho, menu, conteúdo, rodapé, etc.
Exemplos:
Arquivos de tag Facelet
Use os arquivos de tag do Facelet se desejar ter um grupo reutilizável de componentes para prevenir / minimizar a duplicação de código. Por exemplo, um grupo de componentes de etiqueta + entrada + mensagem. A principal diferença com os componentes compostos é que a saída de um arquivo de tag Facelet não representa um único UIComponent
e pode, em algumas circunstâncias, ser a única solução quando um componente composto não é suficiente. Geralmente, ter um <ui:include>
com um ou mais <ui:param>
que passa uma propriedade de bean gerenciado (e, portanto, não um valor codificado permanentemente) é um sinal de que o arquivo de inclusão pode ser melhor um arquivo de tag.
Exemplos:
Componentes compostos
Use componentes compostos se desejar criar um personalizado único e reutilizável UIComponent
com uma única responsabilidade usando XML puro. Esse componente composto geralmente consiste em um monte de componentes existentes e / ou HTML e é renderizado fisicamente como um único componente e deve ser vinculado a uma única propriedade de bean. Por exemplo, um componente que representa uma única java.util.Date
propriedade por 3 <h:selectOneMenu>
componentes dependentes , ou um componente que combina <p:fileUpload>
e <p:imageCropper>
em um único <my:uploadAndCropImage>
referindo uma única com.example.Image
entidade personalizada como propriedade.
Exemplos:
Componentes personalizados
Use um componente personalizado sempre que a funcionalidade não puder ser alcançada com arquivos de tag do Facelet ou componentes compostos, devido à falta de suporte no conjunto de componentes padrão / disponível. Os exemplos podem ser encontrados em todos os lugares no código-fonte de bibliotecas de componentes de software livre , como PrimeFaces e OmniFaces .
Manipuladores de tags
Quando você deseja controlar a construção da árvore de componentes JSF em vez de renderizar a saída HTML, deve usar um manipulador de tags em vez de um componente.
Exemplos:
Projetos de exemplo
Aqui estão alguns exemplos de projetos que utilizam todas as técnicas mencionadas acima.
O desempenho pode ser diferente?
Tecnicamente, a preocupação com o desempenho é insignificante. A escolha deve ser feita com base nos requisitos funcionais concretos e no grau final de abstração, reutilização e manutenção da implementação. Cada abordagem tem seu próprio propósito e limitações bem definidas.
Os componentes compostos, entretanto, têm uma sobrecarga significativa durante a construção / restauração da vista (especificamente: durante o salvamento / restauração do estado da vista). E, nas versões mais antigas do Mojarra, os componentes compostos tinham problemas de desempenho com a atribuição de valores padrão, isso já foi corrigido desde 2.1.13. Além disso, Mojarra teve um vazamento de memória quando um <cc:attribute method-signature>
é usado para expressões de método, basicamente toda a árvore de componentes é referenciada novamente na sessão HTTP, isso foi corrigido desde 2.1.29 / 2.2.8. O vazamento de memória pode ser contornado em versões 2.1 mais antigas, conforme abaixo:
<context-param>
<param-name>com.sun.faces.serializeServerState</param-name>
<param-value>true</param-value>
</context-param>
Ou em versões 2.2 mais antigas, conforme abaixo:
<context-param>
<param-name>javax.faces.SERIALIZE_SERVER_STATE</param-name>
<param-value>true</param-value>
</context-param>
Ainda assim, quando você tem relativamente "muitos" componentes compostos e os javax.faces.STATE_SAVING_METHOD
definiu client
, o desempenho será péssimo. Não abuse dos componentes compostos se desejar apenas a funcionalidade básica que já é possível com um arquivo de inclusão simples ou arquivo de marca. Não use a facilidade de configuração (leia: nenhum *.taglib.xml
arquivo necessário) como uma desculpa para preferir componentes compostos a arquivos de tag.
Ao usar o Mojarra 2.2.10 ou mais antigo, não se esqueça de desativar o período de atualização do Facelets relativamente curto para o modo de produção:
<context-param>
<param-name>javax.faces.FACELETS_REFRESH_PERIOD</param-name>
<param-value>-1</param-value>
</context-param>
Não use esta configuração para desenvolvimento, caso contrário, você terá que reiniciar todo o servidor para que as alterações nos arquivos Facelets sejam refletidas! Mojarra 2.2.11 e mais recente, e MyFaces já assume o padrão -1
quando javax.faces.PROJECT_STAGE
não está definido como Development
.
NamingContainer
, caso contrário, você acabará com problemas de ID duplicado quando o mesmo componente for reutilizado várias vezes.Image
propriedade no feijão.