author | Honza Bambas <honzab.moz@firemni.cz> |
Tue, 23 Jun 2020 17:18:20 +0000 | |
changeset 536940 | 754e4ddef9b931f75d7bfe0e766b3eb5e092020a |
parent 536939 | 995ec4cd01aa21900d8099eca3be320e68c1ea72 |
child 536941 | 990dce4af7cffabeceec07e34cf2e3c658ebacf1 |
push id | 37533 |
push user | dluca@mozilla.com |
push date | Tue, 23 Jun 2020 21:38:40 +0000 |
treeherder | mozilla-central@d48aa0f0aa0b [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | Harald |
bugs | 1603542 |
milestone | 79.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/dom/locales/en-US/chrome/dom/dom.properties +++ b/dom/locales/en-US/chrome/dom/dom.properties @@ -384,8 +384,10 @@ MathML_DeprecatedScriptShiftAttributes=MathML attributes “subscriptshift” and “superscriptshift” are deprecated and may be removed at a future date. MathML_DeprecatedStyleAttributeWarning=MathML attributes “background”, “color”, “fontfamily”, “fontsize”, “fontstyle” and “fontweight” are deprecated and will be removed at a future date. # LOCALIZATION NOTE: Do not translate MathML and XLink. MathML_DeprecatedXLinkAttributeWarning=XLink attributes “href”, “type”, “show” and “actuate” are deprecated on MathML elements and will be removed at a future date. WebShareAPI_Failed=The share operation has failed. WebShareAPI_Aborted=The share operation was aborted. # LOCALIZATION NOTE (UnknownProtocolNavigationPrevented): %1$S is the destination URL. UnknownProtocolNavigationPrevented=Prevented navigation to “%1$S” due to an unknown protocol. PostMessageSharedMemoryObjectToCrossOriginWarning=Cannot post message containing a shared memory object to a cross-origin window. +# LOCALIZATION NOTE: %S is the URL of the resource in question +UnusedLinkPreloadPending=The resource at “%S” preloaded with link preload was not used within a few seconds. Make sure all attributes of the preload tag are set correctly.
--- a/uriloader/preload/PreloaderBase.cpp +++ b/uriloader/preload/PreloaderBase.cpp @@ -1,15 +1,16 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "PreloaderBase.h" #include "mozilla/dom/Document.h" +#include "nsContentUtils.h" #include "nsIAsyncVerifyRedirectCallback.h" #include "nsIChannel.h" #include "nsILoadGroup.h" #include "nsIInterfaceRequestorUtils.h" // Change this if we want to cancel and remove the associated preload on removal // of all <link rel=preload> tags from the tree. constexpr static bool kCancelAndRemovePreloadOnZeroReferences = false; @@ -106,17 +107,19 @@ void PreloaderBase::NotifyOpen(const Pre mIsUsed = !aIsPreload; } void PreloaderBase::NotifyOpen(const PreloadHashKey& aKey, nsIChannel* aChannel, dom::Document* aDocument, bool aIsPreload) { NotifyOpen(aKey, aDocument, aIsPreload); mChannel = aChannel; - // * Start the usage timer if aIsPreload. + auto callback = MakeRefPtr<UsageTimer>(this, aDocument); + NS_NewTimerWithCallback(getter_AddRefs(mUsageTimer), callback, 10000, + nsITimer::TYPE_ONE_SHOT); nsCOMPtr<nsIInterfaceRequestor> callbacks; mChannel->GetNotificationCallbacks(getter_AddRefs(callbacks)); RefPtr<RedirectSink> sink(new RedirectSink(this, callbacks)); mChannel->SetNotificationCallbacks(sink); } void PreloaderBase::NotifyUsage(LoadBackground aLoadBackground) { @@ -141,31 +144,32 @@ void PreloaderBase::NotifyUsage(LoadBack if (NS_SUCCEEDED(rv)) { loadGroup->AddRequest(mChannel, nullptr); } } } } mIsUsed = true; - - // * Cancel the usage timer. + CancelUsageTimer(); } void PreloaderBase::RemoveSelf(dom::Document* aDocument) { if (aDocument) { aDocument->Preloads().DeregisterPreload(mKey); } } void PreloaderBase::NotifyRestart(dom::Document* aDocument, PreloaderBase* aNewPreloader) { RemoveSelf(aDocument); mKey = PreloadHashKey(); + CancelUsageTimer(); + if (aNewPreloader) { aNewPreloader->mNodes = std::move(mNodes); } } void PreloaderBase::NotifyStart(nsIRequest* aRequest) { // If there is no channel assigned on this preloader, we are not between // channel switching, so we can freely update the mShouldFireLoadEvent using @@ -249,16 +253,23 @@ void PreloaderBase::RemoveLinkPreloadNod } } void PreloaderBase::NotifyNodeEvent(nsINode* aNode) { PreloadService::NotifyNodeEvent( aNode, mShouldFireLoadEvent || NS_SUCCEEDED(*mOnStopStatus)); } +void PreloaderBase::CancelUsageTimer() { + if (mUsageTimer) { + mUsageTimer->Cancel(); + mUsageTimer = nullptr; + } +} + nsresult PreloaderBase::AsyncConsume(nsIStreamListener* aListener) { // We want to return an error so that consumers can't ever use a preload to // consume data unless it's properly implemented. return NS_ERROR_NOT_IMPLEMENTED; } // PreloaderBase::RedirectRecord @@ -270,9 +281,43 @@ nsCString PreloaderBase::RedirectRecord: } nsCString PreloaderBase::RedirectRecord::Fragment() const { nsCString fragment; mURI->GetRef(fragment); return fragment; } +// PreloaderBase::UsageTimer + +NS_IMPL_ISUPPORTS(PreloaderBase::UsageTimer, nsITimerCallback) + +NS_IMETHODIMP PreloaderBase::UsageTimer::Notify(nsITimer* aTimer) { + if (!mPreload || !mDocument) { + return NS_OK; + } + + MOZ_ASSERT(aTimer == mPreload->mUsageTimer); + mPreload->mUsageTimer = nullptr; + + if (mPreload->IsUsed()) { + // Left in the hashtable, but marked as used. This is a valid case, and we + // don't want to emit a warning for this preload then. + return NS_OK; + } + + // PreloadHashKey overrides GetKey, we need to use the nsURIHashKey one to get + // the URI. + nsIURI* uri = static_cast<nsURIHashKey*>(&mPreload->mKey)->GetKey(); + if (!uri) { + return NS_OK; + } + nsString spec = NS_ConvertUTF8toUTF16(uri->GetSpecOrDefault()); + + nsContentUtils::ReportToConsole( + nsIScriptError::warningFlag, NS_LITERAL_CSTRING("DOM"), mDocument, + nsContentUtils::eDOM_PROPERTIES, "UnusedLinkPreloadPending", + nsTArray<nsString>({spec})); + + return NS_OK; +} + } // namespace mozilla
--- a/uriloader/preload/PreloaderBase.h +++ b/uriloader/preload/PreloaderBase.h @@ -6,16 +6,17 @@ #define PreloaderBase_h__ #include "mozilla/Maybe.h" #include "mozilla/PreloadHashKey.h" #include "mozilla/WeakPtr.h" #include "nsIChannelEventSink.h" #include "nsIInterfaceRequestor.h" #include "nsIRedirectResultListener.h" +#include "nsITimer.h" #include "nsIURI.h" #include "nsTArray.h" #include "nsProxyRelease.h" #include "nsWeakReference.h" class nsIChannel; class nsINode; class nsIRequest; @@ -136,16 +137,17 @@ class PreloaderBase : public SupportsWea protected: virtual ~PreloaderBase(); // The loading channel. This will update when a redirect occurs. nsCOMPtr<nsIChannel> mChannel; private: void NotifyNodeEvent(nsINode* aNode); + void CancelUsageTimer(); // A helper class that will update the PreloaderBase.mChannel member when a // redirect happens, so that we can reprioritize or cancel when needed. // Having a separate class instead of implementing this on PreloaderBase // directly is to keep PreloaderBase as simple as possible so that derived // classes don't have to deal with calling super when implementing these // interfaces from some reason as well. class RedirectSink final : public nsIInterfaceRequestor, @@ -163,24 +165,43 @@ class PreloaderBase : public SupportsWea RedirectSink(PreloaderBase* aPreloader, nsIInterfaceRequestor* aCallbacks); private: nsMainThreadPtrHandle<PreloaderBase> mPreloader; nsCOMPtr<nsIInterfaceRequestor> mCallbacks; nsCOMPtr<nsIChannel> mRedirectChannel; }; + // A timer callback to trigger the unuse warning for this preload + class UsageTimer final : public nsITimerCallback { + NS_DECL_ISUPPORTS + NS_DECL_NSITIMERCALLBACK + + UsageTimer(PreloaderBase* aPreload, dom::Document* aDocument) + : mDocument(aDocument), mPreload(aPreload) {} + + private: + ~UsageTimer() = default; + + WeakPtr<dom::Document> mDocument; + WeakPtr<PreloaderBase> mPreload; + }; + private: // Reference to HTMLLinkElement DOM nodes to deliver onload and onerror // notifications to. nsTArray<nsWeakPtr> mNodes; // History of redirects. nsTArray<RedirectRecord> mRedirectRecords; + // Usage timer, emits warning when the preload is not used in time. Started + // in NotifyOpen and stopped in NotifyUsage. + nsCOMPtr<nsITimer> mUsageTimer; + // The key this preload has been registered under. We want to remember it to // be able to deregister itself from the document's preloads. PreloadHashKey mKey; // This overrides the final event we send to DOM nodes to be always 'load'. // Modified in NotifyStart based on LoadInfo data of the loading channel. bool mShouldFireLoadEvent = false;