Here the cache expression is used as a key to store so what is put inside a cache attribute is important, and everything in the cached fragment will only be evaluated during the initial rendering and ignored in the subsequent rendering.
Key expression:
It can be defined as a list of elements that are evaluated to generate a unique key for the cache value. Different key expressions include:
1. Python statement:
Eg:
<t t-cache="datetime.datetime.now()">
<!-- cached content-->
<div>
<t t-esc="datetime.datetime.now()"/>
</div
</t>
Also we could give values, eg 42: t-cache="42"
Here the key expression is 42, and it will be evaluated as a Python expression and will be used to generate the cache key and thus allows different cache values for the same template.
2. Recordset
Eg: <t t-cache="pricelist,product">
When the key expression is a tuple or a list it will be searched while generating the cache key. For the case where the key expression returns a recordset, then the model, ids, and their corresponding write_date will be used to generate the cache key. And if a module modifies the record, the write_date being modified, the cached value is discarded.
3. Qweb context values (t-value)
Eg:
<t t-set="record" t-value="object.env['crm.team'].search([], limit=1)"/>
<t t-cache="record">
<!-- cached content-->
<div t-attf-id="crm-{record.id}">
<!-- etc-->
</div>
</t>
Context variables outside the cache can also be used.
4. Conditionals:
Eg:
<div t-cache="record,bool(condition)">
<span t-if="condition" t-field="record.partner_id.name">
<span t-else="" t-field="record.partner_id" t-options-widget="contact">
</div>
In this case, there may be values ??(string) in the cache corresponding to each record already returned with a true condition, as well as for the false condition.
NOTE: : If the key expression returns a Falsy value, then the content will not be cached.
t-cache and scoped values.
Values in t-cache are scoped. Hence there will be a change in behavior between having the t-cache on the parent nodes.
Example:
<div>
<t t-set="a" t-value="1"/>
<inside>
<t t-set="a" t-value="2"/>
<t t-out="a"/>
</inside>
<outside t-out="a"/>
<t t-set="b" t-value="1"/>
<inside t-cache="True">
<t t-set="b" t-value="2"/>
<t t-out="b"/>
</inside>
<outside t-out="b"/>
</div>
Will render:
<div>
<inside>2</inside>
<outside>2</inside>
<inside>2</inside>
<outside>1</inside>
</div>
t-nocache
It can be used when you want to cache part of a template with t-cache, but a small piece needs to remain dynamic and be evaluated at cache times.
To make a small piece of a cached template to be dynamic and be evaluated at cache time, we can use the t-nocache
Eg:
<template id="header_wishlist_link" name="Header Wishlist Link">
<t t-nocache="The wishlist may vary and depends on the user.">
</t>
</template>
However, the part in t-nocache will not have access to the t-set value of the template. Only the values ?? provided by the controller are accessible there. Here the key is unimportant, and It is also advisable that the attribute given inside the t-nocache is self-explaining as it explains why this part is made dynamic.
primitive values in the cache:
It is also possible to cache the values generated in the template and can be used using the directive t-no-cache-*= "expr" where * is the name of the chosen value and expr the python expression so the result will be cached. The cached value must be a primitive type.
Eg:
<section t-cache="records">
<article t-foreach="records" t-as="record">
<header>
<title t-field="record.name"/>
</header>
<footer t-nocache="This part has a dynamic counter and must be rendered all the time." t-nocache-partner_name="record.partner_id.name">
<span t-out="partner_name"/>
</footer>
</article>
</section>
Debugging
http://localhost:8016/@/shop?debug=disable-t-cache
This allows to easily enable or disable the caching mechanism on a per-request basis.
Conclusion
Fragment caching using t-cache in Odoo can be an effective way to improve performance and reduce the load on the database server. This can lead to significant performance improvements, especially for pages that have a large amount of translated content.
However, it's important to keep in mind that caching can also have its downsides. Caching may not be suitable for pages that have frequently changing content, and bugs related to caching can be annoying as the values are based on the state of the system, and it will be difficult to reproduce the errors.
Overall, using fragment caching with t-cache can be a powerful tool for improving the performance of an Odoo application, but it's important to carefully consider the trade-offs and use it judiciously based on the specific needs of the application.