[Webkit-unassigned] [Bug 32423] New: Incorrect cache behavior with dynamic scripts after page-refresh

bugzilla-daemon at webkit.org bugzilla-daemon at webkit.org
Fri Dec 11 04:31:22 PST 2009


https://bugs.webkit.org/show_bug.cgi?id=32423

           Summary: Incorrect cache behavior with dynamic scripts after
                    page-refresh
           Product: WebKit
           Version: 528+ (Nightly build)
          Platform: PC
               URL: http://test.getify.com/webkit-cache-bug/test-1.html
        OS/Version: Windows XP
            Status: UNCONFIRMED
          Severity: Normal
          Priority: P2
         Component: History
        AssignedTo: webkit-unassigned at lists.webkit.org
        ReportedBy: getify at gmail.com


I originally filed this bug with Chromium bug tracker believing it to only
affect Chrome. However, it has come to my attention that the behavior in
question affects both Chrome and Safari, and the Chrome developers believe it's
actually inside the Webkit code, so they suggested I post here instead.

For reference, that Chromium bug report is here: 
http://code.google.com/p/chromium/issues/detail?id=23162

The way I originally described and presented the bug turns out to have just
been pretty confusing. My bad. So, here, I'm gonna present it in a different,
hopefully more concrete/clear way. So, that's why it sounds different here from
how I originally described over on the Chromium site.

Please bear with me as I know this is very long bug report with lots of detail.

--------------

Let me first describe a scenario and my observations/conclusions about it,
then, down below, I'll link to and explain some proof test cases so you can
confirm the behavior/bug I describe for yourself.


Page View 1 (initial page view in browser)
a) Download "script1.php?3333" with type "text/javascript"
b) Download "script2.php?5555" with type "script/preload"
c) After 1b completes, re-attach "script2.php?5555" to page (via script tag)
with type "text/javascript"


Page View 2 (regular refresh view of same page in browser)
a) Download "script1.php?7777" with type "text/javascript"
b) Download "script2.php?9999" with type "script/preload"
c) After 2b completes, re-attach "script2.php?9999" to page (via script tag)
with type "text/javascript"

----------

Notice how 1b and 1c have the SAME URL as each other... meaning the browser
should be able to pull from cache of 1b for 1c.

Also notice how 2b and 2c have the SAME URL (same as each other, but obviously
different from 1b and 1c)... meaning the browser should be able to pull from
cache of 2b for 2c.

----------

What actually happens:

* browser does a full request for 1b, but pulls from cache for 1c. -- Good!

* browser does a full request for 2b, but cannot pull from cache for 2c, so
must full download again. -- Bad!

----------

2b and 2c have same URL as each other, why is the cache INVALID for 2c?
Moreover, why is the cache VALID for 1c but INVALID for 2c?

The difference between 1 and 2 is really why I'm claiming a bug. In my mind,
there shouldn't be a difference in how the browser treats 1 and 2, because both
start with freshly generated dynamic URL's (to keep the test clean).

1b should result in a valid cache for 1c, and it does! But by the same logic,
2b should result in a valid cache for 2c, but it doesn't. :(

***I understand*** that my .php scripts are only sending out a valid "Expires"
header, but not sending out an Etag or last-modified header. But that still
hasn't explained to me sensibly why behavior is different between 1 and 2,
since the same headers get sent in both cases.

----------

Other things to note about the quirky/buggy behavior:

1. if 1b, 1c, 2b, and 2c all happen AFTER their respective page loads, then
BOTH 1c and 2c find valid cache hits.

2. if there are no ?xxxx type parameters added to the above URL's (but you
clear the cache after initial page load before hitting "refresh"), then BOTH 1c
and 2c find valid cache hits.

3. if the URL's are ".js" instead of ".php", then BOTH 1c and 2c find valid
cache hits.

4. If 1a and 1b are not part of the scenario (meaning, we only try 1b, 1c, 2b,
and 2c), then BOTH 1c and 2c always find valid cache hits. Only when another
regular script download is introduced to the scenario does this quirk present
itself.

----------

Test cases:

http://test.getify.com/webkit-cache-bug/test-1.html

http://test.getify.com/webkit-cache-bug/test-1-alt.html

http://test.getify.com/webkit-cache-bug/test-2.html

http://test.getify.com/webkit-cache-bug/test-3.html

http://test.getify.com/webkit-cache-bug/test-4.html

http://test.getify.com/webkit-cache-bug/test-5.html

----------

Only "test-1" shows the bug I'm asserting, the rest of the tests show
variations which make the bug *not* appear.

In all of these tests, essentially the same basic logic occurs, which maps
closely to the scenarios and assertions described above. 

Each test starts out by loading "script1" URL with a valid script type of
"text/javascript", and "script2" with a fake script type of "script/preload".

Then, once the first download of "script2" finishes, the test tries to reload
the exact same "script2" URL again (so should pull from cache), but this time
using the valid "text/javascript" script type.

The "log" output that you'll see in each test is to demonstrate the elapsed
time between when a script URL is added and when it finishes loading. The .php
scripts are set to intentionally create a 3-4 second delay to make it very
obvious in the elapsed time log output whether the browser is requesting from
the server or pulling from cache. But even in the .js test (#4), which has no
artifical delays, you'll see a 300-400ms time for the full load, and a 30-50ms
time for the pull from cache.

Basically, the key thing to look for in the log output, to demonstrate the bug
I'm asserting, is the two elapsed times for the "script2" URL's. You *should*
see the first "script2" attempt be long (since it pulls from server), and the
second "script2" attempt be short (since it should pull from cache).

Also, remember, the bug assertion I make is that behavior is different between
an initial page view and when you refresh the page.

----------

Specifics notes/steps for each test case:

* test-1 : base test case. when you first load this test, you'll see that
"script2" has first a long elapsed time, and then on second attempt a short
elapsed time. This proves it pulled from cache the second time. Good!

but, if you then refresh the page (F5, refresh button, etc), you'll see that
both attempts for "script2" will be long elapsed times, indicating the cache is
not used for the second attempt like it should, and like it did in the initial
page view. Bad!


* test-1-alt : variation on test-1, the ONLY difference being that the scripts
don't auto-load during page load, but are loaded on-demand when you click the
button. In this test, you'll note that the "script2" elapsed times are correct
for both an initial page load and after you refresh the page. Good!


* test-2 : before running this test, clear your cache. this test doesn't do the
re-attempt of "script2" at all. So in the logs, you'll only see one listing for
"script2". Inspect your cache entries after running this test, and you'll prove
that "test2" really IS in the cache (even though "script/preload" was used as
the type). Good!

then, clear your cache again, and refresh the page. then reinspect the cache
entries, you'll see "script2" there again. So it comes to the cache just fine,
both on initial page view and on refresh. Good!


* test-3 : before running this test, clear your cache. this test is the same as
test-1 except that the _=0.54353453 "cache busting" params are NOT generated
for the "script1" and "script2" URLs. Run the test, notice the "script2"
elapsed times are correct. Good!

then, clear your cache again, and refresh the page. notice the "script2"
elapsed times are still correct. Good!


* test-4 : this test is the same as test-1 except that the URL's are ".js"
instead of ".php". Run the test, you'll notice the "script2" elapsed times are
correct. Good!

then, refresh the page. notice the "script2" elapsed tiems are still correct.
Good!


* test-5 : this test only loads "script2" (both attempts), but not "script1".
You'll note that the elapsed times are correct for "script2" on both initial
page view *and* after a refresh. Good!

-- 
Configure bugmail: https://bugs.webkit.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug.



More information about the webkit-unassigned mailing list