Version 11.1 by Thomas Mortagne on 2025/05/19

Hide last authors
Thomas Mortagne 9.1 1 {{box cssClass="floatinginfobox" title="**Contents**"}}
2 {{toc/}}
3 {{/box}}
Thomas Mortagne 1.1 4
Thomas Mortagne 9.1 5 = Database =
Thomas Mortagne 1.1 6
Thomas Mortagne 9.1 7 == Index ==
Thomas Mortagne 1.1 8
Thomas Mortagne 5.1 9 Filtering and ordering on a non indexed field (for example, searching for something in the content of a document) will cause very important performance problems as soon as that table starts to contain a lot of entries. Not only for the query you are trying to execute but also for other queries running in the database server.
Thomas Mortagne 1.1 10
Thomas Mortagne 8.1 11 You can also have a similar problems when combining several indexed fields in the same ##WHERE## clause, as, in theory, for this to be fast, you would need to have an index combining those fields. Unfortunately, very often, it's not possible in XWiki to do that (at least with MySQL/MariaDB) because most String columns already have the maximum size accepted for an index, and combining them would make such an index go beyond that limit.
Thomas Mortagne 1.1 12
Thomas Mortagne 3.1 13 The possible alternatives are generally:
Thomas Mortagne 9.1 14
Thomas Mortagne 3.1 15 * Use the Solr ##search## core instead.
Thomas Mortagne 8.1 16 * Do post filtering/ordering on your side (Java, script) instead of the database (but this can cause prove challenging when you need pagination)
Thomas Mortagne 1.1 17
Thomas Mortagne 9.1 18 = Solr =
Thomas Mortagne 6.1 19
Thomas Mortagne 9.1 20 == Commit is slow ==
Thomas Mortagne 6.1 21
Thomas Mortagne 7.1 22 Each commit to Solr can be expensive and reducing the number of commits you are doing when you send a lot of data to Solr generally have a very big speed impact.
Thomas Mortagne 6.1 23
Thomas Mortagne 9.1 24 = Components =
Thomas Mortagne 1.1 25
Thomas Mortagne 9.1 26 == [[Wiki components>>extensions:Extension.WikiComponent Module]] are slow ==
Thomas Mortagne 1.1 27
Thomas Mortagne 3.1 28 Wiki components are discouraged because they are much slower than the alternatives (beside various other problems).
Thomas Mortagne 1.1 29
Thomas Mortagne 1.2 30 If you really need to implement your component in a wiki page, you should take a look at [[extensions:Extension.Script Component]] (which also makes implementing, and especially registering, components in a wiki page a lot easier). What will be produced in the end is technically exactly the same thing as what you get with a component implemented in Java.
Thomas Mortagne 1.1 31
Thomas Mortagne 9.1 32 = Rendering =
Thomas Mortagne 1.1 33
Thomas Mortagne 9.1 34 == When [[implementing a macro>>xwiki:Documentation.DevGuide.Tutorials.WritingMacros]] ==
Thomas Mortagne 1.1 35
36 When you implement your own macro, there are various performance related things that you should be aware of.
37
Thomas Mortagne 9.1 38 === [[Wiki macros>>xwiki:Documentation.DevGuide.Tutorials.WritingMacros.WikiMacroTutorial]] are much slower than [[Java macros>>rendering:Main.ExtendingMacro]] ===
Thomas Mortagne 1.1 39
Thomas Mortagne 3.1 40 So you should try as much as possible to implement Java macros (it's also much easier to write automated tests for Java macros). It's not always very practical to write complex UI in Java, but you can easily execute a [[template>>extensions:Extension.Template Module]] from your Java code.
Thomas Mortagne 1.1 41
Thomas Mortagne 9.1 42 Like with any other component, you can implement a Java macro through a [[extensions:Extension.Script Component]] if you absolutely need your macro to be implemented in a wiki page. What will be produced in the end is technically exactly the same thing as what you get with a macro implemented in Java (so it always have the same features).
Thomas Mortagne 1.1 43
Thomas Mortagne 9.1 44 === Macro preparation ===
Thomas Mortagne 1.1 45
46 {{info}}
Thomas Mortagne 3.1 47 Currently, not supported in Wiki macros.
Thomas Mortagne 1.1 48 {{/info}}
49
50 There are two steps in the execution of a macro:
Thomas Mortagne 9.1 51
Thomas Mortagne 1.1 52 * the preparation
53 * the actual execution
54
Thomas Mortagne 9.2 55 During the preparation step, you get a chance to do everything that does not rely on any contextual information and store the result in the ##MacroBlock## (as attribute). For example message macro, like the info macro, parse and prepare the passed content. It can improve execution time greatly because the ##MacroBlock## is generally part of cached data, so the preparation will be executed only once for potentially many executions.
Thomas Mortagne 1.1 56
Thomas Mortagne 9.1 57 === Isolated execution ===
Thomas Mortagne 1.3 58
59 {{version since="17.3.0"}}
Thomas Mortagne 3.1 60 If your macro does not modify the XDOM around it (which is the case most of the time), it's highly recommended to indicate it:
Thomas Mortagne 1.3 61
Thomas Mortagne 3.1 62 * For Java macros: see [[rendering:Main.ExtendingMacro]]
63 * For wiki macros: see [[xwiki:Documentation.DevGuide.Tutorials.WritingMacros.WikiMacroTutorial]]
Thomas Mortagne 1.3 64 {{/version}}
65
Thomas Mortagne 10.1 66 This will help speed up the macro transformation ordering of macros by reducing a lot the navigation it needs to do in the blocks.
67
Thomas Mortagne 9.1 68 == HTML Macro ==
Thomas Mortagne 1.1 69
Thomas Mortagne 1.6 70 The cleaning part of the HTML macro can be expensive, so using {{code}}clean="false"{{/code}} could have a significant impact on the performance if a lot of them are used.
Thomas Mortagne 1.7 71
Thomas Mortagne 9.1 72 == Preparation ==
Thomas Mortagne 1.7 73
Thomas Mortagne 9.1 74 === Preparing ##Block##s ===
Thomas Mortagne 1.7 75
Thomas Mortagne 1.10 76 Similarly to [[what is explained for macros>>||anchor="HMacropreparation"]], it's a good idea to parse and "prepare" any wiki content you are planning to execute several times. It will generally considerably reduce the execution time.
Thomas Mortagne 1.7 77
Thomas Mortagne 3.1 78 You can do that by calling ##Transformation#prepare(Block block)## in Java. If you don't know which ##Transformation## to apply, apply at least the ##macro## one:
Thomas Mortagne 1.7 79
80 {{code language="java"}}
81 @Inject
82 @Named("macro")
83 private Translation macroTransformation;
84
Thomas Mortagne 1.10 85 private XDOM cachedXDOM;
Thomas Mortagne 1.7 86
Thomas Mortagne 1.10 87 void cacheContent(String wikiContent)
Thomas Mortagne 1.7 88 {
Thomas Mortagne 1.10 89 this.cachedXDOM = parse(wikiContent);
90 this.macroTransformation.prepare(cachedBlock);
Thomas Mortagne 1.7 91 }
92
93 ...
94 {{/code}}
95
Thomas Mortagne 9.1 96 === Compiling Velocity ===
Thomas Mortagne 1.7 97
Thomas Mortagne 1.13 98 If you have the possibility to cache a Velocity script, it's generally a good idea to pre-compile it. In the case of Velocity it means parsing the String into an AST, which can be an expensive step.
Thomas Mortagne 1.7 99
Thomas Mortagne 1.10 100 {{code language="java"}}
101 @Inject
102 private VelocityManager velocityManager;
103
104 private VelocityTemplate cachedVelocity;
105
106 void cacheContent(String velocityScript)
107 {
108 this.cachedVelocity = this.velocityManager.compile(nameAssociatedtoTheScript, velocityScript)
109 }
110
Thomas Mortagne 11.1 111 void evaluate(Writer writer)
Thomas Mortagne 1.10 112 {
113 ...
114 this.velocityManager.getVelocityEngine().evaluate(velocityContext, writer, namespace, this.cachedVelocity);
115 }
Thomas Mortagne 1.11 116
Thomas Mortagne 1.10 117 ...
118 {{/code}}
119
Thomas Mortagne 9.1 120 This is, for example, what the [[##{{velocity}}## macro{{/velocity}}##>>extensions:Extension.Velocity Macro]] is doing as part of it's [[macro preparation step>>||anchor="#HMacropreparation"]].
Thomas Mortagne 1.13 121
Thomas Mortagne 9.1 122 = [[UI extensions>>extensions:Extension.UIExtension Module]] =
Thomas Mortagne 1.7 123
Thomas Mortagne 9.1 124 == Wiki-based UI extensions are slower than Java-based ones ==
Thomas Mortagne 1.7 125
Thomas Mortagne 3.1 126 What is true for generic wiki components and wiki macros is also true for UI extensions.

Get Connected