Performance problems in XSLT are sneaky. The stylesheet looks clean, the output is correct, but the transform slows down as the input grows. Most of the time this is caused by expensive selections that are repeated in loops, or by deep // searches that scan the entire tree more often than you expect. The good news is that you can usually fix these issues without turning the stylesheet into unreadable micro-optimizations.
The first step is to examine where you are traversing the document. XSLT processors are optimized for template matching, so prefer xsl:apply-templates and specific match patterns over xsl:for-each with // in the select. When you do need a search, limit it to the smallest possible subtree. A single // at the top-level becomes a full-tree scan each time it runs. If it runs inside another loop, the cost can explode.
Keys are the most important performance feature, and they also improve readability. When you define an xsl:key, you turn a repeated search into a fast lookup. This is especially critical for join-like operations where you match a reference value to another document or a secondary section of the same document. Build the key once, and then use key('id', $value) everywhere. The intent becomes clear: you are doing a lookup, not a scan. If you only use keys occasionally, it can feel like overkill, but it is often the biggest win.












