Relatude has an extremely efficient cache built deeply into the core of the system. That means that you in many situations don't have to worry about performance, but in certain situations you need to optimize the template rendering, here are some great tips!
Test the performance of your template code
Try adding "?WAFPageTimer=true" to the request url on any page. You'll get back information about page rendering in ms. Generally the average page rendering should not exceed 200 ms, this will start to limit the overall capacity of the server (1000/200 = 5 pageviews per sec per CPU) and the user will start to notice some delay on a fast internet connection.
Never make queries using with the DateTime.Now as a parameter
These queries cannot be cahed efficiently and can potentially result in a new SQL every second. Workaround: use a DateTime variable that only changes every hour like this for instance: DateTime.Now.Date.AddHours(DateTime.Now.Hour) . (Or even every minute is better than every second)
Avoid synchronous calls to external websites
Like RSS, Web services etc. Workarounds: Cache the result in an application wide variable updated on the first request each hour or better, use a scheduled task to update the data in the background.
Query only for relevant data
This is kind of obvious, but still often forgotten. Check the number of objects retrieved during a page request using the "?WAFPageTimer=true" parameter. Try to stay below 1000. Badly written functions that renders hierarchical menues are often a good place to start looking. Remember to always add paging to larger queries. Do as much of the filtering as possible in the AQL query, do not leave to much of the processing to in memory LINQ queries and similar.
Avoid too many joins in one statement
Consider de-normalizing the data. You can build complicated and nested joins with the AQL Query objects, but these joins can load the database heavily. As a general rule try to avoid more than 4 types in one query, especially if you are dealing with a database with more than 100 000 objects and it is difficult to cache the queries effectively, due to frequent updates or date based filtering. The workaround is to de-normalize parts of the data, this normally means storing certain information more than once in the database. Add hidden fields to the objects that are updated automaticall in the relevant content events like "OnBeforeUpdate".
Push as much work as possible onto the client
Use output cache on heavy data in masterpages
The built in ASP.Net page cache is very fast, but is mainly time based and therefore not ideal for all use cases. Generally this cache is a good last tuningoption on pages with really high traffic loads and infrequent updates.
Optimize the cache size
Tune the size of the cache size to the memory you have available. The default settings allows for a lot of memory usage, so if you are hosting many installations on one server it makes sense to tune each one. The size limit is specified in web.config:
<add key="WAF.QueryCacheLimit" value="10000" />
<add key="WAF.ContentCacheLimit" value="10000" />