[ 
https://jira.jboss.org/browse/RF-8197?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Nick Belaevski resolved RF-8197.
--------------------------------

    Fix Version/s:     (was: 4.0.0.Milestone1)
       Resolution: Out of Date


Not applicable to 4.x: AjaxChildrenRenderer is not used.

> Optimize AjaxChildrenRenderer render component check algorithm
> --------------------------------------------------------------
>
>                 Key: RF-8197
>                 URL: https://jira.jboss.org/browse/RF-8197
>             Project: RichFaces
>          Issue Type: Patch
>      Security Level: Public(Everyone can see) 
>          Components: core
>    Affects Versions: 3.3.2.SR1
>         Environment: Myfaces 1.2.8, Facelets 1.1.15, Tomcat 6.0.20
>            Reporter: Jan Ziegler
>            Assignee: Nick Belaevski
>
> I just realized some possible "lifecycle processing overhead" when doing ajax 
> actions: 
> In render response phase each ajax component is checked for rendering by the 
> method AjaxChildrenRenderer.encodeAjaxComponent(). That - what I could see -  
> is the case when:
> 1) the component“s rendered-attribute is true
> 2) the component is ajaxRendered 
> 3) the componentId is defined in the reRenderId-List
> This also reflects the order of checking, so the first thing to be done is 
> check if the component“s rendered-attribute is true. But this might also lead 
> to additional lifecycle processings when 
>  rendered-conditions are bound to managed beans by el expressions. To 
> evaluate the rendered condition, request scoped managed beans must be 
> created. to my opion this is suboptimal, like in my case the managed bean 
> performs some (time intensive?) actions in its constructor or the rendered 
> conditions relies on a list which must be fetched from the database - and 
> this also happens even if the componentId is not in den reRenderId-List. 
> So why not first evaluate if the componentId is in the reRenderId-List or the 
> component is ajaxRendered and then (if one of this conditions is true) 
> additionally check the rendered-condition?
> This might be accomplished with a small change 
> AjaxChildrenRenderer.encodeAjaxComponent():
> {code}
> public void encodeAjaxComponent(FacesContext context,
>                       UIComponent component, String currentPath, Set<String> 
> ids,
>                       Set<String> renderedAreas) throws IOException {
>               if (component.isRendered()) { // skip not-rendered components.
>                       boolean found = false;
>                       boolean limitToList = 
> AjaxContext.getCurrentInstance(context).isLimitToList();
>                       String elementId = component.getId();
>                       String absoluteId = currentPath + elementId;
>                       if (!ids.isEmpty()) {
>                               // list for rendering may contains absolute id 
> ( best ),
>                               // component Id or client ID
>                               // String clientId = 
> element.getClientId(context);
>                               if (ids.contains(absoluteId) || 
> ids.contains(elementId)) {
>                                       if (log.isDebugEnabled()) {
>                                               log.debug(Messages.getMessage(
>                                                               
> Messages.RENDER_AJAX_AREA_INFO, absoluteId));
>                                       }
>                                       // renderChild(context, element);
>                                       found = true;
>                               }
>                       }
>                       // 
>                       if (!found && limitToList
>                                       && component instanceof NamingContainer
>                                       && noIdUnderPath(absoluteId
>                                                       + 
> NamingContainer.SEPARATOR_CHAR, ids)) {
>                               return;
>                       }
>                       if (!found && !limitToList && component instanceof 
> AjaxOutput) {
>                               if (((AjaxOutput) component).isAjaxRendered()) {
>                                       // renderChild(context, element);
>                                       found = true;
>                               }
>                       }
>                       if (!found) {
>                               if (component instanceof AjaxChildrenEncoder) {
>                                       ((AjaxChildrenEncoder) 
> component).encodeAjaxChild(context,
>                                                       currentPath, ids, 
> renderedAreas);
>                               } else {
>                                       // Special case - for control 
> components, not produced
>                                       // html code - such as message bundles 
> loaders,
>                                       // MyFaces aliases etc. we call 
> encodeBegin/end methods
>                                       // even if components not in rendered 
> areas.
>                                       boolean special = 
> isSpecialElement(context, component);
>                                       if (special) {
>                                               component.encodeBegin(context);
>                                       }
>                                       encodeAjaxChildren(context, component, 
> currentPath, ids,
>                                                       renderedAreas);
>                                       if (special) {
>                                               component.encodeEnd(context);
>                                       }
>                               }
>                       } else {
>                               
> renderedAreas.add(component.getClientId(context));
>                               renderChild(context, component);
>                       }
>               }
>       }
> {code}
> Patched version (the isRendered()-condition is moved the the last else-Block 
> before renderChild() is called and the component will be rendered):
> public void encodeAjaxComponent(FacesContext context,
>                       UIComponent component, String currentPath, Set<String> 
> ids,
>                       Set<String> renderedAreas) throws IOException {
>               boolean found = false;
>               boolean limitToList = 
> AjaxContext.getCurrentInstance(context).isLimitToList();
>               String elementId = component.getId();
>               String absoluteId = currentPath + elementId;
>               if (!ids.isEmpty()) {
>                       // list for rendering may contains absolute id ( best ),
>                       // component Id or client ID
>                       // String clientId = element.getClientId(context);
>                       if (ids.contains(absoluteId) || 
> ids.contains(elementId)) {
>                               if (log.isDebugEnabled()) {
>                                       log.debug(Messages.getMessage(
>                                                       
> Messages.RENDER_AJAX_AREA_INFO, absoluteId));
>                               }
>                               // renderChild(context, element);
>                               found = true;
>                       }
>               }
>               // 
>               if (!found && limitToList
>                               && component instanceof NamingContainer
>                               && noIdUnderPath(absoluteId
>                                               + 
> NamingContainer.SEPARATOR_CHAR, ids)) {
>                       return;
>               }
>               if (!found && !limitToList && component instanceof AjaxOutput) {
>                       if (((AjaxOutput) component).isAjaxRendered()) {
>                               // renderChild(context, element);
>                               found = true;
>                       }
>               }
>               if (!found) {
>                       if (component instanceof AjaxChildrenEncoder) {
>                               ((AjaxChildrenEncoder) 
> component).encodeAjaxChild(context,
>                                               currentPath, ids, 
> renderedAreas);
>                       } else {
>                               // Special case - for control components, not 
> produced
>                               // html code - such as message bundles loaders,
>                               // MyFaces aliases etc. we call encodeBegin/end 
> methods
>                               // even if components not in rendered areas.
>                               boolean special = isSpecialElement(context, 
> component);
>                               if (special) {
>                                       component.encodeBegin(context);
>                               }
>                               encodeAjaxChildren(context, component, 
> currentPath, ids,
>                                               renderedAreas);
>                               if (special) {
>                                       component.encodeEnd(context);
>                               }
>                       }
>               } else if (component.isRendered()) { // skip not-rendered 
> components.
>                       renderedAreas.add(component.getClientId(context));
>                       renderChild(context, component);
>               }
>       }
> {code}

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: 
https://jira.jboss.org/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

       

_______________________________________________
richfaces-issues mailing list
[email protected]
https://lists.jboss.org/mailman/listinfo/richfaces-issues

Reply via email to