XForms - Performance Settings


See also

Indexing instance elements by id

[SINCE 2013-02-19 / Orbeon Forms 4.0.1]

You enable an index for the id() function on regular (non-readonly) XForms instances with:

<xf:instance id="my-book" xxf:index="id">

For example:

<xf:instance id="my-book" xxf:index="id">
    <book id="simple_book">
        <chapter id="chapter_1">
            <title>Chapter 1</title>
            <para>Hello world!</para>
        </chapter>
        <chapter id="chapter_2">
            ...
        </chapter>
    </book>
</xf:instance>

You can then use the id() function as follows:

<xf:insert
  ref="id('chapter_2', instance('my-book'))"
  origin="xf:element('chapter', xf:attribute('id', 'chapter_3'))"/>

For more details, see this blog post: Faster XML search with the id() function.

Controlling item sets refreshes with xxf:refresh-items

XForms specifies that items and itemsets are re-evaluated when processing xforms-refresh. This may happen quite often, and may lead to time-consuming re-evaluations especially when there are many or large itemsets.

Orbeon Forms supports an extension attribute, xxf:refresh-items, on the <xf:select> and <xf:select1> elements. When set to true (the default), items and itemsets are re-computed upon xforms-refresh event processing. When set to false, this attribute signals that once computed, the set of items for the control will not be recomputed upon xforms-refresh event processing.

If you know that itemsets do not change over time, setting xxf:refresh-items to false disables refreshing of the items during xforms-refresh and may yield significant performance improvements. Example:

<xforms:select1 ref="state" xxforms:refresh-items="false"><xforms:label>State</xforms:label><xforms:item><xforms:label>[Select...]</xforms:label><xforms:value/></xforms:item><xforms:itemset nodeset="instance('schema-instance')/xs:simpleType[@name = 'state']//xs:enumeration"><xforms:label ref="@value"/><xforms:value ref="@value"/></xforms:itemset></xforms:select1>

In addition, for selection controls within repeats with xxforms:refresh-items="false", only a single itemset is computed for all repeat iterations for the given control. This allows large repeats with costly itemsets to compute an itemset only once. This only makes sense if all iterations of the repeat must show the same itemsets for the given selection control.

xxf:internal appearance on <xf:group>

<xf:group> supports the xxf:internal appearance, which causes the group to have no representation at all on the client:

<xforms:group model="my-model" appearance="xxf:internal"><!-- More XForms controls --></xforms:group>

In general you won't have a need for this appearance, but it is useful as an optimization, as it leads to less HTML sent to the client. You may use it when a group is used only to change the in-scope evaluation context for nested controls and when you don't need changes to relevance which apply directly to the group to be reflected in the client.

Full update mechanism

Availability

This is an Orbeon Forms PE feature.

Rationale

By default, the XForms engine handles Ajax updates on a per-control basis. The Ajax response produced by the server contains the new "state" for each control, and if a large number of controls need to be updating, the interpreting a large number of updates and doing the corresponding changes to the DOM can be quite time consuming. In those cases, it might be faster for the server to send the full HTML so the browser can update the form in "one" operation. To trigger this mode, you need to:
  • Place the xxf:update="full" attribute on a control if you know that nested content will have very large updates, for example a large repeat with hundreds of items. In most cases, you will place it on an <xf:group>.
  • Be in "span" mode, as the xxf:update="full" is not supported with the "nospan" layout.

<xf:group xxf:update="full">
    <xf:repeat nodeset="value">
        <div>
            <xf:output value="."/>
        </div>
    </xf:repeat>
</xf:group>

Configuration

The following property controls the approximate number of incremental updates beyond which the server sends a full update to the client:

<property as="xs:integer" name="oxf.xforms.ajax.update.full.threshold" value="20"/>

Using xxf:update="full" is not always the right thing to do (and this is why this is a hint you need to specify explicitly rather than the default behavior):
  • When you use a xxf:update="full" on a control, the server keeps the HTML markup for the content under that control. Also, when there are updates under that control, the server need to consider whether to send them incrementally (if the number of below a certain threshold), or as a full update. This creates some overhead compared to the case where you don't have a xxf:update="full".

  • You can use the xxf:update="full" on most XForms elements, but it will run less efficiently when used on:
    • An <xf:repeat>
    • And <xf:group> that is a around an <xh:tr> or <xh:td>.

    As a rule of thumb, you will get the most performance out of xxf:update="full" when using it on an <xf:group> which is not around an <xf:tr> or <xf:td>.
Comments