Power Pages: Cache test dummies

Nick DoelmanDyn365CE2 weeks ago6 Views

What is Power Pages caching?

Sooner or later, while you are configuring a new Power Pages website, you are going to run into the concept of caching. What is it, why does it matter? And why does Nick Hayduk post memes about it?

Caching in web applications refers to storing frequently accessed data (such as web pages, database queries, or API responses) in a readily accessible location to improve performance and reduce server load. When a user requests data, the application serves the cached version if it’s still valid, avoiding the need to generate or retrieve it from the source again.

In Power Pages, this means that when you retrieve data to display on a webpage from Dataverse, for up to 15 minutes, what you see won’t get updated from Dataverse even if you reload the page.

Too lazy to read? No problem! Here is the video version of this blog post (but the code mentioned in the video is below 👇)

How caching works

For example:

We see a list of records on a list on a web page in Power Pages:

We then make a change in Dataverse (via a model-driven app) but this could be a Power Automate flow, a plug-in, etc.

Even after we refresh the page with the List control, the data on the Power Pages site doesn’t update (yet).

BUT! If we drill down the the *first* time the record is loaded on a new page using the form component, we will see the change almost immediately. 🤔

However, if we make another change in our model-driven app;

And then refresh the web page again… we won’t see the change because the form was already recently loaded.

The caching mechanism is related to how the data is retrieved from the website (forms and lists) but once retrieved, will be cached.

When will the updated data show up? I have found that the data will refresh likely in around 5 minutes… sometimes faster, but definitely not immediately. The service level agreement outline in the Microsoft documentation is 15 minutes.

This “feature” is not meant to be malicious or isn’t a bug, it is meant to ensure that Power Pages as a web application platform runs smoothly and efficiently. If the website needed to constantly query Dataverse, not only would your website slow down to a crawl but it could use up a lot of cloud server resources. (That could be used for things like… copilots. 😲)

Update Dataverse from Power Pages – No cache impact!

Now, if you had the correct table permissions assigned and created/updated a record from Power Pages to Dataverse, then you would immediately see the data update on a Power Pages site. This would apply to all users that happen to be browsing the website.

The change will be immediate, no caching as data will be written to Dataverse and will clear the cache.

Clearing the cache while developing a website

When configuring your website and testing, you can force a cache refresh by either choosing the Preview button from the Power Pages design studio or by hitting the clear cache button if you are signed in with an authenticated user has the out of the box administrator role.

Can I programmatically clear the cache?

No.

This question comes up often in use cases where something happens on the website (e.g. kick off a process) and then some kind of processing happens in Dataverse (plug-in, flow, etc) that may create or update sub-tables where you want to data to be immediately reflected on a Power Pages website.

Not that the use of multi-step forms will reflect backend processing immediate on the website. Used creatively, this is the best way to avoid cache issues. See: Using Dataverse low-code plugins with Power Pages.

Is there an ugly hack or work-around?

Sure.

A common way to circumvent the caching is to create a custom view or form using Liquid using the FetchXML tag to retrieve the data, but adding the following condition:

<condition attribute="createdon" operator="on-or-before" value="{{ "today" | date: "yyyy-MM-dd HH:mm:ss" }}" />

What this will do is each time the FetchXML statement is called (and Liquid runs server side) because the value of “today” changes every second, the cache will invalidate and new data will be retrieved.

A couple of issues with this method:

  • You will need to create a custom view using Liquid and HTML, and it will take effort to add all of the features that the out-of-the-box list component has.
  • This will not be fast, and if you need to display a lot of data, this could result in sluggish data loading for your entire site. It is actually not recommended design practice to use this.

Now that we got all the various warnings out of the way, I know you are going to do it anyway, here is example code and high level steps.

I created this example code of a very simple HTML list and created it as a web template component (also known as a custom component).

Create a new web template (Using Power Pages Management app or Visual Studio Code for Desktop) paste in the following code (adjust for your own tables and fields).

<H2>{{name}}</H2>
<table class="table table-bordered">
  <thead>
    <tr>
      <th>Session ID</th>
      <th>Session Name</th>
      <th>Session Description</th>
    </tr>
  </thead>
  <tbody>
    {% fetchxml sessions %}
    <fetch returntotalrecordcount="true">
        <entity name="docs_session">
          <attribute name="docs_sessiondateandtime" />
          <attribute name="docs_sessiondescription" />
          <attribute name="docs_sessionid" />
          <attribute name="docs_sessionname" />
          <attribute name="docs_speaker" />
          <attribute name="docs_rating" />
          <filter type="and">
            <condition attribute="createdon" operator="on-or-before" value="{{ "today" | date: "yyyy-MM-dd HH:mm:ss" }}" />
          </filter>
        </entity>
    </fetch>
    {% endfetchxml %}
    {% for session in sessions.results.entities %}
    <tr>
      <td>{{ session.docs_sessionname | escape }}</td>
      <td>{{ session.docs_sessiondescription | escape }}</td>
      <td>{{ session.docs_sessiondateandtime | date: 'g' }}</td>
    </tr>
    {% endfor %}
  </tbody>
</table>
<p>{{load_more_label}}</p>

{% manifest %} 
{
  "type": "Functional",
  "displayName": "Custom Session List",
  "description": "Shows all sessions",
  "tables": ["docs_sessions"],
  "params": [
    {
      "id": "name",
      "displayName": "Title",
      "description": "Let's give it a title"
    },
    {
      "id": "load_more_label",
      "displayName": "Load more label",
      "description": ""
    }
  ]
}
{% endmanifest %}

Once you have created the web template, you (or your makers) can add it as a custom component via the Power Pages design studio to a webpage:

You will have a custom view that is always up to date.

Note that any out-of-the-box list and form components will likely still show the cached data.

The Portal Web API Hack

A few years ago I wrote about a method that involved using the Power Pages Web API as a (very) hacky method to invalidate the cache.

The basic idea is that when you want to view a page with the most recent changes, you write a small update from the Power Pages site to Dataverse, and as we learned above, this will clear the cache for that table.

So if we wanted to view the most up to date data from a record, we would have an intermediary page that would write and update prior to viewing it.

Here is the post:

Using the Power Apps portals WebAPI to Clear the Portal Cache

The method still works, and was written while the WebAPI was still in preview. The following is a slightly updated code component that will allow you to pass the various tables and details as parameters to a code component.

You need to add a column to your table that you want to view the cache. This will just hold the update that we are writing from the Power Pages website.

We create a site marker to point to the page where we would want to see the updated data:

Again, add the code as a web template.

{% assign targetpage = sitemarkers[target_sitemarker] %}
{% assign guid = request.params['id'] %}
{% include 'portalwebapihelper' %}

Clearing cache for {{dv_table}} with guid: {{guid}}<br>

DV Table: {{dv_table}}</br>
Sitemarker: {{target_sitemarker}}</br>
Target page: {{targetpage.url}}</br>

<script>

function rtc() {
    try {
        var n = Date.now();
        var timestamp = n.toString();
        var guid = "{{guid}}";
        console.log(guid);
        webapi.safeAjax({
            type: "PUT",
            url: "/_api/{{dv_table}}(" + guid + ")/{{dv_cache_field}}",
            contentType: "application/json",
            data: JSON.stringify({
            "value": timestamp
        }),
        success: function(res) {
            console.log(res);
        }
    });
    } catch (err) {
        console.log(err.message);
    }
}

 $(document).ready(function() {
    rtc();

    //jump to actual detail page
    window.location.href = "{{ targetpage.url }}?id={{guid}}";
  });
</script>

Essentially, create a page and add this component.

When you add the code component, put in the entityset name of the table you want to clear the cache, the cache field and the sitemarker.

Modify your list view (or however you are navigating to view this record) to point to this web page and pass the record id as a parameter (the out-of-the-box list will already do this):

You will need to configure the WebAPI site settings to allow the WebAPI to write to the tables.

You will need to setup table permissions and (yuck) allow the users to be able *write* to the table, and that could be the deal breaker for this technique.

Once everything is configured, preview your site, and when you select the record from the list:

You may see a “flash” of the intermediary page, but you will see the most up to date data on the form page.

The cons of this approach

  • It is that it is clunky.
  • Huge potential security concerns as you need to give users “write” permissions to data.
  • It will have an effect on performance.

As I mentioned in my original post, this is more for education purposes.

Stuff I tried that didn’t work

I tried the intermediary page trick, but instead of the WebAPI tried the FetchXML data retrieval, however, this did not work. The process did not clear the cache for the list for form components. I’ve tried JavaScript browser refreshes, hacking FetchXML on Dataverse views, various plug-in processes, etc. However, ended up with inconsistent results or things just didn’t work as expected.

Does it matter?

In my experience working on a lot of different Power Pages projects, overall, it usually isn’t mission critical to have the most up to date changed data from Dataverse. A lot critical caching issues can be resolved by being creative or using features like multistep forms or custom views. Not saying it wouldn’t be nice to have a way to programmatically or a configurable way to clear the cache, but it likely isn’t going to happen anytime soon. And then what would Nick Hayduk create memes about?

Nick Doelman is a Microsoft MVP, podcaster, trainer, public speaker, and competitive Powerlifter. Follow Nick on X at @readyxrm or LinkedIN, and now; Bluesky. Listen or watch the the Power Platform Boost podcast with Nick and co-host Ulrikke Akerbæk every second week for news and updates from the Power Platform community.

Original Post https://readyxrm.blog/2025/01/25/power-pages-cache-test-dummies/

0 Votes: 0 Upvotes, 0 Downvotes (0 Points)

Leave a reply

Join Us
  • X Network2.1K
  • LinkedIn3.8k
  • Bluesky0.5K
Support The Site
Events
February 2025
MTWTFSS
      1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28   
« Jan   Mar »
Follow
Sign In/Sign Up Sidebar Search
Popular Now
Loading

Signing-in 3 seconds...

Signing-up 3 seconds...