Enable Dark Mode!
an-overview-of-fragment-caching-using-t-cache-in-odoo-16.jpg
By: Nikhil Mathew

An Overview of Fragment Caching Using T-Cache in Odoo 16

Technical Odoo 16

What is fragment caching?

Fragments are part of a website that can be functionally isolated and can be reused.
The main objective is to avoid fetching the data from the backend every time and speed up the browsing experience.
 In order to achieve fragment caching, a new caching mechanism called t-cache has been introduced to Odoo 16, which can be used to speed up the rendering by caching parts of the final document, which may save queries to the database. 

Why and when to use t-cache?                                                

The main objective of this directive is to speed up the rendering by limiting the queries to the database. In order to actually save database queries, it might be necessary to render the template with values that are evaluated lazily. If those lazy values are used in a cached part, they will not be evaluated if the part is available in the cache.
However, it should be used sparingly as it can cause complications. It should be kept in consideration that the t-cache directive is most useful for template parts using values that depend on a limited amount of data. Also, the cache may not be available for different users as they might need to render the cached parts the same way. Another important thing to be considered is that the values in t-cache parts are scoped, which could affect the case where t-set directives are used as the rendering of what comes after it could be different than if there was no t-cache directive.
There should also be other factors to be considered while using the t-cache directive, which can be mainly the popularity of the page where how often does the fragment gets visited, the dynamicity of the page as the content of the page may change with the user type or the content needs to be changed dynamically and lastly, how often the fragment is repeatedly rendered.
  • Simple syntax:
    1. return request.render('survey.survey_void_content', {
    1.                 'survey': survey,           
    1. <template id="survey_void_content" name="Survey: void content">
    1. <t t-cache="survey,prodansweruct">
    1.     <!--    cached content-->
    1.     <div">
    1.         <!--        etc-->
    1.     </div>
    1. </t>
    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.


If you need any assistance in odoo, we are online, please chat with us.



0
Comments



Leave a comment



whatsapp_icon
location

Calicut

Cybrosys Technologies Pvt. Ltd.
Neospace, Kinfra Techno Park
Kakkancherry, Calicut
Kerala, India - 673635

location

Kochi

Cybrosys Technologies Pvt. Ltd.
1st Floor, Thapasya Building,
Infopark, Kakkanad,
Kochi, India - 682030.

location

Bangalore

Cybrosys Techno Solutions
The Estate, 8th Floor,
Dickenson Road,
Bangalore, India - 560042

Send Us A Message