This forum is closed to new posts and responses. New discussions are now taking place in the IBM Developer Answers forum.



Feb 16, 2012, 3:29 AM
22 Posts

Partial refresh is executed on IDs that are not part of the partial refreh

  • Category: Server Side JavaScript
  • Platform: Windows
  • Release: 8.5.3
  • Role: Developer
  • Tags: partial refresh
  • Replies: 10
We have the following situation:
 
Ozr application is build with the lates version of extensionLibrary. The basic layout is a applicationLayout component with a left Sidebar and a content area.
The content area contains a tabContainer and on the first tabPane some xe:widgetContainer
The widget container contains a DataTable; The values for the DataTable are calculated. 
 
In the left sidebar, we do a search on a view using the keys parameter
 
        <xp:this.data>
            <xp:dominoView var="view_company" viewName="(COMPANY)"
                keys="#{javascript:viewScope.qry_company}" />
        </xp:this.data>
 
The search is triggered by pressing the enter key and does a partial refresh on the pnl_entries_company
 
        <xp:div id="pnl_entries_company" style="overflow:auto;">
            <xc:cc_SearchBarNoResults prop_componentID="rpt_company" />
            <xp:repeat id="rpt_company" var="rowCompanyCol" value="#{view_company}"
                removeRepeat="false" repeatControls="false" rows="50">
                <xp:div themeId="cois.searchbar.parent">
 
The problem we have seen is that although the partial refresh is done on pnl_entries_company is executed, also the DataTable in the widgetContainer is updated TWICE during the partial refresh.
 
 
I have tested with a computed field inside the widgetContainer; this field is NOT updated during the partial refresh, but the code in this.value is trigged TWICE. 
 
We do not have any clue, why this happens, but it has a huge impact on performance. 
Anyone to shed a light on this?? 
Feb 17, 2012, 10:09 AM
22 Posts
Re: Partial refresh is executed on IDs that are not part of the partial refreh
To exclude the complexity of our application as an issue, I was able to reproduce the behaviour using the following code
 
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
    <xp:button value="Label" id="button1">
        <xp:eventHandler event="onclick" submit="true"
            refreshMode="partial" refreshId="col1" />
    </xp:button>
    <xp:table>
        <xp:tr>
            <xp:td id="col1">
                <xp:text escape="true" id="computedField2" value="#{javascript:@Now()}">
                    <xp:this.converter>
                        <xp:convertDateTime type="both" />
                    </xp:this.converter>
                </xp:text>
            </xp:td>
            <xp:td id="col2">
                <xp:text escape="true" id="computedField1" value="#{javascript:@Now()}">
                    <xp:this.converter>
                        <xp:convertDateTime type="both" />
                    </xp:this.converter>
                </xp:text>
                <xp:dataTable id="dataTable1" rows="30">
                    <xp:this.value><![CDATA[#{javascript:
                    print('You shall not refresh');
}]]></xp:this.value>
                    <xp:column id="column1" />
                </xp:dataTable>
            </xp:td>
        </xp:tr>
    </xp:table>
</xp:view>

 
The datatable in col2 is refreshed every time, the button is pressed ( not expected that ); the computedText is not ( which is the expected behaviour). 
Feb 17, 2012, 4:18 PM
272 Posts
Re: Partial refresh is executed on IDs that are not part of the partial refreh
Hi Ulrich,
 
as far as I know this is normal behaviour for all "data containing" elements, f.e. dataTables, repeatControls, dataContexts etc.
Regardless of which node has to be refreshed. Regardless of partial execution mode is set or not.
 
Sven
 
Feb 18, 2012, 2:00 AM
22 Posts
Re: Partial refresh is executed on IDs that are not part of the partial refreh
Thanks for the response.
 
If this is a normal behaviour, I just wonder if anyone ever has used datatables and other with larger amount of data than only a set of test data.
This behaviour had (HAS)  a HUGE performance impact in our application and we really had trouble to justify this. I did not find any hint about this.
And I even wonder more that this is the normal behaviour since XPages came out. And nobody ever intended to fix this??
 
Feb 21, 2012, 11:24 AM
22 Posts
Re: Partial refresh is executed on IDs that are not part of the partial refreh
PHAN8RPL3D has been logged to track this
Mar 2, 2012, 6:56 PM
122 Posts
Re: Partial refresh is executed on IDs that are not part of the partial refreh
Setting refreshId is not going to be enough. That just tells the server what part of the component tree needs to be passed back to the browser in the response. It still evaluates everything, because values in the area being passed back to the browser may be affected by dataContexts or anything else elsewhere on the page.
 
That's where execMode="partial" comes in. That tells the browser "You don't need to bother about updating the whole component tree. Just update area XXX". The area to update is defined with execId property of the eventHandler. If you set these, the dataContext won't get recalculated.
 
Just bear in mind that if anything in your execId area relies on values outside of it, then the values used will not get updated.
 
I'll blog about it over the weekend and post a link.
Mar 5, 2012, 4:49 AM
122 Posts
Re: Partial refresh is executed on IDs that are not part of the partial refreh
Currently with execMode dataContexts outside of the execId area are still recalculated during the Render Response phase. Uses execMode and execId prevents them being recalculated during the Apply Request Values phase.
 
It looks like the recalculation of components outside the execId area is restricted to data components. Rendered properties and values of Computed Fields outside the execId area don't get recalculated at all during the partial refresh.
Mar 6, 2012, 5:05 PM
272 Posts
Re: Partial refresh is executed on IDs that are not part of the partial refreh
Yes, this is exactly the problem: Even if just a part of the component tree is refreshed and/or recalculated, other data containing components like repeat controls, data tables, data context variables etc. are recalculated (multiple times if not using partial execution).
 
This can hava a huge impact on performance of a XPages application: If you are using multiple partial refreshes of different areas of a XPage, the recalculation will be made for *every* refresh (even by using partial execution). Even if you click on a pager (which uses partial execution), all data containing elements are recalculated...
 
I have added a XSnippet which can prevent the recalculation if not required:
 
It is just a simple workaround and can only be used with serializable data.
 
Sven
 
Aug 24, 2012, 5:58 AM
2 Posts
Re: Partial refresh is executed on IDs that are not part of the partial refresh
Hi, the solution here is to enable partial execution (in Designer, the Events view, check-box "Set partial execution mode") which updates the xp:eventHandler tag with execMode="partial" And to verify that the xsp.properties file in the application contains xsp.ajax.renderwholetree=false That option is present by default in applications created in Domino Designer 8.5.2 or later - you can set it manually in 8.5.1. [For more on the renderwholetree option see the XPages Portable Command Guide which has a detailed discussion.] So the example provided becomes like so: Updated Source PHAN8RPL3D Updated sample With execMode="partial" and xsp.properties option xsp.ajax.renderwholetree=false the problem does not occur - clicking the button does not give the print statement from col2 on the server console. To explain what's going on there involves a discussion of the JSF lifecycle and the restricted lifecycle(s) used in partial update requests. Detailed Explanation [There is some more discussion of the lifecycle here; http://www-10.lotus.com/ldd/ddwiki.nsf/dx/xpagesnodatavalidation.htm ] A partial update (like a full page submission) is a sequence of phases. The values of input controls in the browser are posted to the server, then on the server the server-side control tree is restored, the posted values are applied to temporary locations, values are validated using the validators and converters, values are saved to the document fields, then the event action is executed, the control tree is rendered to HTML (computing any values as needed), the response is received in the browser, and (for partial update) the old HTML content is removed and the new HTML content is inserted. For a full page submission each of the server-side phases is executed over all the controls in sequence, so all of the controls save values to temporary locations, then all of the controls validate, then all of the values are saved, etc. For a partial update submission, the phases do occur in sequence, but some phases only apply to the subset of controls indicated by the refreshId, some phases apply to all the controls, and some phases only apply to the subset of controls indicated by the execId. The exact behavior depends on how the partial update submission is configured in the Event Handler for the control, the xsp.properties options for the application (and in any Dynamic Content control in the XPage). For the early phases - copy posted values, validate, save to document fields - which controls are processed depends on the execMode property in the Event Handler (i.e. the "Set partial execution mode" checkbox in the Events tab in Designer). When the execMode property is absent, the early phases will process all of the controls in the tree. [So why would the print statement only appear once instead of for each phase? Any data that's evaluated is cached through the early phases and the execute action phase, and the cache is cleared before the final render, so that any changes to the data are read from the NSF layer.] When the execMode property is present (execMode="partial"), then the early phases are restricted to the control area specified by the execId property. If you haven't configured the execId for the Event Handler, then by default the execId will be the Button (or whatever control is the Event Handler's parent). To find the control for the execId it does an "invokeOnComponent" search through the control tree, which will publish container data sources of the control area and xp:panel data sources, but won't publish dataTable or viewPanel data sources, nor data sources in irrelevant Custom Controls. The execute event action phase always applies to a single control - the Event Handler. The final phase of HTML generation is not effected by the execMode property, only by the refreshId and by the renderwholetree option mentioned above. When renderwholetree=false, the phase does an "invokeOnComponent" search for the refreshId control, then it renders the HTML for that control and its children (and the Script Collector for the page) and returns the HTML to the browser. So the original server-side behavior was; 1. Restore control tree. 2. Apply posted values for all controls, including iterating through the dataTable control multiple times, for each of the rows being displayed in the datatable. That phase will compute and cache any data sources encountered. That's where the print statement was output. 3. Validate all controls, including iterating through the dataTable multiple times. 4. Save all values, including iterating through the dataTable multiple times. 5. Execute the Event Handler control. 6. In the render phase, do an "invokeOnContainer" search for the refreshId control, render the control to generate the HTML. The new server-side behavior with execMode=partial is: 1. Restore the control tree. 2. Apply posted values to the execId area (using an "invokeOnContainer" search to find that control). 3. Validate the execId area (another "invokeOnContainer" search), 4. Save values in the execId area (another "invokeOnContainer" search), 5. Execute the Event Handler control. 6. In the render phase, do an "invokeOnContainer" search for the refreshId control, render the control to generate the HTML. Let us know if there are still problems with that setting enabled.
Aug 24, 2012, 8:48 AM
2 Posts
Re: Partial refresh is executed on IDs that are not part of the partial refreh
Reposting the response due to some formatting problems:
 
Hi, the solution here is to enable partial execution (in Designer, the Events view, check-box "Set partial execution mode")
which updates the xp:eventHandler tag with execMode="partial"
And to verify that the xsp.properties file in the application contains
xsp.ajax.renderwholetree=false
That option is present by default in applications created in Domino Designer 8.5.2 or later - you can set it manually in 8.5.1.
[For more on the renderwholetree option see the XPages Portable Command Guide which has a detailed discussion.]
 
So the example provided becomes like so:
Updated Source
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
PHAN8RPL3D Updated sample<xp:br/>
With execMode="partial"<xp:br/>
and xsp.properties option <xp:br/>
xsp.ajax.renderwholetree=false<xp:br/>
the problem does not occur - clicking the button <xp:br/>
does not give the print statement from col2 on the server console.<xp:br/>
<xp:button value="Refresh Table Column 1" id="button1">
<xp:eventHandler event="onclick" submit="true"
refreshMode="partial" refreshId="col1" execMode="partial" />
</xp:button>
<xp:table border="1">
<xp:tr>
<xp:td id="col1" style="border:solid blue thin">
<xp:text escape="true" id="computedField2" value="#{javascript:@Now()}">
<xp:this.converter>
<xp:convertDateTime type="both" />
</xp:this.converter>
</xp:text>
</xp:td>
<xp:td id="col2" style="border:solid blue thin">
<xp:text escape="true" id="computedField1" value="#{javascript:@Now()}">
<xp:this.converter>
<xp:convertDateTime type="both" />
</xp:this.converter>
</xp:text>
<xp:dataTable id="dataTable1" rows="30">
<xp:this.value><![CDATA[#{javascript:
print('You shall not refresh');
}]]></xp:this.value>
<xp:column id="column1">
</xp:column>
</xp:dataTable>
</xp:td>
</xp:tr>
</xp:table>
</xp:view>
 
To explain what's going on there involves a discussion of the JSF lifecycle and the restricted lifecycle(s) used in partial update requests.
Detailed Explanation
[There is some more discussion of the lifecycle here; http://www-10.lotus.com/ldd/ddwiki.nsf/dx/xpagesnodatavalidation.htm ]
A partial update (like a full page submission) is a sequence of phases. The values of input controls in the browser are posted to the server,
then on the server the server-side control tree is restored, the posted values are applied to temporary locations,
values are validated using the validators and converters, values are saved to the document fields,
then the event action is executed, the control tree is rendered to HTML (computing any values as needed),
the response is received in the browser, and (for partial update) the old HTML content is removed and the new HTML content is inserted.
For a full page submission each of the server-side phases is executed over all the controls in sequence,
so all of the controls save values to temporary locations, then all of the controls validate, then all of the values are saved, etc.
For a partial update submission, the phases do occur in sequence, but some phases only apply to the subset of controls indicated by the refreshId,
some phases apply to all the controls, and some phases only apply to the subset of controls indicated by the execId.
The exact behavior depends on how the partial update submission is configured in the Event Handler for the control,
the xsp.properties options for the application (and in any Dynamic Content control in the XPage).
For the early phases - copy posted values, validate, save to document fields -
which controls are processed depends on the execMode property in the Event Handler
(i.e. the "Set partial execution mode" checkbox in the Events tab in Designer).
When the execMode property is absent, the early phases will process all of the controls in the tree.
[So why would the print statement only appear once instead of for each phase? Any data
that's evaluated is cached through the early phases and the execute action phase,
and the cache is cleared before the final render, so that any changes to the data are read from the NSF layer.]
When the execMode property is present (execMode="partial"), then the early phases are restricted to the control area specified
by the execId property. If you haven't configured the execId for the Event Handler, then by default the execId will be the Button
(or whatever control is the Event Handler's parent). To find the control for the execId
it does an "invokeOnComponent" search through the control tree, which will publish container data sources of the control area
and xp:panel data sources, but won't publish dataTable or viewPanel data sources, nor data sources in irrelevant Custom Controls.
The execute event action phase always applies to a single control - the Event Handler.
The final phase of HTML generation is not effected by the execMode property,
only by the refreshId and by the renderwholetree option mentioned above.
When renderwholetree=false, the phase does an "invokeOnComponent" search for the refreshId control,
then it renders the HTML for that control and its children (and the Script Collector for the page) and returns the HTML to the browser.

So the original server-side behavior was;
1. Restore control tree. 2. Apply posted values for all controls,
including iterating through the dataTable control multiple times, for each of the rows being displayed in the datatable.
That phase will compute and cache any data sources encountered.
That's where the print statement was output.
3. Validate all controls, including iterating through the dataTable multiple times.
4. Save all values, including iterating through the dataTable multiple times.
5. Execute the Event Handler control.
6. In the render phase, do an "invokeOnContainer" search for the refreshId control, render the control to generate the HTML.
 
The new server-side behavior with execMode=partial is:
1. Restore the control tree. 2. Apply posted values to the execId area (using an "invokeOnContainer" search to find that control).
3. Validate the execId area (another "invokeOnContainer" search),
4. Save values in the execId area (another "invokeOnContainer" search),
5. Execute the Event Handler control.
6. In the render phase, do an "invokeOnContainer" search for the refreshId control, render the control to generate the HTML.
 
Let us know if there are still problems with that setting enabled.
 
Aug 24, 2012, 9:31 AM
298 Posts
And see Paul Wither's excellent blog entry on this
http://www.intec.co.uk/partial-execution-mode-probably-the-most-powerful-xpages- feature-you-dont-use/

This forum is closed to new posts and responses. New discussions are now taking place in the IBM Developer Answers forum.