On 2/22/11 3:07 PM, Kyle Simpson wrote:
Look above at what Will says... he says "before a URL loads" in (a). I
interpreted that to mean that if I make two requests in rapid fire
succession, and the browser hasn't yet gotten the response headers (from
the first request) to tell it not to cache, then it makes sense from an
optimization standpoint that IE would see the two simultaneous URL
requests as the same and assume to only load once instead of twice.
That's a violation of HTTP semantics, yes. A convenient way to write
the code, but a violation of HTTP semantics.
Again, maybe I'm missing something, but the way Will describes it sounds
perfectly reasonable to me. It might be slightly on the aggressive side,
but I don't see how that, as described, is violating the HTTP caching
semantics.
Trivially. If it's not in your cache at all, you're supposed to make a
request to the server! If you're not doing that, then you're not
implementing HTTP.
I don't see that those semantics imply that a browser must
wait to fully receive response-headers from a first request before
deciding what to do with a second request of the same URL.
Right. They just imply that you need to send the second request. Or
wait for the first to come and then decide whether to send it. Or
_something_ that looks like what HTTP is supposed to look like.
What _this_ looks like is that there's a non-HTTP cache of in-progress
loads that can serve to coalesce said in-progress loads. That gives
behavior that's invalid per HTTP and inherently racy in a bad way.
Because it's the easy way to do it; we had to jump through some hoops
in Gecko to make sure an async XHR stays alive until it fires its last
readystate change event when no one is holding a ref to the XHR object.
Right, but in that case, the XHR object has a circular reference to
itself via the closure of the handler function (assuming it was an
assigned anonymous or in-scope function that was assigned).
Sure.
I was just saying that in the case of actual DOM elements, when a circular
reference is created between the DOM element and a JS counter-part,
through the closure of a handler assigned to the element, I assumed this
was enough to avoid GC.
Circular references can't be enough to avoid GC. The whole point of
having a GC is to be able to collect entire subgraphs of the object
graph that are not rooted. And you have to be able to collect cyclic
subgraphs; otherwise you might as well use reference counting instead of
a GC.
I recall in older IE days avoiding stuff like:
var script = document.createElement("script");
script.theobj = script;
Because this created a circular reference, and thus a memory-leak, if
you didn't forcibly unset before unload the `theobj` reference to break
the circular ref.
Yes, that would be due to the fact that GC was used on the JS side and
"something else" on the C++ side and the expando caused the script to be
a GC root. Other browsers have had similar bugs too. Those are just
bugs to fix. A GC should be able to collect the above.
Well... no. You could grab the ref in the onreadystatechange handler.
In the most rudimentary of cases, and only assuming the
`onreadystatechange` handler actually had a closure reference to the
script element...
|this| is the script element in the onreadystatechange handler, I would
think. So it _always_ has a reference to the script element. Just like
the XHR onreadystatechange case.
he can't just daisy-chain off the handlers, he needs to actually have a
reference kept for each script element, so that he can specifically
execute each one in their proper order.
Yes, but it could just grab those references as the scripts load. In
any way, this is a side-issue; my main question has been answered: IE
both shows bad memory behavior _and_ fails to implement HTTP semantics
for script preloads done in this way.
-Boris
-Boris