Calling reload with flag LOAD_FLAGS_BYPASS_CACHE still sees scripts added dynamically post-pageload coming from cache

NEW
Unassigned

Status

()

Core
Networking
P3
normal
4 years ago
9 months ago

People

(Reporter: Ken Winters, Unassigned)

Tracking

({reproducible, testcase})

31 Branch
reproducible, testcase
Points:
---

Firefox Tracking Flags

(Not tracked)

Details

(Whiteboard: DUPEME[necko-backlog], URL)

Attachments

(1 attachment)

(Reporter)

Description

4 years ago
Created attachment 8474575 [details]
cache bug shift-reload.png

User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:31.0) Gecko/20100101 Firefox/31.0 (Beta/Release)
Build ID: 20140716183446

Steps to reproduce:

1. Create an HTML5 page with a script tag in the head section
2. After document.ready, inject more javascript files via document.createElement and append, jQuery.ajax(), or both methods

jQuery.ajax({
         url: '/cache/en_US.js',
         dataType: "script",
         cache: true,
         success: loadCallback
});

3. Set typical cache control headers on the js files that will make it cache

Cache-Control	max-age=2592000, public, must-revalidate
Etag	"8a15b-46-500e851c79400"
Expires	Wed, 17 Sep 2014 14:53:34 GMT
Last-Modified	Mon, 18 Aug 2014 14:38:08 GMT

4. Load the page.
5. Reload the page.
5. Shift-reload the page (ignore cache)

Tested with http and https self-signed, did not appear to make a difference.  Also tested with multiple cache control settings, still the same behavior.

(I've noticed the same problem when running JSLint but does that does not impact the end user.)


Actual results:

The js files in the html file's head section return 304 Not Modified on normal reload, 200 on shift-reload.

The injected js files return 200 OK (BFCache) in all cases. The only way to get the new injected file is to clear the entire cache and the file contents will be stale until then.


Expected results:

Injected javascript files should obey the refresh cache rules and be consistent regardless of how and when the file is loaded.

Chrome behaves this way, for comparison.
(Reporter)

Comment 1

4 years ago
A few extra details:

This is in an AngularJS single-page app, on a URL with a # in it.

It's running on Apache2 on a server accessed by IP address (no DNS).

Comment 2

4 years ago
Internally, a shift reload does a reload with some extra flags (identical to doing location.reload(true)), and they don't seem to be used for the subsequent requests from the page.

I've added a simple testcase that uses two tiny php scripts that emit cache headers and set the content of two divs on the page to the server's unix timestamp inserted via php. As you shift-reload, you'll note that the statically loaded script's timestamp increases (because it's re-fetching it). The dynamically loaded script's contents stay the same. I can reproduce this behaviour in 32 and nightly.

I *think* this behaviour is incorrect (and an issue with docshell?), but I've been known to be wrong. bz?
Status: UNCONFIRMED → NEW
Component: Untriaged → Document Navigation
Ever confirmed: true
Flags: needinfo?(bzbarsky)
Keywords: reproducible, testcase
OS: Mac OS X → All
Product: Firefox → Core
Hardware: x86 → All
Summary: Ctrl-shift-f5 cache clear does not work post-ready → Calling reload with flag LOAD_FLAGS_BYPASS_CACHE still sees scripts added dynamically post-pageload coming from bfcache

Comment 4

4 years ago
(In reply to Ken Winters from comment #0)
> Chrome behaves this way, for comparison.

Interestingly, my testcase seems to behave the same way in Chrome as it does in Firefox... perhaps the cache headers I'm using aren't right? Can you provide a testcase where you see different behaviour?

(there might still be a bug in both Firefox and Chrome, but I'd like to understand how my testcase differs from what you're seeing)
Flags: needinfo?(kwintersnc)
(Reporter)

Comment 5

4 years ago
It turns out that the Chrome behavior was because of the self-signed cert (which prevents all caching). Turning off HTTPS eliminated the difference.

FYI, my workaround for now is to remove the far-future expires header on the files loaded via XHR. It does not cache them as efficiently, but now at least it is doing 304 checks. I believe this works because of the calculations regarding percentage of expires time elapsed.

After posting the bug report, I went back and thought some more about the impact on single-page apps if it were fixed.  If feasible I'd recommend something like "ignore cache if cache time < shift-reload time" so that multiple requests to the same resource after that can still cache. Otherwise the performance hit could last until the tab is closed etc. because there are no normal nav events.
Flags: needinfo?(kwintersnc)
I don't see how bfcache is relevant here; Firebug is just on crack.

The observed behavior is quite purposeful last I checked.  Specifically, it's there for at least two reasons:

1)  We need to decide when to stop applying the main load's "skip the cache" state to the entire loadgroup, because the loadgroup is shared with later-loaded documents.  Right now that's done at page load end.

2)  Continuing to apply the "skip the cache" state after load completion would mess with XHR in single-page apps.  I don't think developers expect a shift-reload to mess with the functioning of the page infinitely into the future.

Issue #2 is what comment 5 is talking about, I guess.

In any case, this is a necko policy issue: what exactly should "force reload" mean?
Component: Document Navigation → Networking
Flags: needinfo?(bzbarsky)
Summary: Calling reload with flag LOAD_FLAGS_BYPASS_CACHE still sees scripts added dynamically post-pageload coming from bfcache → Calling reload with flag LOAD_FLAGS_BYPASS_CACHE still sees scripts added dynamically post-pageload coming from cache
(Reporter)

Comment 7

4 years ago
I had a feeling that the technical reason for the behavior was something along those lines.

But the behavior is still surprising, because users have been trained at this point that ctrl-shift-r = reload the page with a fresh cache. http://en.wikipedia.org/wiki/Wikipedia:Bypass_your_cache says "In unusual circumstances, it may be worth clearing the entire cache" but gives clear precedence to the reload.

The actual ctrl-shift-r behavior is "bypass the cache for some of the files" and then watch everyone's eyes glaze over when I try to explain which ones.  Just clearing the entire cache is not a good alternative because has broader performance impact and requires significantly more steps to complete.

There does need to be some balance but I don't believe that Firefox has hit the optimum point yet. Is one refresh per resource as in #5 infeasible?
It might be possible...  That's for the necko folks to figure out.
Whiteboard: DUPEME → DUPEME[necko-backlog]
You need to log in before you can comment on or make changes to this bug.