I recently ran into a problem where my HTML web resources and their script dependencies weren’t being cached. I first noticed this because the page was loading slowly. The web resource in question was dynamically loading data from Dynamics 365, so I was expecting a delay but not as much as the delay I was seeing.
Diagnosing the Problem
- The first thing I did was to load the page a few times to make sure it wasn’t just running slowly the first time after a publish. In this case, it was running just as slowly every time.
- The next step was to break out the browser developer tools. In my case I was using Chrome so after a quick <F12>, select the Network tab and page reload, I was in business. Here is the pertinent section from the network log:
You can see that the ‘size’ is listed. If these were coming from cache then they would show as (from memory) or (from disk).
- I remembered that Scott Durow had a blog article about caching web resources so I checked there first. If you aren’t already familiar with how Dynamics 365 caches web resources, I suggest you read that before continuing here. Everything seemed in order.
- Then I realised that this particular web resource is being dynamically loaded when a lookup field on the form is modified. You can see the GUID of the record being passed in the ?data parameter in my screen shot above.
- When I hovered over the URL of the initiator it was missing the Dynamics ‘Cache Token’ that normally looks something like this %7B634411504110000000%7D.
var clientUrl = Xrm.Page.context.getClientUrl();
var url = clientUrl + webResourceUrl + "?data=" + recordId;
The getClientUrl() function in the SDK gives you the base URL for your organization, but it does NOT include the cache token.
To fix the problem, instead of using getClientUrl() I just grabbed the ‘base’ URL from the URL that was already loaded in the web resource and replaced the query string with the one I needed. Like this:
var baseUrl = webResource.getSrc().split("?");
var url = baseUrl + "?data=" + recordId;
N.B. there are ways to identify the cache token and dynamically build the URL yourself, such as this method from Nick Doriot. The down-side is that it requires a network request, and in my situation I already had the required base URL available in the web resource.
Post image (oops, wrong kind of cash…) by Nikita Andreev on Unsplash.