-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Failed dynamic import should not always be cached #6768
Comments
cc/ @hiroshige-g @domenic While Safari isn't conforming to the spec in this case, I think their behavior is more intuitive and reasonable to web developers. We should fix the spec, not the browser 🙂 |
cc @whatwg/modules |
If we end up deciding to change behavior here, https://bugzilla.mozilla.org/show_bug.cgi?id=1716019 can be reopened and repurposed. |
Some random thoughts (I'm neutral about whether this change should be made or not; focusing its feasibility here): Should we retry { fetch errors | parse errors | instantiation errors | evaluation errors }? Should we retry in {dynamic imports | static imports | How it should be specified? |
Thanks @hiroshige-g! I believe these are similar thoughts from @domenic's comment (from 2019):
One thing that I'm imagining here:
I believe if Step 3 just says something like: If moduleMap[url] exists and is not
The new Step 3 would have an immediate follow up to change a null Step 2 works today because there is no repeated I hope this helps moving this issue forward towards an effective resolution! |
Is there anything I can do to move this issue forward? |
Any progress? |
I'm guessing this hasn't made much progress because there aren't a lot of people clamoring for a solution, so I'm just here to be an additional squeaky wheel. I'm about to "fix" this in my own project by implementing a service worker that will retry only requests for javascript files, which strikes me as an extremely drastic measure to have to take to guard against a common condition like flaky connectivity. The user experience when this fails is also really, really bad -- parts of the app just entirely fail to load, and as far as I can tell the only mitigation short of the service worker approach would be to report that an error happened and encourage/force the user to reload the page. It's a bad look for the app developer, and I don't think most engineers know that this is a danger when implementing code-splitting, which is part of all the major SPA frameworks and a standard recommendation for large apps. I'm really surprised I haven't heard about this biting more people, and I wonder if a lot of teams either don't know this is happening to them or have given up on solving it. |
Same problem. I use microfrontends with chunks. I'm trying to protect against chunk loading error when deploying a new microfrontend version. Because the old chunks are gone. I'm trying to reimport a microfrontend, but it's cached. |
I was struggling with this issue and found a workaround. and had the chance to even write about it here: |
Caching the result of a failed |
## Issue ChunkLoadError. There is anecdote saying that Chromium will cache failed responses (e.g. timeout), so users could end up perpetually in a bad state until the cache is cleared, or the site moved on a new different js chunks. `https://github.com/whatwg/html/issues/6768` ## Approach While there is no way to programmatically clear a user's cache, doing a separate `fetch` with `no-cache` indirectly replaces the cache with a fresh download.
## Issue ChunkLoadError. There is anecdote saying that Chromium will cache failed responses (e.g. timeout), so users could end up perpetually in a bad state until the cache is manually cleared, or the site moved on to a new chunk. `https://github.com/whatwg/html/issues/6768` ## Approach While there is no way to programmatically clear a user's cache, doing a separate `fetch` with `no-cache` indirectly replaces the cache with a fresh download.
## Issue ChunkLoadError. There is anecdote saying that Chromium will cache failed responses (e.g. timeout), so users could end up perpetually in a bad state until the cache is manually cleared, or the site moved on to a new chunk. `https://github.com/whatwg/html/issues/6768` ## Approach While there is no way to programmatically clear a user's cache, doing a separate `fetch` with `no-cache` indirectly replaces the cache with a fresh download.
## Issue ChunkLoadError. There is anecdote saying that Chromium will cache failed responses (e.g. timeout), so users could end up perpetually in a bad state until the cache is manually cleared, or the site moved on to a new chunk. `https://github.com/whatwg/html/issues/6768` ## Approach While there is no way to programmatically clear a user's cache, doing a separate `fetch` with `no-cache` indirectly replaces the cache with a fresh download.
## Issue ChunkLoadError. There is anecdote saying that Chromium will cache failed responses (e.g. timeout), so users could end up perpetually in a bad state until the cache is manually cleared, or the site moved on to a new chunk. `https://github.com/whatwg/html/issues/6768` ## Approach While there is no way to programmatically clear a user's cache, doing a separate `fetch` with `no-cache` indirectly replaces the cache with a fresh download.
I'd like to reiterate the importance of addressing this specification issue. ES6 modules should be the preferred choice for building a large SPA website, but currently result in a poor experience for users with unreliable network connections. Our use case: We utilize Vite and Rollup to produce ES6 modules for a large-scale website. However, we've faced difficulties with the workarounds provided here:
I genuinely hope this can be prioritized, as it significantly impacts SPA applications using ES6 modules. |
we have the same problem on our projects. we have a different cdn as the backup for the scenario "unstable network" or "DNS cache pollution".
|
Dirty hack to solve it:
|
@nathnolt this was already covered in:
|
I see. It's strange that such a common thing like import() is so fragile under non perfect network conditions. |
It is strange. Dynamic Import is ~7 years old, this issue is ~3 years old, and the same issue was resolved in the ECMAScript specification ~5 years ago. But it also makes sense! Most of the internet runs on older bundlers like Webpack UMD. As @davidwallacejackson wrote, there aren't enough squeaky wheels. The good news is that in 2023 Webpack growth began to decline and ESBuild / Rollup / Vite usage is rising exponentially. With luck this issue will soon have enough squeaky wheels to demand action. |
@domenic and @hiroshige-g and @annevk it's been a few years since you commented on this issue, but I think it warrants a second look as ESM usage is increasing exponentially. In your previous investigation, you identified that Chrome and Firefox are following this problematic WHATWG specification but Safari is not: For a real-world example of how this impacts the Chrome and Firefox user experience, I will share some data from my company's website. We have ~750 javascript modules and approximately 10% of imports are done using
From this data I conclude that Edited to include Firefox data. A larger time range was necessary due to lower Firefox traffic on our site, so I also updated Safari and Chrome with data from same time range. The new numbers vary a bit from the original numbers, but clearly show the same trend. |
@past I marked this agenda+ mainly to seek feedback on @zcrittendon's request above. @lucacasonato kindly wrote up #10327 so at this point the main question is whether Chromium and Gecko are interested in making a change here. (I won't attend this week due to a holiday, but I don't think I'm needed for this. If you feel otherwise feel free to postpone.) |
Amazing! Thanks so much @annevk and @lucacasonato -- really appreciate your attention to this! Hopefully Chromium and Gecko will support this change as it will significantly improve the browsing experience for their users. |
Given feedback from https://bugs.chromium.org/p/chromium/issues/detail?id=1195405#c9
In my opinion, HTML spec should also stop demanding to cache failed dynamic imports.
The rationale of this proposal is well discussed in tc39/proposal-dynamic-import#80
The ECMAScript spec has adopted the change long ago: tc39/ecma262#1645
Lack of retry-ability is stopping SPA developers from using native dynamic imports. Because they would have to reload the whole web app, only to make up for an otherwise insignificant network failure when fetching a lazy-loaded js chunk.
The text was updated successfully, but these errors were encountered: