diff --git a/dom/base/Document.cpp b/dom/base/Document.cpp index 2078e286b316..7a998c8a35cd 100644 --- a/dom/base/Document.cpp +++ b/dom/base/Document.cpp @@ -12394,7 +12394,8 @@ already_AddRefed Document::ResolvePreloadImage( void Document::PreLoadImage(nsIURI* aUri, const nsAString& aCrossOriginAttr, ReferrerPolicyEnum aReferrerPolicy, bool aIsImgSet, - bool aLinkPreload, uint64_t aEarlyHintPreloaderId) { + bool aLinkPreload, uint64_t aEarlyHintPreloaderId, + const nsAString& aFetchPriority) { nsLoadFlags loadFlags = nsIRequest::LOAD_NORMAL | nsContentUtils::CORSModeToLoadImageFlags( Element::StringToCORSMode(aCrossOriginAttr)); @@ -12415,7 +12416,8 @@ void Document::PreLoadImage(nsIURI* aUri, const nsAString& aCrossOriginAttr, nsresult rv = nsContentUtils::LoadImage( aUri, static_cast(this), this, NodePrincipal(), 0, referrerInfo, nullptr /* no observer */, loadFlags, initiator, getter_AddRefs(request), - policyType, false /* urgent */, aLinkPreload, aEarlyHintPreloaderId); + policyType, false /* urgent */, aLinkPreload, aEarlyHintPreloaderId, + nsGenericHTMLElement::ToFetchPriority(aFetchPriority)); // Pin image-reference to avoid evicting it from the img-cache before // the "real" load occurs. Unpinned in DispatchContentLoadedEvents and @@ -12428,7 +12430,8 @@ void Document::PreLoadImage(nsIURI* aUri, const nsAString& aCrossOriginAttr, void Document::MaybePreLoadImage(nsIURI* aUri, const nsAString& aCrossOriginAttr, ReferrerPolicyEnum aReferrerPolicy, - bool aIsImgSet, bool aLinkPreload) { + bool aIsImgSet, bool aLinkPreload, + const nsAString& aFetchPriority) { const CORSMode corsMode = dom::Element::StringToCORSMode(aCrossOriginAttr); if (aLinkPreload) { // Check if the image was already preloaded in this document to avoid @@ -12437,7 +12440,7 @@ void Document::MaybePreLoadImage(nsIURI* aUri, PreloadHashKey::CreateAsImage(aUri, NodePrincipal(), corsMode); if (!mPreloadService.PreloadExists(key)) { PreLoadImage(aUri, aCrossOriginAttr, aReferrerPolicy, aIsImgSet, - aLinkPreload, 0); + aLinkPreload, 0, aFetchPriority); } return; } @@ -12451,7 +12454,7 @@ void Document::MaybePreLoadImage(nsIURI* aUri, // Image not in cache - trigger preload PreLoadImage(aUri, aCrossOriginAttr, aReferrerPolicy, aIsImgSet, aLinkPreload, - 0); + 0, aFetchPriority); } void Document::MaybePreconnect(nsIURI* aOrigURI, mozilla::CORSMode aCORSMode) { diff --git a/dom/base/Document.h b/dom/base/Document.h index 6a2bd55a9caa..75cffe66be3d 100644 --- a/dom/base/Document.h +++ b/dom/base/Document.h @@ -2930,10 +2930,11 @@ class Document : public nsINode, */ void MaybePreLoadImage(nsIURI* uri, const nsAString& aCrossOriginAttr, ReferrerPolicyEnum aReferrerPolicy, bool aIsImgSet, - bool aLinkPreload); + bool aLinkPreload, const nsAString& aFetchPriority); void PreLoadImage(nsIURI* uri, const nsAString& aCrossOriginAttr, ReferrerPolicyEnum aReferrerPolicy, bool aIsImgSet, - bool aLinkPreload, uint64_t aEarlyHintPreloaderId); + bool aLinkPreload, uint64_t aEarlyHintPreloaderId, + const nsAString& aFetchPriority); /** * Called by images to forget an image preload when they start doing diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp index d849b1392780..b668e3f86b00 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -4004,7 +4004,8 @@ nsresult nsContentUtils::LoadImage( int32_t aLoadFlags, const nsAString& initiatorType, imgRequestProxy** aRequest, nsContentPolicyType aContentPolicyType, bool aUseUrgentStartForChannel, bool aLinkPreload, - uint64_t aEarlyHintPreloaderId) { + uint64_t aEarlyHintPreloaderId, + mozilla::dom::FetchPriority aFetchPriority) { MOZ_ASSERT(aURI, "Must have a URI"); MOZ_ASSERT(aContext, "Must have a context"); MOZ_ASSERT(aLoadingDocument, "Must have a document"); @@ -4041,7 +4042,7 @@ nsresult nsContentUtils::LoadImage( initiatorType, /* the load initiator */ aUseUrgentStartForChannel, /* urgent-start flag */ aLinkPreload, /* initiator */ - aEarlyHintPreloaderId, aRequest); + aEarlyHintPreloaderId, aFetchPriority, aRequest); } // static diff --git a/dom/base/nsContentUtils.h b/dom/base/nsContentUtils.h index 95744fe8315b..38736f979ba2 100644 --- a/dom/base/nsContentUtils.h +++ b/dom/base/nsContentUtils.h @@ -39,6 +39,7 @@ #include "mozilla/UniquePtr.h" #include "mozilla/dom/BindingDeclarations.h" #include "mozilla/dom/FromParser.h" +#include "mozilla/dom/FetchPriority.h" #include "mozilla/fallible.h" #include "mozilla/gfx/Point.h" #include "nsCOMPtr.h" @@ -1026,7 +1027,9 @@ class nsContentUtils { nsContentPolicyType aContentPolicyType = nsIContentPolicy::TYPE_INTERNAL_IMAGE, bool aUseUrgentStartForChannel = false, bool aLinkPreload = false, - uint64_t aEarlyHintPreloaderId = 0); + uint64_t aEarlyHintPreloaderId = 0, + mozilla::dom::FetchPriority aFetchPriority = + mozilla::dom::FetchPriority::Auto); /** * Obtain an image loader that respects the given document/channel's privacy diff --git a/image/imgLoader.cpp b/image/imgLoader.cpp index 737d99ff1512..eeb90cf374ac 100644 --- a/image/imgLoader.cpp +++ b/image/imgLoader.cpp @@ -32,6 +32,7 @@ #include "mozilla/StaticPrefs_network.h" #include "mozilla/StoragePrincipalHelper.h" #include "mozilla/dom/ContentParent.h" +#include "mozilla/dom/FetchPriority.h" #include "mozilla/dom/nsMixedContentBlocker.h" #include "mozilla/image/ImageMemoryReporter.h" #include "mozilla/layers/CompositorManagerChild.h" @@ -815,6 +816,28 @@ static bool ValidateSecurityInfo(imgRequest* aRequest, /* aSendCSPViolationReports */ false); } +static void AdjustPriorityForImages(nsIChannel* aChannel, + nsLoadFlags aLoadFlags, + FetchPriority aFetchPriority) { + // Image channels are loaded by default with reduced priority. + if (nsCOMPtr supportsPriority = + do_QueryInterface(aChannel)) { + int32_t priority = nsISupportsPriority::PRIORITY_LOW; + + // Adjust priority according to fetchpriorty attribute. + if (StaticPrefs::network_fetchpriority_enabled()) { + priority += FETCH_PRIORITY_ADJUSTMENT_FOR(images, aFetchPriority); + } + + // Further reduce priority for background loads + if (aLoadFlags & nsIRequest::LOAD_BACKGROUND) { + ++priority; + } + + supportsPriority->AdjustPriority(priority); + } +} + static nsresult NewImageChannel( nsIChannel** aResult, // If aForcePrincipalCheckForCacheEntry is true, then we will @@ -828,7 +851,8 @@ static nsresult NewImageChannel( nsIReferrerInfo* aReferrerInfo, nsILoadGroup* aLoadGroup, nsLoadFlags aLoadFlags, nsContentPolicyType aPolicyType, nsIPrincipal* aTriggeringPrincipal, nsINode* aRequestingNode, - bool aRespectPrivacy, uint64_t aEarlyHintPreloaderId) { + bool aRespectPrivacy, uint64_t aEarlyHintPreloaderId, + FetchPriority aFetchPriority) { MOZ_ASSERT(aResult); nsresult rv; @@ -948,17 +972,7 @@ static nsresult NewImageChannel( } } - // Image channels are loaded by default with reduced priority. - nsCOMPtr p = do_QueryInterface(*aResult); - if (p) { - uint32_t priority = nsISupportsPriority::PRIORITY_LOW; - - if (aLoadFlags & nsIRequest::LOAD_BACKGROUND) { - ++priority; // further reduce priority for background loads - } - - p->AdjustPriority(priority); - } + AdjustPriorityForImages(*aResult, aLoadFlags, aFetchPriority); // Create a new loadgroup for this new channel, using the old group as // the parent. The indirection keeps the channel insulated from cancels, @@ -1715,7 +1729,8 @@ bool imgLoader::ValidateRequestWithNewChannel( uint64_t aInnerWindowId, nsLoadFlags aLoadFlags, nsContentPolicyType aLoadPolicyType, imgRequestProxy** aProxyRequest, nsIPrincipal* aTriggeringPrincipal, CORSMode aCORSMode, bool aLinkPreload, - uint64_t aEarlyHintPreloaderId, bool* aNewChannelCreated) { + uint64_t aEarlyHintPreloaderId, FetchPriority aFetchPriority, + bool* aNewChannelCreated) { // now we need to insert a new channel request object in between the real // request and the proxy that basically delays loading the image until it // gets a 304 or figures out that this needs to be a new request @@ -1758,11 +1773,11 @@ bool imgLoader::ValidateRequestWithNewChannel( // cache. nsCOMPtr newChannel; bool forcePrincipalCheck; - rv = - NewImageChannel(getter_AddRefs(newChannel), &forcePrincipalCheck, aURI, - aInitialDocumentURI, aCORSMode, aReferrerInfo, aLoadGroup, - aLoadFlags, aLoadPolicyType, aTriggeringPrincipal, - aLoadingDocument, mRespectPrivacy, aEarlyHintPreloaderId); + rv = NewImageChannel(getter_AddRefs(newChannel), &forcePrincipalCheck, aURI, + aInitialDocumentURI, aCORSMode, aReferrerInfo, + aLoadGroup, aLoadFlags, aLoadPolicyType, + aTriggeringPrincipal, aLoadingDocument, mRespectPrivacy, + aEarlyHintPreloaderId, aFetchPriority); if (NS_FAILED(rv)) { return false; } @@ -1841,7 +1856,7 @@ void imgLoader::NotifyObserversForCachedImage( imgCacheEntry* aEntry, imgRequest* request, nsIURI* aURI, nsIReferrerInfo* aReferrerInfo, Document* aLoadingDocument, nsIPrincipal* aTriggeringPrincipal, CORSMode aCORSMode, - uint64_t aEarlyHintPreloaderId) { + uint64_t aEarlyHintPreloaderId, FetchPriority aFetchPriority) { if (aEntry->HasNotified()) { return; } @@ -1860,7 +1875,7 @@ void imgLoader::NotifyObserversForCachedImage( getter_AddRefs(newChannel), &forcePrincipalCheck, aURI, nullptr, aCORSMode, aReferrerInfo, nullptr, 0, nsIContentPolicy::TYPE_INTERNAL_IMAGE, aTriggeringPrincipal, - aLoadingDocument, mRespectPrivacy, aEarlyHintPreloaderId); + aLoadingDocument, mRespectPrivacy, aEarlyHintPreloaderId, aFetchPriority); if (NS_FAILED(rv)) { return; } @@ -1885,7 +1900,8 @@ bool imgLoader::ValidateEntry( nsLoadFlags aLoadFlags, nsContentPolicyType aLoadPolicyType, bool aCanMakeNewChannel, bool* aNewChannelCreated, imgRequestProxy** aProxyRequest, nsIPrincipal* aTriggeringPrincipal, - CORSMode aCORSMode, bool aLinkPreload, uint64_t aEarlyHintPreloaderId) { + CORSMode aCORSMode, bool aLinkPreload, uint64_t aEarlyHintPreloaderId, + FetchPriority aFetchPriority) { LOG_SCOPE(gImgLog, "imgLoader::ValidateEntry"); // If the expiration time is zero, then the request has not gotten far enough @@ -2013,13 +2029,13 @@ bool imgLoader::ValidateEntry( request, aURI, aInitialDocumentURI, aReferrerInfo, aLoadGroup, aObserver, aLoadingDocument, innerWindowID, aLoadFlags, aLoadPolicyType, aProxyRequest, aTriggeringPrincipal, aCORSMode, aLinkPreload, - aEarlyHintPreloaderId, aNewChannelCreated); + aEarlyHintPreloaderId, aFetchPriority, aNewChannelCreated); } if (!validateRequest) { - NotifyObserversForCachedImage(aEntry, request, aURI, aReferrerInfo, - aLoadingDocument, aTriggeringPrincipal, - aCORSMode, aEarlyHintPreloaderId); + NotifyObserversForCachedImage( + aEntry, request, aURI, aReferrerInfo, aLoadingDocument, + aTriggeringPrincipal, aCORSMode, aEarlyHintPreloaderId, aFetchPriority); } return !validateRequest; @@ -2174,7 +2190,7 @@ imgLoader::LoadImageXPCOM( 0, aLoadGroup, aObserver, aLoadingDocument, aLoadingDocument, aLoadFlags, aCacheKey, aContentPolicyType, u""_ns, /* aUseUrgentStartForChannel */ false, /* aListPreload */ false, - 0, &proxy); + 0, FetchPriority::Auto, &proxy); *_retval = proxy; return rv; } @@ -2233,7 +2249,7 @@ nsresult imgLoader::LoadImage( nsISupports* aCacheKey, nsContentPolicyType aContentPolicyType, const nsAString& initiatorType, bool aUseUrgentStartForChannel, bool aLinkPreload, uint64_t aEarlyHintPreloaderId, - imgRequestProxy** _retval) { + FetchPriority aFetchPriority, imgRequestProxy** _retval) { VerifyCacheSizes(); NS_ASSERTION(aURI, "imgLoader::LoadImage -- NULL URI pointer"); @@ -2386,7 +2402,7 @@ nsresult imgLoader::LoadImage( aLoadGroup, aObserver, aLoadingDocument, requestFlags, aContentPolicyType, true, &newChannelCreated, _retval, aTriggeringPrincipal, corsmode, aLinkPreload, - aEarlyHintPreloaderId)) { + aEarlyHintPreloaderId, aFetchPriority)) { request = entry->GetRequest(); // If this entry has no proxies, its request has no reference to the @@ -2436,7 +2452,7 @@ nsresult imgLoader::LoadImage( aInitialDocumentURI, corsmode, aReferrerInfo, aLoadGroup, requestFlags, aContentPolicyType, aTriggeringPrincipal, aContext, mRespectPrivacy, - aEarlyHintPreloaderId); + aEarlyHintPreloaderId, aFetchPriority); if (NS_FAILED(rv)) { return NS_ERROR_FAILURE; } @@ -2650,7 +2666,8 @@ nsresult imgLoader::LoadImageWithChannel(nsIChannel* channel, if (ValidateEntry(entry, uri, nullptr, nullptr, nullptr, aObserver, aLoadingDocument, requestFlags, policyType, false, - nullptr, nullptr, nullptr, corsMode, false, 0)) { + nullptr, nullptr, nullptr, corsMode, false, 0, + FetchPriority::Auto)) { request = entry->GetRequest(); } else { nsCOMPtr cacheChan(do_QueryInterface(channel)); diff --git a/image/imgLoader.h b/image/imgLoader.h index c5155067903d..742351792533 100644 --- a/image/imgLoader.h +++ b/image/imgLoader.h @@ -37,6 +37,7 @@ class imgMemoryReporter; namespace mozilla { namespace dom { class Document; +enum class FetchPriority : uint8_t; } } // namespace mozilla @@ -238,7 +239,8 @@ class imgLoader final : public imgILoader, nsLoadFlags aLoadFlags, nsISupports* aCacheKey, nsContentPolicyType aContentPolicyType, const nsAString& initiatorType, bool aUseUrgentStartForChannel, bool aLinkPreload, - uint64_t aEarlyHintPreloaderId, imgRequestProxy** _retval); + uint64_t aEarlyHintPreloaderId, + mozilla::dom::FetchPriority aFetchPriority, imgRequestProxy** _retval); [[nodiscard]] nsresult LoadImageWithChannel( nsIChannel* channel, imgINotificationObserver* aObserver, @@ -349,7 +351,8 @@ class imgLoader final : public imgILoader, bool aCanMakeNewChannel, bool* aNewChannelCreated, imgRequestProxy** aProxyRequest, nsIPrincipal* aTriggeringPrincipal, mozilla::CORSMode, - bool aLinkPreload, uint64_t aEarlyHintPreloaderId); + bool aLinkPreload, uint64_t aEarlyHintPreloaderId, + mozilla::dom::FetchPriority aFetchPriority); bool ValidateRequestWithNewChannel( imgRequest* request, nsIURI* aURI, nsIURI* aInitialDocumentURI, @@ -359,15 +362,14 @@ class imgLoader final : public imgILoader, nsLoadFlags aLoadFlags, nsContentPolicyType aContentPolicyType, imgRequestProxy** aProxyRequest, nsIPrincipal* aLoadingPrincipal, mozilla::CORSMode, bool aLinkPreload, uint64_t aEarlyHintPreloaderId, - bool* aNewChannelCreated); + mozilla::dom::FetchPriority aFetchPriority, bool* aNewChannelCreated); - void NotifyObserversForCachedImage(imgCacheEntry* aEntry, imgRequest* request, - nsIURI* aURI, - nsIReferrerInfo* aReferrerInfo, - mozilla::dom::Document* aLoadingDocument, - nsIPrincipal* aLoadingPrincipal, - mozilla::CORSMode, - uint64_t aEarlyHintPreloaderId); + void NotifyObserversForCachedImage( + imgCacheEntry* aEntry, imgRequest* request, nsIURI* aURI, + nsIReferrerInfo* aReferrerInfo, mozilla::dom::Document* aLoadingDocument, + nsIPrincipal* aTriggeringPrincipal, mozilla::CORSMode, + uint64_t aEarlyHintPreloaderId, + mozilla::dom::FetchPriority aFetchPriority); // aURI may be different from imgRequest's URI in the case of blob URIs, as we // can share requests with different URIs. nsresult CreateNewProxyForRequest(imgRequest* aRequest, nsIURI* aURI, diff --git a/layout/generic/nsImageFrame.cpp b/layout/generic/nsImageFrame.cpp index e0a6243ed2ad..ddeff68f23b4 100644 --- a/layout/generic/nsImageFrame.cpp +++ b/layout/generic/nsImageFrame.cpp @@ -18,6 +18,7 @@ #include "mozilla/DebugOnly.h" #include "mozilla/Encoding.h" #include "mozilla/HTMLEditor.h" +#include "mozilla/dom/FetchPriority.h" #include "mozilla/dom/ImageTracker.h" #include "mozilla/gfx/2D.h" #include "mozilla/gfx/Helpers.h" @@ -268,7 +269,7 @@ BrokenImageIcon::BrokenImageIcon(const nsImageFrame& aFrame) { loadFlags, nullptr, contentPolicyType, u""_ns, false, /* aUseUrgentStartForChannel */ false, /* aLinkPreload */ - 0, getter_AddRefs(mImage)); + 0, FetchPriority::Auto, getter_AddRefs(mImage)); Unused << NS_WARN_IF(NS_FAILED(rv)); } diff --git a/modules/libpref/init/StaticPrefList.yaml b/modules/libpref/init/StaticPrefList.yaml index 4e54ae1d3c53..23d03397d58b 100644 --- a/modules/libpref/init/StaticPrefList.yaml +++ b/modules/libpref/init/StaticPrefList.yaml @@ -11993,6 +11993,26 @@ value: 0 mirror: always +# Adjustments to apply to the internal priority of and with +# respect to the case when network.fetchpriority is disabled. +# - When the flag is disabled, Gecko currently sets priority to LOW. +# - When the flag is enabled, it respectively maps to LOW/LOW/HIGH. +# The image code can currently further adjust the priority for image load, see +# imgRequest::BoostPriority and AdjustPriorityForImages. +- name: network.fetchpriority.adjustments.images.low + type: int32_t + value: 0 + mirror: always +- name: network.fetchpriority.adjustments.images.high + type: int32_t + value: -20 + mirror: always +- name: network.fetchpriority.adjustments.images.auto + type: int32_t + value: 0 + mirror: always + # Enables `` tag and `Link: rel=preconnect` response header # handling. - name: network.preconnect diff --git a/parser/html/nsHtml5SpeculativeLoad.cpp b/parser/html/nsHtml5SpeculativeLoad.cpp index b85c31f655c6..4ddc15b957ab 100644 --- a/parser/html/nsHtml5SpeculativeLoad.cpp +++ b/parser/html/nsHtml5SpeculativeLoad.cpp @@ -45,7 +45,7 @@ void nsHtml5SpeculativeLoad::Perform(nsHtml5TreeOpExecutor* aExecutor) { aExecutor->PreloadImage( mUrlOrSizes, mCrossOrigin, mMedia, mCharsetOrSrcset, mTypeOrCharsetSourceOrDocumentModeOrMetaCSPOrSizesOrIntegrity, - mReferrerPolicyOrIntegrity, mIsLinkPreload); + mReferrerPolicyOrIntegrity, mIsLinkPreload, mFetchPriority); break; case eSpeculativeLoadOpenPicture: aExecutor->PreloadOpenPicture(); diff --git a/parser/html/nsHtml5SpeculativeLoad.h b/parser/html/nsHtml5SpeculativeLoad.h index d53d3a5b46cc..61ec92e6a4e9 100644 --- a/parser/html/nsHtml5SpeculativeLoad.h +++ b/parser/html/nsHtml5SpeculativeLoad.h @@ -75,7 +75,7 @@ class nsHtml5SpeculativeLoad { inline void InitImage(nsHtml5String aUrl, nsHtml5String aCrossOrigin, nsHtml5String aMedia, nsHtml5String aReferrerPolicy, nsHtml5String aSrcset, nsHtml5String aSizes, - bool aLinkPreload) { + bool aLinkPreload, nsHtml5String aFetchPriority) { MOZ_ASSERT(mOpCode == eSpeculativeLoadUninitialized, "Trying to reinitialize a speculative load!"); mOpCode = eSpeculativeLoadImage; @@ -92,6 +92,7 @@ class nsHtml5SpeculativeLoad { aSizes.ToString( mTypeOrCharsetSourceOrDocumentModeOrMetaCSPOrSizesOrIntegrity); mIsLinkPreload = aLinkPreload; + aFetchPriority.ToString(mFetchPriority); } inline void InitFont(nsHtml5String aUrl, nsHtml5String aCrossOrigin, diff --git a/parser/html/nsHtml5TreeBuilderCppSupplement.h b/parser/html/nsHtml5TreeBuilderCppSupplement.h index f39f456663d1..2eb7fa91ee52 100644 --- a/parser/html/nsHtml5TreeBuilderCppSupplement.h +++ b/parser/html/nsHtml5TreeBuilderCppSupplement.h @@ -215,9 +215,16 @@ nsIContentHandle* nsHtml5TreeBuilder::createElement( nsHtml5AttributeName::ATTR_REFERRERPOLICY); nsHtml5String sizes = aAttributes->getValue(nsHtml5AttributeName::ATTR_SIZES); + + // TODO: support the fetchpriority attribute in bug 1839313. + // Meanwhile the empty string is used since it's mapped to the + // auto state + // (https://html.spec.whatwg.org/#fetch-priority-attribute). + auto fetchPriority = nsHtml5String::EmptyString(); + mSpeculativeLoadQueue.AppendElement()->InitImage( url, crossOrigin, /* aMedia = */ nullptr, referrerPolicy, - srcset, sizes, false); + srcset, sizes, false, fetchPriority); } } else if (nsGkAtoms::source == aName) { nsHtml5String srcset = @@ -435,7 +442,7 @@ nsIContentHandle* nsHtml5TreeBuilder::createElement( nsHtml5AttributeName::ATTR_IMAGESIZES); mSpeculativeLoadQueue.AppendElement()->InitImage( url, crossOrigin, media, referrerPolicy, srcset, sizes, - true); + true, fetchPriority); } else if (as.LowerCaseEqualsASCII("font")) { mSpeculativeLoadQueue.AppendElement()->InitFont( url, crossOrigin, media, referrerPolicy, fetchPriority); @@ -487,8 +494,14 @@ nsIContentHandle* nsHtml5TreeBuilder::createElement( nsHtml5String url = aAttributes->getValue(nsHtml5AttributeName::ATTR_POSTER); if (url) { + // Fetch priority is not supported for video. Nullptr will map to + // the auto state + // (https://html.spec.whatwg.org/#fetch-priority-attribute). + auto fetchPriority = nullptr; + mSpeculativeLoadQueue.AppendElement()->InitImage( - url, nullptr, nullptr, nullptr, nullptr, nullptr, false); + url, nullptr, nullptr, nullptr, nullptr, nullptr, false, + fetchPriority); } } else if (nsGkAtoms::style == aName) { mImportScanner.Start(); @@ -543,8 +556,15 @@ nsIContentHandle* nsHtml5TreeBuilder::createElement( url = aAttributes->getValue(nsHtml5AttributeName::ATTR_XLINK_HREF); } if (url) { + // Currently SVG's `` element lacks support for + // `fetchpriority`, see bug 1847712. Hence passing nullptr which + // maps to the auto state + // (https://html.spec.whatwg.org/#fetch-priority-attribute). + auto fetchPriority = nullptr; + mSpeculativeLoadQueue.AppendElement()->InitImage( - url, nullptr, nullptr, nullptr, nullptr, nullptr, false); + url, nullptr, nullptr, nullptr, nullptr, nullptr, false, + fetchPriority); } } else if (nsGkAtoms::script == aName) { nsHtml5TreeOperation* treeOp = diff --git a/parser/html/nsHtml5TreeOpExecutor.cpp b/parser/html/nsHtml5TreeOpExecutor.cpp index 3cb38dcf28a5..f2c47c42a6b6 100644 --- a/parser/html/nsHtml5TreeOpExecutor.cpp +++ b/parser/html/nsHtml5TreeOpExecutor.cpp @@ -1261,7 +1261,8 @@ void nsHtml5TreeOpExecutor::PreloadStyle( void nsHtml5TreeOpExecutor::PreloadImage( const nsAString& aURL, const nsAString& aCrossOrigin, const nsAString& aMedia, const nsAString& aSrcset, const nsAString& aSizes, - const nsAString& aImageReferrerPolicy, bool aLinkPreload) { + const nsAString& aImageReferrerPolicy, bool aLinkPreload, + const nsAString& aFetchPriority) { nsCOMPtr baseURI = BaseURIForPreload(); bool isImgSet = false; nsCOMPtr uri = @@ -1270,7 +1271,7 @@ void nsHtml5TreeOpExecutor::PreloadImage( // use document wide referrer policy mDocument->MaybePreLoadImage(uri, aCrossOrigin, GetPreloadReferrerPolicy(aImageReferrerPolicy), - isImgSet, aLinkPreload); + isImgSet, aLinkPreload, aFetchPriority); } } diff --git a/parser/html/nsHtml5TreeOpExecutor.h b/parser/html/nsHtml5TreeOpExecutor.h index 3a8225614770..169fa5a703a6 100644 --- a/parser/html/nsHtml5TreeOpExecutor.h +++ b/parser/html/nsHtml5TreeOpExecutor.h @@ -260,7 +260,8 @@ class nsHtml5TreeOpExecutor final void PreloadImage(const nsAString& aURL, const nsAString& aCrossOrigin, const nsAString& aMedia, const nsAString& aSrcset, const nsAString& aSizes, - const nsAString& aImageReferrerPolicy, bool aLinkPreload); + const nsAString& aImageReferrerPolicy, bool aLinkPreload, + const nsAString& aFetchPriority); void PreloadOpenPicture(); diff --git a/testing/web-platform/mozilla/meta/fetch/fetchpriority/fetchpriority.h2.html.ini b/testing/web-platform/mozilla/meta/fetch/fetchpriority/fetchpriority.h2.html.ini index d2ed4028dee8..e87dcd4c44e0 100644 --- a/testing/web-platform/mozilla/meta/fetch/fetchpriority/fetchpriority.h2.html.ini +++ b/testing/web-platform/mozilla/meta/fetch/fetchpriority/fetchpriority.h2.html.ini @@ -1,15 +1,6 @@ [fetchpriority.h2.html] lsan-allowed: [mozilla::net::AddStaticElement, InitializeStaticHeaders, mozilla::net::nvFIFO::nvFIFO, mozilla::net::Http2BaseCompressor::Http2BaseCompressor] # https://bugzilla.mozilla.org/show_bug.cgi?id=1759310 prefs: [network.fetchpriority.enabled:true] - [link-initial-preload-image.h2.html: test different 'fetchpriority' values] - expected: FAIL - - [link-dynamic-preload-image.h2.html: test different 'fetchpriority' values] - expected: FAIL - - [link-header.h2.html?pipe=|header(Link,; rel=preload; as=image; fetchpriority=low,True)|header(Link,; rel=preload; as=image; fetchpriority=high,True)|header(Link,; rel=preload; as=image; fetchpriority=auto,True)|header(Link,; rel=preload; as=image,True): test different 'fetchpriority' values] - expected: FAIL - [image-dynamic-load.h2.html: test different 'fetchpriority' values] expected: FAIL diff --git a/testing/web-platform/mozilla/tests/fetch/fetchpriority/fetchpriority-adjustments.html b/testing/web-platform/mozilla/tests/fetch/fetchpriority/fetchpriority-adjustments.html index 3027cddf310c..71bfbcc0b587 100644 --- a/testing/web-platform/mozilla/tests/fetch/fetchpriority/fetchpriority-adjustments.html +++ b/testing/web-platform/mozilla/tests/fetch/fetchpriority/fetchpriority-adjustments.html @@ -18,6 +18,7 @@ "link-preload-style": SpecialPowers.Ci.nsISupportsPriority.PRIORITY_HIGHEST, "non-deferred-style": SpecialPowers.Ci.nsISupportsPriority.PRIORITY_NORMAL, "global-fetch-api": SpecialPowers.Ci.nsISupportsPriority.PRIORITY_NORMAL, + "images": SpecialPowers.Ci.nsISupportsPriority.PRIORITY_LOW, }; for (const name in prioritiesWhenFetchpriorityDisabled) { let adjustments = {}; diff --git a/testing/web-platform/mozilla/tests/fetch/fetchpriority/support/link-tests-data.js b/testing/web-platform/mozilla/tests/fetch/fetchpriority/support/link-tests-data.js index d20de07fbabf..1606894e2e1e 100644 --- a/testing/web-platform/mozilla/tests/fetch/fetchpriority/support/link-tests-data.js +++ b/testing/web-platform/mozilla/tests/fetch/fetchpriority/support/link-tests-data.js @@ -113,16 +113,16 @@ const kExpectedRequestsOfLinkPreloadFontDisabled = [ const kExpectedRequestsOfLinkPreloadImage = [ { fileNameAndSuffix: "dummy.image?1", - internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_LOW + internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_LOW + 1 }, { fileNameAndSuffix: "dummy.image?2", - internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_HIGH + internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_HIGH + 1 }, { fileNameAndSuffix: "dummy.image?3", - internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_LOW + internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_LOW + 1 }, { fileNameAndSuffix: "dummy.image?4", - internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_LOW + internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_LOW + 1 }, ]; diff --git a/uriloader/preload/PreloadService.cpp b/uriloader/preload/PreloadService.cpp index 845c06ef3392..48cf9a364cee 100644 --- a/uriloader/preload/PreloadService.cpp +++ b/uriloader/preload/PreloadService.cpp @@ -226,7 +226,8 @@ PreloadService::PreloadOrCoalesceResult PreloadService::PreloadOrCoalesce( break; } } else if (aAs.LowerCaseEqualsASCII("image")) { - PreloadImage(uri, aCORS, aReferrerPolicy, isImgSet, aEarlyHintPreloaderId); + PreloadImage(uri, aCORS, aReferrerPolicy, isImgSet, aEarlyHintPreloaderId, + aFetchPriority); } else if (aAs.LowerCaseEqualsASCII("font")) { PreloadFont(uri, aCORS, aReferrerPolicy, aEarlyHintPreloaderId, aFetchPriority); @@ -258,10 +259,11 @@ void PreloadService::PreloadScript( void PreloadService::PreloadImage(nsIURI* aURI, const nsAString& aCrossOrigin, const nsAString& aImageReferrerPolicy, bool aIsImgSet, - uint64_t aEarlyHintPreloaderId) { - mDocument->PreLoadImage(aURI, aCrossOrigin, - PreloadReferrerPolicy(aImageReferrerPolicy), - aIsImgSet, true, aEarlyHintPreloaderId); + uint64_t aEarlyHintPreloaderId, + const nsAString& aFetchPriority) { + mDocument->PreLoadImage( + aURI, aCrossOrigin, PreloadReferrerPolicy(aImageReferrerPolicy), + aIsImgSet, true, aEarlyHintPreloaderId, aFetchPriority); } void PreloadService::PreloadFont(nsIURI* aURI, const nsAString& aCrossOrigin, diff --git a/uriloader/preload/PreloadService.h b/uriloader/preload/PreloadService.h index 5f6566ea34cc..79f5e7b6d137 100644 --- a/uriloader/preload/PreloadService.h +++ b/uriloader/preload/PreloadService.h @@ -90,7 +90,8 @@ class PreloadService { void PreloadImage(nsIURI* aURI, const nsAString& aCrossOrigin, const nsAString& aImageReferrerPolicy, bool aIsImgSet, - uint64_t aEarlyHintPreloaderId); + uint64_t aEarlyHintPreloaderId, + const nsAString& aFetchPriority); void PreloadFont(nsIURI* aURI, const nsAString& aCrossOrigin, const nsAString& aReferrerPolicy, diff --git a/widget/IconLoader.cpp b/widget/IconLoader.cpp index 5c0488e3e21e..41d2a29bc741 100644 --- a/widget/IconLoader.cpp +++ b/widget/IconLoader.cpp @@ -9,6 +9,7 @@ #include "imgLoader.h" #include "imgRequestProxy.h" #include "mozilla/dom/Document.h" +#include "mozilla/dom/FetchPriority.h" #include "nsContentUtils.h" #include "nsIContent.h" #include "nsIContentPolicy.h" @@ -63,7 +64,7 @@ nsresult IconLoader::LoadIcon(nsIURI* aIconURI, nsINode* aNode, nullptr, nsIRequest::LOAD_NORMAL, nullptr, nsIContentPolicy::TYPE_INTERNAL_IMAGE, u""_ns, /* aUseUrgentStartForChannel */ false, /* aLinkPreload */ false, 0, - getter_AddRefs(mIconRequest)); + dom::FetchPriority::Auto, getter_AddRefs(mIconRequest)); } else { // TODO: nsIContentPolicy::TYPE_INTERNAL_IMAGE may not be the correct // policy. See bug 1691868 for more details. @@ -72,7 +73,8 @@ nsresult IconLoader::LoadIcon(nsIURI* aIconURI, nsINode* aNode, aNode, document, nsIRequest::LOAD_NORMAL, nullptr, nsIContentPolicy::TYPE_INTERNAL_IMAGE, u""_ns, /* aUseUrgentStartForChannel */ false, - /* aLinkPreload */ false, 0, getter_AddRefs(mIconRequest)); + /* aLinkPreload */ false, 0, dom::FetchPriority::Auto, + getter_AddRefs(mIconRequest)); } if (NS_FAILED(rv)) { return rv;