mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-07 09:54:42 +00:00
Bug 1872657 - Add fetchpriority support for <link rel=preload as=image>
. r=valentin,smaug,manuel
This patch adds fetchpriority support for `<link rel=preload as=image>` and equivalent HTTP Link header. The fetchpriority value is passed from where the link is parsed down to `NewImageChannel` where the priority is initially set. Currently, the default equals PRIORITY_LOW, but is decreased a bit if LOAD_BACKGROUND flag is set (this is always the case for link preload images, see `imgLoader::LoadImage`). Later, the priority can be increased again depending on the category (see `imgRequest::BoostPriority`). In order to minimize the changes, the new calculation is to keep the initial setting to PRIORITY_LOW, adjust it using a new `network.fetchpriority.adjustments.*` preference depending on the fetchpriority attributes, and then preserve further adjustments for LOAD_BACKGROUND and `BoostPriority`. For the default value `fetchpriority=auto`, there is no adjustment i.e. we continue to start with PRIORITY_LOW. `fetchpriority=low/high` are respectively mapped to PRIORITY_LOW/PRIORITY_HIGH which is simple and consistent with the "Image" cases from Google's web.dev article https://web.dev/articles/fetch-priority. These values could of course be revised in the future after more experiments. This change is covered by the following tests below. The expectations is modified to match what is described above (i.e. map to PRIORITY_LOW or PRIORITY_HIGH with adjustment due to LOAD_BACKGROUND): - `link-initial-preload-image.h2.html` - `link-dynamic-preload-image.h2.html` - `kPipeHeaderPreloadImageLinks` Based on a patch by Mirko Brodesser (mbrodesser@igalia.com) Differential Revision: https://phabricator.services.mozilla.com/D197493
This commit is contained in:
parent
61e25ea963
commit
b005b82248
@ -12394,7 +12394,8 @@ already_AddRefed<nsIURI> 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<nsINode*>(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) {
|
||||
|
@ -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
|
||||
|
@ -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, /* <link preload> initiator */
|
||||
aEarlyHintPreloaderId, aRequest);
|
||||
aEarlyHintPreloaderId, aFetchPriority, aRequest);
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -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
|
||||
|
@ -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<nsISupportsPriority> 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<nsISupportsPriority> 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<nsIChannel> 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<nsICacheInfoChannel> cacheChan(do_QueryInterface(channel));
|
||||
|
@ -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,
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -11993,6 +11993,26 @@
|
||||
value: 0
|
||||
mirror: always
|
||||
|
||||
# Adjustments to apply to the internal priority of <link rel=preload as=images
|
||||
# fetchpriority=low/high/auto> and <img fetchpriority=low/high/auto> 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 `<link rel="preconnect">` tag and `Link: rel=preconnect` response header
|
||||
# handling.
|
||||
- name: network.preconnect
|
||||
|
@ -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();
|
||||
|
@ -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,
|
||||
|
@ -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 `<image>` 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 =
|
||||
|
@ -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<nsIURI> baseURI = BaseURIForPreload();
|
||||
bool isImgSet = false;
|
||||
nsCOMPtr<nsIURI> uri =
|
||||
@ -1270,7 +1271,7 @@ void nsHtml5TreeOpExecutor::PreloadImage(
|
||||
// use document wide referrer policy
|
||||
mDocument->MaybePreLoadImage(uri, aCrossOrigin,
|
||||
GetPreloadReferrerPolicy(aImageReferrerPolicy),
|
||||
isImgSet, aLinkPreload);
|
||||
isImgSet, aLinkPreload, aFetchPriority);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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,<dummy.image?1>; rel=preload; as=image; fetchpriority=low,True)|header(Link,<dummy.image?2>; rel=preload; as=image; fetchpriority=high,True)|header(Link,<dummy.image?3>; rel=preload; as=image; fetchpriority=auto,True)|header(Link,<dummy.image?4>; rel=preload; as=image,True): test different 'fetchpriority' values]
|
||||
expected: FAIL
|
||||
|
||||
[image-dynamic-load.h2.html: test different 'fetchpriority' values]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -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 = {};
|
||||
|
@ -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
|
||||
},
|
||||
];
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user