Lwc: [Lightning] platformResourceLoader loadStyle never resolves promises on subsequent page loads

Created on 20 Oct 2020  路  3Comments  路  Source: salesforce/lwc

Description

N.B. this is likely a Salesforce/lightning bug rather than LWC, however components built on the platform may be directly impacted by this bug and I do not have an alternative way to inform the Lightning team. If this could be passed on to the lightning team it would be much appreciated.

This issue was highlighted after enabling the new critical update 'Enable Secure Static Resources for Lightning Components'.

We discovered that, previous to this critical update, the loadStyle function made available to LWC would always correctly resolve promises. For example, code like this would work correctly.

await loadStyle(...);
console.log('this code runs after the style is loaded, as per documentation');

It was discovered that the loadStyle function also has de-duplication logic, that is, it prevents re-adding a CSS file that already exists on a page . However, due to lightning URLs, this URL was prefixed with a timestamp each time loadStyle() was run, which prevented the deduplication logic from working. Now, after enabling this critical update, URLs are deterministic and likely based on the timestamp the file was last modified. This causes the deduplication logic to work correctly, but exposes this particular code snippet (screenshot from platformResourceLoader below).
image

As shown above, if a CSS style already exists on a page (for example, if you navigate to an object tab and then back to a page containing your LWC, loadStyle will never call resolve(), resulting in no subsequent code execution after loadStyle(...).then() or await loadStyle. This is a fundamentally concerning issue as it could result in subtle bugs due to this critical update 'fixing' non-deterministic CSS URLs when loaded from the now-deprecated lightning domain.

Steps to Reproduce

  1. Enable the critical update 'Enable Secure Static Resources for Lightning Components'
  2. Add an loadStyle(this, pathToStaticResource).then(() => console.log('hit')); to connectedCallback() (optionally, use async / await)
  3. Notice that loadStyle() resolves the promise on initial component load, but then subsequent page loads will never log 'hit' to the console. This is a change of behaviour due to the change outlined above (and broke several of our components in subtle ways, where the components all relied on loadStyle resolving properly, as promises should always resolve - or reject upon an exception)

Expected Results

loadStyle resolves (even when a duplicate asset is loaded), subsequent console.log is executed

Actual Results

loadStyle never longer resolves, resulting in a promise callback never fired

Browsers Affected

Any browser.

Version

Possible Solution
Change all instances of loadStyle() to never wait for promise resolution, as it may never happen in some cases.

BUG P1 Lightning Locker

Most helpful comment

@jordanhenderson thanks for filing this very much appreciated.

All 3 comments

This issue has been linked to a new work item: W-8238241

@jordanhenderson thanks for filing this very much appreciated.

We have been informed by SF that this has now been addressed and will be deployed along with Spring 21.
I'll mark this as closed.

Support Message:

This communication is related to the case #27938998 - LWC loadStyle is not resolving promises when CSS loading is skipped.

I would like to let you know that product team has fixed this issue and it will be deployed as part of Spring 21 release(safe harbor applies).

Was this page helpful?
0 / 5 - 0 ratings