Issue #618 - (async, preload) Correctly pass info about async/defer to parser.

This makes sure we don't block body-referred sub-resources by head-referenced
defer and async scripts. This is important for all script loads, not just
modules, but is added here because it was run into while implementing modules.
This commit is contained in:
Moonchild 2020-08-24 11:11:17 +00:00 committed by Roy Tam
commit 3fa4aabfad
7 changed files with 53 additions and 15 deletions

View file

@ -6,9 +6,12 @@
#include "nsHtml5TreeOpExecutor.h"
nsHtml5SpeculativeLoad::nsHtml5SpeculativeLoad()
:
#ifdef DEBUG
: mOpCode(eSpeculativeLoadUninitialized)
mOpCode(eSpeculativeLoadUninitialized),
#endif
mIsAsync(false),
mIsDefer(false)
{
MOZ_COUNT_CTOR(nsHtml5SpeculativeLoad);
}
@ -48,11 +51,13 @@ nsHtml5SpeculativeLoad::Perform(nsHtml5TreeOpExecutor* aExecutor)
break;
case eSpeculativeLoadScript:
aExecutor->PreloadScript(mUrl, mCharset, mTypeOrCharsetSourceOrDocumentMode,
mCrossOrigin, mIntegrity, false);
mCrossOrigin, mIntegrity, false,
mIsAsync, mIsDefer);
break;
case eSpeculativeLoadScriptFromHead:
aExecutor->PreloadScript(mUrl, mCharset, mTypeOrCharsetSourceOrDocumentMode,
mCrossOrigin, mIntegrity, true);
mCrossOrigin, mIntegrity, true,
mIsAsync, mIsDefer);
break;
case eSpeculativeLoadStyle:
aExecutor->PreloadStyle(mUrl, mCharset, mCrossOrigin, mIntegrity);

View file

@ -128,7 +128,9 @@ class nsHtml5SpeculativeLoad {
nsHtml5String aType,
nsHtml5String aCrossOrigin,
nsHtml5String aIntegrity,
bool aParserInHead)
bool aParserInHead,
bool aAsync,
bool aDefer)
{
NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
"Trying to reinitialize a speculative load!");
@ -139,6 +141,8 @@ class nsHtml5SpeculativeLoad {
aType.ToString(mTypeOrCharsetSourceOrDocumentMode);
aCrossOrigin.ToString(mCrossOrigin);
aIntegrity.ToString(mIntegrity);
mIsAsync = aAsync;
mIsDefer = aDefer;
}
inline void InitStyle(nsHtml5String aUrl,
@ -221,6 +225,13 @@ class nsHtml5SpeculativeLoad {
private:
eHtml5SpeculativeLoad mOpCode;
/**
* Whether the refering element has async and/or defer attributes.
*/
bool mIsAsync;
bool mIsDefer;
nsString mUrl;
nsString mReferrerPolicy;
nsString mMetaCSP;

View file

@ -185,16 +185,20 @@ nsHtml5TreeBuilder::createElement(int32_t aNamespace,
aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN);
nsHtml5String integrity =
aAttributes->getValue(nsHtml5AttributeName::ATTR_INTEGRITY);
bool async =
aAttributes->contains(nsHtml5AttributeName::ATTR_ASYNC);
bool defer =
aAttributes->contains(nsHtml5AttributeName::ATTR_DEFER);
mSpeculativeLoadQueue.AppendElement()->InitScript(
url,
charset,
type,
crossOrigin,
integrity,
mode == nsHtml5TreeBuilder::IN_HEAD);
mCurrentHtmlScriptIsAsyncOrDefer =
aAttributes->contains(nsHtml5AttributeName::ATTR_ASYNC) ||
aAttributes->contains(nsHtml5AttributeName::ATTR_DEFER);
mode == nsHtml5TreeBuilder::IN_HEAD,
async,
defer);
mCurrentHtmlScriptIsAsyncOrDefer = async || defer;
}
} else if (nsHtml5Atoms::link == aName) {
nsHtml5String rel =
@ -297,7 +301,9 @@ nsHtml5TreeBuilder::createElement(int32_t aNamespace,
type,
crossOrigin,
integrity,
mode == nsHtml5TreeBuilder::IN_HEAD);
mode == nsHtml5TreeBuilder::IN_HEAD,
false /* async */,
false /* defer */);
}
} else if (nsHtml5Atoms::style == aName) {
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();

View file

@ -921,14 +921,16 @@ nsHtml5TreeOpExecutor::PreloadScript(const nsAString& aURL,
const nsAString& aType,
const nsAString& aCrossOrigin,
const nsAString& aIntegrity,
bool aScriptFromHead)
bool aScriptFromHead,
bool aAsync,
bool aDefer)
{
nsCOMPtr<nsIURI> uri = ConvertIfNotPreloadedYet(aURL);
if (!uri) {
return;
}
mDocument->ScriptLoader()->PreloadURI(uri, aCharset, aType, aCrossOrigin,
aIntegrity, aScriptFromHead,
aIntegrity, aScriptFromHead, aAsync, aDefer,
mSpeculationReferrerPolicy);
}

View file

@ -249,7 +249,9 @@ class nsHtml5TreeOpExecutor final : public nsHtml5DocumentBuilder,
const nsAString& aType,
const nsAString& aCrossOrigin,
const nsAString& aIntegrity,
bool aScriptFromHead);
bool aScriptFromHead,
bool aAsync,
bool aDefer);
void PreloadStyle(const nsAString& aURL, const nsAString& aCharset,
const nsAString& aCrossOrigin,