Re: Executing script-inserted external scripts in insertion order

Hallvord R. M. Steen wrote:
> > Why would that be the performance-savvy default? It seems to me
> > IE/WebKit behavior is more performance-savvy when there are at least
> > two
> > non-interacting scripts being downloaded in parallel (e.g. a site
> > functionality script and an advertising script).
> 
> Henri: If the site could choose, would it want the browser to spend
> time
> on executing the site functionality script or the advertising script
> first? Processing the DOM mutations of the ad layout or the logic that
> will make the site respond to the user? With the browser-centric
> performance hat on running scripts as fast as we can get hold of them
> makes sense, but I'm not sure it really gives the best user experience
> overall.

Maybe the site would choose to prioritize the site functionality script. But the defaults are really about the case where we have a legacy site that hasn't tried to make that choice by scripting around the defaults.

If a browser wanted to be able to prioritize site functionality of legacy sites over ads if it had a heuristic for detecting ads, surely in that case the behavior that doesn't guarantee order would be preferable, since that would leave the browser the chance to game the download priorities. With an order guarantee, the browser didn't have the room to game the download priorities.

> > I think the default shouldn't depend on what makes sense but on what
> > works for existing content.
> 
> In this case much (all?) existing content should work with either
> behaviour since Firefox+Opera with their fairly substantial market
> share
> differs from IE+WebKit.

Yes, except for UA sniffing.

> So we should be able to pick a default based
> on
> what's more author-friendly.

Note that what would be author-friendly in a vacuum isn't necessarily author-friendly in the context of deployed browsers. I think in a vacuum, it would make author-friendliness sense to make script-inserted external scripts maintain order among themselves by default and to require async=true to opt to non-ordering. However, in the context of deployed IE and WebKit providing a weaker guarantee, it's not necessarily author-friendly to make ordering the default: Authors wouldn't be able to rely on ordering as long as browsers with a non-ordered default are around, so authors would be unable to rely on the default safety for years even if IE 10 Standards Mode had a new default. Until the authors are able to rely on a stronger default, having to take into account two defaults that aren't distinguishable except by UA sniffing would be worse than having the weaker guarantee be the default everywhere and having the stronger guarantees available in feature-sniffable way.

> (However, I have not investigated why exactly HTML5 parsing made you
> run
> into a bug that made you want to implement non-ordered execution. I
> may be
> missing something regarding why non-ordered is a better/easier choice
> for
> a UA that supports HTML5 parsing. Guess I will find out some day..
> :-p)

A script-inserted external script caused a script-inserted inline script be deferred. The script-inserted inline script called document.write, but when it did, it was no longer safe to call document.write. Since protection against destructive writes applied only to external scripts, the inline script did a destructive write.

Obviously, one alternative way of maintaining non-spec-compliant script execution would have been to extend the destructive write protection to inline scripts, but since the problem was addressable by implementing another part of the spec, I ended up implementing another part of the spec instead of extending measures that would have allowed the continued non-implementation of the other part of the spec.

> > My point is that if existing content can't rely on a characteristic,
> > the
> > spec doesn't need to provide that characteristic as a default.
> 
> ..unless it's considered better on its own merits..

And maybe not even then, since as long as browsers with the old default are around, authors would have to deal with two different defaults--in this case not even capability-sniffably distinguishable. I posit that having to deal with two defaults is worse that dealing with one default that might in a vacuum be less ideal than an alternative.

Of course, one might claim the future is longer than the transition period, but that's why we'd need some theory of time-value of feature-availability to be able to compare the transition period discounted to present value with the future discounted to present value.

> >  1) Blocking script-inserted inline scripts when there's a pending
> > external non-async script. This characteristic is so undesirable
> > that
> > it's what prompted the change in Gecko.
> 
> (An equivalent issue just caused me problems when enabling Facebook's
> @mentions with Opera's site patching, so I agree entirely that this is
> a
> bad thing.. And it seems we can follow WebKit and do it differently.)

Thanks for the data point!

> CNet (and a few other sites back then - probably more than I managed
> to
> analyze because those problems typically were hard to debug) broke
> because
> we ran document.write() inserted external scripts immediately. It
> seemed
> like a good idea at the time (since document.write() internal scripts
> run
> immediately, it was sort of seen as the most predictable way to do
> it).

I think this shows rather nicely why one should avoid meddling with the established defaults even when something else looks like a good idea.

> The problem on AOL and some other sites (a problem which is still with
> us
> actually) is caused by blocking *parsing* when exernal scripts are
> inserted through the DOM. Turns out a few sites rely on being able to
> see
> elements after the script that inserts the external script (but does
> AOL
> really work if e.g. the external script is cached?

It should work on Gecko trunk. At least I tried to make sure we don't run external scripts immediately even when the data would be available immediately.

> Re-reading some old bugs. We were forced to make a major change a
> while
> ago (we used to run external scripts as soon as they were inserted
> into
> the DOM, blocking appendChild() until the script was downloaded and
> run -
> by the time that behaviour was changed it was causing trouble for
> Dojo,
> YUI and breaking Facebook's new user registration form.. ).

Well, that, too, is something were a behavior made sense in a vacuum but deviating from the established defaults was still trouble.

-- 
Henri Sivonen
hsivonen@iki.fi
http://hsivonen.iki.fi/

Received on Monday, 18 October 2010 09:02:02 UTC