mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-05 08:35:26 +00:00
200 lines
6.4 KiB
HTML
200 lines
6.4 KiB
HTML
<html>
|
|
<head>
|
|
<title>Optimizing Stylesheets</title>
|
|
<style>
|
|
.comment {
|
|
font-style: italic;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
|
|
<h1>Optimizing Stylesheets</h1>
|
|
|
|
<h2>Overview</h2>
|
|
<p>
|
|
This document outlines optimizations that we can perform on
|
|
stylesheets after a stylesheet is compiled, but before it is executed.
|
|
</p>
|
|
|
|
|
|
<h2>Create AVTs out of xsl:attributes</h2>
|
|
<p>
|
|
People often write stylesheets like
|
|
<pre>
|
|
<LRE>
|
|
<xsl:attribute name="foo">
|
|
text here
|
|
<xsl:value-of select="@bar"/>
|
|
</xsl:attribute>
|
|
</pre>
|
|
This could be optimized into an AVT like
|
|
<pre>
|
|
<LRE foo="text here{@foo}">
|
|
</pre>
|
|
This can be done both in templates and in attribute-sets
|
|
</p>
|
|
|
|
|
|
<h2>Investigate how RTFs are being used</h2>
|
|
<p>
|
|
When only the string-value or double-value of an RTF is being used it
|
|
is unneccesary to create an entire RTF. Instead we could set up a
|
|
string-handler and use the resulting string.
|
|
</p>
|
|
|
|
<p>
|
|
Once we have a node-set() function we could also have a special
|
|
handler that creates that resulting nodeset rather then
|
|
whatever-we-create-once-we-have-real-RTFs. That handler would be set
|
|
up when we can determain that a RTF is used only as argument to the
|
|
node-set() function.
|
|
</p>
|
|
|
|
<p>
|
|
In cases where an RTF is used as parameter in a call to another
|
|
template we could do further analysis to see how that parameter is
|
|
used in that template. Either by first analyzing how all template
|
|
parameters are used in all templates, or by recursivly searching
|
|
the called template when we find that a RTF is used as an argument.
|
|
</p>
|
|
|
|
<p>
|
|
We will still need a catch-all RTF implementation that is used when
|
|
we can't determin how a variable is used, or when it is used in
|
|
multiple different ways.
|
|
</p>
|
|
|
|
|
|
<h2>Inline/calculate constant variables</h2>
|
|
<p>
|
|
Variables that does not have a value that depends on the source
|
|
document can be inlined into the stylesheet. The value of these
|
|
variables could also be calculated before the transformation is
|
|
started.
|
|
</p>
|
|
|
|
<p>
|
|
This can be combined with the previous optimization of RTFs so that
|
|
stylesheets like
|
|
<pre>
|
|
<xsl:variable name="v">_</xsl:variable>
|
|
...
|
|
<xsl:value-of select="concat(@id, $v, foo)"/>
|
|
</pre>
|
|
is executed like
|
|
<pre>
|
|
<xsl:value-of select="concat(@id, '_', foo)"/>
|
|
</pre>
|
|
<p>
|
|
|
|
<p>
|
|
This can be done for both global and local variables.
|
|
</p>
|
|
|
|
|
|
<h2>Resolve cross-references</h2>
|
|
<p>
|
|
Cross-references to named templates, attribute-sets and template-modes
|
|
can be resolved before the stylesheet is executed. That way we don't
|
|
have to search for the template/attribute-set with a certain name, or
|
|
the group of templates for a certain mode.
|
|
</p>
|
|
|
|
<p>
|
|
Note that for apply-imports we won't always know at compile-time which
|
|
mode to seach for templates in.
|
|
</p>
|
|
|
|
|
|
<h2>Resolve variables by index rather then expanded name</h2>
|
|
<p>
|
|
Rather then seaching for variables with a certain name at runtime
|
|
we could remove names for variables/parameters entierly and put all
|
|
variables in an array (possibly a separate array for global variables)
|
|
and then let variable-references in expressions just point to an index
|
|
in that array.
|
|
</p>
|
|
|
|
|
|
<h2>Calculate and use constant AVTs</h2>
|
|
<p>
|
|
A lot of instruction-elements uses AVTs that often are constants in
|
|
stylesheets, such as the data-type parameter to xsl:sort. For xsl:sort
|
|
we could pre-create a finished nodesorter if all AVTs in all
|
|
xsl:sort-elements are constant.
|
|
</p>
|
|
|
|
<p>
|
|
Another example is xsl:element and xsl:attribute where we could use
|
|
LRE-instructions if the AVTs are constant. For xsl:number we could
|
|
create prepare the list of <code>txFormattedCounter</code>s.
|
|
</p>
|
|
|
|
|
|
<h2>Reuse parameter-map if exact same parameters are used</h2>
|
|
<p>
|
|
If a template calls another template and uses the exact same
|
|
parameters we can reuse the same parameter-map.
|
|
<pre>
|
|
<xsl:template name="hsbc_html_body">
|
|
<xsl:param name="appName"/>
|
|
<xsl:param name="title"/>
|
|
<body>
|
|
<xsl:call-template name="hsbc_form">
|
|
<xsl:with-param name="appName" select="$appName"/>
|
|
<xsl:with-param name="title" select="$title"/>
|
|
</xsl:call-template>
|
|
</body>
|
|
</xsl:template>
|
|
</pre>
|
|
</p>
|
|
|
|
<p>
|
|
We have to watch out for default parameter-values as well as
|
|
parameters being specified by the caller of this template but not used
|
|
by this template. I.e. if the parameter "hello" is specified when
|
|
calling the above template.
|
|
</p>
|
|
|
|
<p class="comment">
|
|
All this might make this optimization useless.
|
|
</p>
|
|
|
|
<h2>Combind consecutive LRE items into a txResultBuffer</h2>
|
|
<p>
|
|
When a template contains several consecutive "LRE instructions" such
|
|
as LRE-elements, LRE-attributes and textnodes we can replace their
|
|
instructions with a special instruction that contains a
|
|
<code>txResultBuffer</code>. This buffer would then be flushed when
|
|
the instruction is executed. This can of course not be done for
|
|
LRE-attributes that contains AVTs. Even PI and comment-instructions
|
|
can be included in this buffer if their contents is strictly literal.
|
|
</p>
|
|
|
|
<p>
|
|
The result is that a template like
|
|
<pre>
|
|
<xsl:template match="/">
|
|
<html>
|
|
<body bgcolor="green">
|
|
Here goes pagecontent
|
|
<xsl:apply-templates />
|
|
</body>
|
|
</html>
|
|
</xsl:template>
|
|
</pre>
|
|
Would result in the first <code>txResultBuffer</code> to contain the
|
|
following transactions: eStartElementTransaction,
|
|
eStartElementTransaction, eAttributeTransaction, eCharacterTransaction.
|
|
</p>
|
|
|
|
<p class="comment">
|
|
There is probably a lower limit to when it's worth the effort to
|
|
replace the normal instructions with the buffer-instruction. A single
|
|
"LRE instruction" is probobably better kept as a normal instruction.
|
|
</p>
|
|
|
|
</body>
|
|
</html>
|