Changeset 251637 in webkit
- Timestamp:
- Oct 26, 2019 10:17:54 AM (4 years ago)
- Location:
- trunk
- Files:
-
- 26 added
- 21 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r251631 r251637 1 2019-10-26 Rob Buis <rbuis@igalia.com> 2 3 Main implementation for lazy image loading 4 https://bugs.webkit.org/show_bug.cgi?id=200764 5 6 Reviewed by Simon Fraser. 7 8 Import relevant tests into http/tests/lazyload. 9 Skip lazy image load tests for WK1 and windows, which 10 has IntersectionObserver turned off by default. 11 12 * TestExpectations: 13 * http/tests/lazyload/attribute-expected.txt: Added. 14 * http/tests/lazyload/attribute.html: Added. 15 * http/tests/lazyload/invisible-image-expected.txt: Added. 16 * http/tests/lazyload/invisible-image.html: Added. 17 * http/tests/lazyload/js-image-expected.txt: Added. 18 * http/tests/lazyload/js-image.html: Added. 19 * http/tests/lazyload/lazy-expected.txt: Added. 20 * http/tests/lazyload/lazy-image-load-in-iframes-scripting-disabled-expected.txt: Added. 21 * http/tests/lazyload/lazy-image-load-in-iframes-scripting-disabled.html: Added. 22 * http/tests/lazyload/lazy-image-load-in-iframes-scripting-enabled-expected.txt: Added. 23 * http/tests/lazyload/lazy-image-load-in-iframes-scripting-enabled.html: Added. 24 * http/tests/lazyload/lazy.html: Added. 25 * http/tests/lazyload/lazy2-expected.txt: Added. 26 * http/tests/lazyload/placeholder.js: Added. 27 (is_image_fully_loaded): 28 * http/tests/lazyload/resources/lazy-load-in-iframe.html: Added. 29 * http/tests/lazyload/scroll-element-moved-from-document-expected.txt: Added. 30 * http/tests/lazyload/scroll-element-moved-from-document.html: Added. 31 * http/tests/lazyload/scroll-element-removed-from-document-expected.txt: Added. 32 * http/tests/lazyload/scroll-element-removed-from-document.html: Added. 33 * http/tests/lazyload/scroll-expected.txt: Added. 34 * http/tests/lazyload/scroll.html: Added. 35 * platform/mac-wk1/TestExpectations: 36 * platform/win/TestExpectations: 37 1 38 2019-10-26 Yury Semikhatsky <yurys@chromium.org> 2 39 -
trunk/LayoutTests/TestExpectations
r251630 r251637 3855 3855 fast/text/design-system-ui-16.html [ ImageOnlyFailure ] 3856 3856 3857 webkit.org/b/196698 imported/w3c/web-platform-tests/loading/lazyload/image-loading-lazy.tentative.html3858 3857 webkit.org/b/196698 imported/w3c/web-platform-tests/loading/lazyload/iframe-loading-lazy.tentative.html 3859 3858 -
trunk/LayoutTests/imported/w3c/ChangeLog
r251635 r251637 1 2019-10-26 Rob Buis <rbuis@igalia.com> 2 3 Main implementation for lazy image loading 4 https://bugs.webkit.org/show_bug.cgi?id=200764 5 6 Reviewed by Simon Fraser. 7 8 Set correct test option. 9 10 * web-platform-tests/loading/lazyload/image-loading-lazy.tentative-expected.txt: Added. 11 * web-platform-tests/loading/lazyload/image-loading-lazy.tentative.html: 12 1 13 2019-10-26 Simon Fraser <simon.fraser@apple.com> 2 14 -
trunk/LayoutTests/imported/w3c/web-platform-tests/loading/lazyload/image-loading-lazy.tentative.html
r248404 r251637 1 <!DOCTYPE html> 1 <!DOCTYPE html><!-- webkit-test-runner [ experimental:enableLazyImageLoading=true ] --> 2 2 <head> 3 3 <title>Images with loading='lazy' load when in the viewport</title> -
trunk/LayoutTests/platform/mac-wk1/TestExpectations
r251597 r251637 152 152 imported/w3c/web-platform-tests/intersection-observer [ Skip ] 153 153 intersection-observer [ Skip ] 154 155 http/tests/lazyload [ Skip ] 156 imported/w3c/web-platform-tests/loading/lazyload [ Skip ] 154 157 155 158 # testRunner.queueLoad() does not support loading data URLs in Mac WK1 -
trunk/LayoutTests/platform/win/TestExpectations
r251628 r251637 4469 4469 4470 4470 webkit.org/b/202953 http/tests/websocket/tests/hybi/non-document-mixed-content-blocked-https-with-embedded-http-with-embedded-https.https.html [ Timeout ] 4471 4472 # IntersectionObserver is off by default 4473 http/tests/lazyload [ Skip ] 4474 imported/w3c/web-platform-tests/loading/lazyload [ Skip ] -
trunk/Source/WebCore/ChangeLog
r251636 r251637 1 2019-10-26 Rob Buis <rbuis@igalia.com> 2 3 Main implementation for lazy image loading 4 https://bugs.webkit.org/show_bug.cgi?id=200764 5 6 Reviewed by Simon Fraser. 7 8 Implement lazy image loading as specified here [1]. Lazy image loading 9 is controlled by the loading attribute on <img>. When the loading attribute is 10 auto or not specified, the behavior is like before this patch, i.e. loading is 11 eager. 12 13 Not all loading=lazy requests will turn into actual lazy image loads, when 14 scripting is turned off or images are not http(s), they will not be deferred. 15 16 This implementation relies on Intersection Observer and hence works on WK2 only. 17 18 Deferred images are painted using a simple outline until fully loaded. 19 20 [1] https://github.com/whatwg/html/pull/3752/files 21 22 Tests: http/tests/lazyload/attribute.html 23 http/tests/lazyload/invisible-image.html 24 http/tests/lazyload/js-image.html 25 http/tests/lazyload/lazy-image-load-in-iframes-scripting-disabled.html 26 http/tests/lazyload/lazy-image-load-in-iframes-scripting-enabled.html 27 http/tests/lazyload/lazy.html 28 http/tests/lazyload/scroll-element-moved-from-document.html 29 http/tests/lazyload/scroll-element-removed-from-document.html 30 http/tests/lazyload/scroll.html 31 32 * Sources.txt: 33 * WebCore.xcodeproj/project.pbxproj: 34 * dom/Document.cpp: 35 (WebCore::Document::lazyLoadImageObserver): 36 * dom/Document.h: 37 * html/HTMLImageElement.cpp: 38 (WebCore::HTMLImageElement::parseAttribute): 39 (WebCore::HTMLImageElement::loadDeferredImage): 40 (WebCore::HTMLImageElement::didMoveToNewDocument): 41 (WebCore::HTMLImageElement::loadingForBindings const): 42 (WebCore::HTMLImageElement::setLoadingForBindings): 43 (WebCore::HTMLImageElement::isDeferred const): 44 (WebCore::HTMLImageElement::isLazyLoadable const): 45 * html/HTMLImageElement.h: 46 * html/HTMLImageElement.idl: 47 * html/LazyLoadImageObserver.cpp: Added. 48 (WebCore::LazyLoadImageObserver::observe): 49 (WebCore::LazyLoadImageObserver::unobserve): 50 (WebCore::LazyLoadImageObserver::intersectionObserver): 51 (WebCore::LazyLoadImageObserver::isObserved const): 52 * html/LazyLoadImageObserver.h: Added. 53 * html/parser/HTMLPreloadScanner.cpp: 54 (WebCore::TokenPreloadScanner::StartTagScanner::createPreloadRequest): 55 (WebCore::TokenPreloadScanner::StartTagScanner::processAttribute): 56 * loader/ImageLoader.cpp: 57 (WebCore::ImageLoader::updateFromElement): 58 (WebCore::ImageLoader::notifyFinished): 59 (WebCore::ImageLoader::loadDeferredImage): 60 * loader/ImageLoader.h: 61 (WebCore::ImageLoader::isDeferred const): 62 * loader/cache/CachedImage.h: 63 * loader/cache/CachedResourceLoader.cpp: 64 (WebCore::CachedResourceLoader::requestImage): 65 (WebCore::CachedResourceLoader::requestResource): 66 (WebCore::CachedResourceLoader::determineRevalidationPolicy const): 67 (WebCore::CachedResourceLoader::clientDefersImage const): 68 (WebCore::CachedResourceLoader::shouldDeferImageLoad const): 69 (WebCore::CachedResourceLoader::reloadImagesIfNotDeferred): 70 * loader/cache/CachedResourceLoader.h: 71 * rendering/RenderImage.cpp: 72 (WebCore::isDeferredImage): 73 (WebCore::RenderImage::paintReplaced): 74 1 75 2019-10-26 Antti Koivisto <antti@apple.com> 2 76 -
trunk/Source/WebCore/Sources.txt
r251623 r251637 1222 1222 html/LabelableElement.cpp 1223 1223 html/LabelsNodeList.cpp 1224 html/LazyLoadImageObserver.cpp 1224 1225 html/LinkIconCollector.cpp 1225 1226 html/LinkRelAttribute.cpp -
trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj
r251623 r251637 3375 3375 AAA728F716D1D8BC00D3BBC6 /* WebAccessibilityObjectWrapperIOS.h in Headers */ = {isa = PBXBuildFile; fileRef = AAA728F116D1D8BC00D3BBC6 /* WebAccessibilityObjectWrapperIOS.h */; }; 3376 3376 AAC08CF315F941FD00F1E188 /* AccessibilitySVGRoot.h in Headers */ = {isa = PBXBuildFile; fileRef = AAC08CF115F941FC00F1E188 /* AccessibilitySVGRoot.h */; }; 3377 AAD9D0B521DFA810001B11C7 /* LazyLoadImageObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = AAD9D0B321DFA80E001B11C7 /* LazyLoadImageObserver.h */; settings = {ATTRIBUTES = (Private, ); }; }; 3377 3378 AB23A32809BBA7D00067CC53 /* BeforeTextInsertedEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = AB23A32609BBA7D00067CC53 /* BeforeTextInsertedEvent.h */; }; 3378 3379 AB247A6D0AFD6383003FA5FD /* RenderSlider.h in Headers */ = {isa = PBXBuildFile; fileRef = AB247A6B0AFD6383003FA5FD /* RenderSlider.h */; }; … … 9135 9136 697101071C6BE1550018C7F1 /* AccessibilitySVGElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AccessibilitySVGElement.cpp; sourceTree = "<group>"; }; 9136 9137 697101081C6BE1550018C7F1 /* AccessibilitySVGElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AccessibilitySVGElement.h; sourceTree = "<group>"; }; 9138 AAD9D0B121DFA80C001B11C7 /* LazyLoadImageObserver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LazyLoadImageObserver.cpp; sourceTree = "<group>"; }; 9139 AAD9D0B321DFA80E001B11C7 /* LazyLoadImageObserver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LazyLoadImageObserver.h; sourceTree = "<group>"; }; 9137 9140 6A22E86F1F10418600F546C3 /* InspectorCanvas.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = InspectorCanvas.h; sourceTree = "<group>"; }; 9138 9141 6A22E8721F1042C400F546C3 /* InspectorCanvas.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorCanvas.cpp; sourceTree = "<group>"; }; … … 21905 21908 A456FA2411AD4A830020B420 /* LabelsNodeList.cpp */, 21906 21909 A456FA2511AD4A830020B420 /* LabelsNodeList.h */, 21910 AAD9D0B121DFA80C001B11C7 /* LazyLoadImageObserver.cpp */, 21911 AAD9D0B321DFA80E001B11C7 /* LazyLoadImageObserver.h */, 21907 21912 1A4DA41F1CDD3A8300F4473C /* LinkIconCollector.cpp */, 21908 21913 1A4DA4201CDD3A8300F4473C /* LinkIconCollector.h */, … … 30999 31004 11310CF220BA4A320065A8D0 /* LayoutTreeBuilder.h in Headers */, 31000 31005 141DC0481648348F00371E5A /* LayoutUnit.h in Headers */, 31006 AAD9D0B521DFA810001B11C7 /* LazyLoadImageObserver.h in Headers */, 31001 31007 CDE8B5ED1A69777300B4B66A /* LegacyCDMPrivateClearKey.h in Headers */, 31002 31008 CDF4B7121E0087AE00E235A2 /* LegacyCDMSession.h in Headers */, -
trunk/Source/WebCore/dom/Document.cpp
r251605 r251637 120 120 #include "KeyframeEffect.h" 121 121 #include "LayoutDisallowedScope.h" 122 #include "LazyLoadImageObserver.h" 122 123 #include "LegacySchemeRegistry.h" 123 124 #include "LibWebRTCProvider.h" … … 8326 8327 } 8327 8328 8329 LazyLoadImageObserver& Document::lazyLoadImageObserver() 8330 { 8331 if (!m_lazyLoadImageObserver) 8332 m_lazyLoadImageObserver = makeUnique<LazyLoadImageObserver>(); 8333 return *m_lazyLoadImageObserver; 8334 } 8335 8328 8336 } // namespace WebCore -
trunk/Source/WebCore/dom/Document.h
r251605 r251637 154 154 class LayoutPoint; 155 155 class LayoutRect; 156 class LazyLoadImageObserver; 156 157 class LiveNodeList; 157 158 class Locale; … … 1557 1558 TextManipulationController* textManipulationControllerIfExists() { return m_textManipulationController.get(); } 1558 1559 1560 LazyLoadImageObserver& lazyLoadImageObserver(); 1561 1559 1562 protected: 1560 1563 enum ConstructionFlags { Synthesized = 1, NonRenderedPlaceholder = 1 << 1 }; … … 1742 1745 Element* m_cssTarget { nullptr }; 1743 1746 1747 std::unique_ptr<LazyLoadImageObserver> m_lazyLoadImageObserver; 1748 1744 1749 RefPtr<SerializedScriptValue> m_pendingStateObject; 1745 1750 MonotonicTime m_documentCreationTime; -
trunk/Source/WebCore/html/HTMLImageElement.cpp
r250576 r251637 44 44 #include "HTMLSourceElement.h" 45 45 #include "HTMLSrcsetParser.h" 46 #include "LazyLoadImageObserver.h" 46 47 #include "Logging.h" 47 48 #include "MIMETypeRegistry.h" … … 54 55 #include "RenderView.h" 55 56 #include "RuntimeEnabledFeatures.h" 57 #include "ScriptController.h" 56 58 #include "Settings.h" 57 59 #include "ShadowRoot.h" … … 245 247 } else if (name == x_apple_editable_imageAttr) 246 248 updateEditableImage(); 247 else { 249 else if (name == loadingAttr) { 250 if (!equalLettersIgnoringASCIICase(value, "lazy")) 251 loadDeferredImage(); 252 } else { 248 253 if (name == nameAttr) { 249 254 bool willHaveName = !value.isNull(); … … 262 267 HTMLElement::parseAttribute(name, value); 263 268 } 269 } 270 271 void HTMLImageElement::loadDeferredImage() 272 { 273 m_imageLoader->loadDeferredImage(); 264 274 } 265 275 … … 666 676 void HTMLImageElement::didMoveToNewDocument(Document& oldDocument, Document& newDocument) 667 677 { 678 m_createdByParser = false; 668 679 m_imageLoader->elementDidMoveToNewDocument(); 669 680 HTMLElement::didMoveToNewDocument(oldDocument, newDocument); … … 862 873 } 863 874 864 } 875 const AtomString& HTMLImageElement::loadingForBindings() const 876 { 877 static NeverDestroyed<AtomString> autoValue("auto", AtomString::ConstructFromLiteral); 878 static NeverDestroyed<AtomString> eager("eager", AtomString::ConstructFromLiteral); 879 static NeverDestroyed<AtomString> lazy("lazy", AtomString::ConstructFromLiteral); 880 auto attributeValue = attributeWithoutSynchronization(HTMLNames::loadingAttr); 881 if (equalLettersIgnoringASCIICase(attributeValue, "eager")) 882 return eager; 883 if (equalLettersIgnoringASCIICase(attributeValue, "lazy")) 884 return lazy; 885 return autoValue; 886 } 887 888 void HTMLImageElement::setLoadingForBindings(const AtomString& value) 889 { 890 setAttributeWithoutSynchronization(loadingAttr, value); 891 } 892 893 bool HTMLImageElement::isDeferred() const 894 { 895 return m_imageLoader->isDeferred(); 896 } 897 898 bool HTMLImageElement::isLazyLoadable() const 899 { 900 if (document().frame() && !document().frame()->script().canExecuteScripts(NotAboutToExecuteScript)) 901 return false; 902 // Never do lazy loading for image elements created from JavaScript. 903 return createdByParser() && equalLettersIgnoringASCIICase(attributeWithoutSynchronization(HTMLNames::loadingAttr), "lazy"); 904 } 905 906 } -
trunk/Source/WebCore/html/HTMLImageElement.h
r250576 r251637 127 127 void defaultEventHandler(Event&) final; 128 128 129 void loadDeferredImage(); 130 129 131 bool createdByParser() const { return m_createdByParser; } 132 133 const AtomString& loadingForBindings() const; 134 void setLoadingForBindings(const AtomString&); 135 136 bool isLazyLoadable() const; 137 138 bool isDeferred() const; 130 139 131 140 bool isDroppedImagePlaceholder() const { return m_isDroppedImagePlaceholder; } -
trunk/Source/WebCore/html/HTMLImageElement.idl
r248409 r251637 45 45 [Conditional=ATTACHMENT_ELEMENT, EnabledAtRuntime=AttachmentElement] readonly attribute DOMString attachmentIdentifier; 46 46 47 [ EnabledAtRuntime=LazyImageLoading, CEReactions, Reflect] attribute DOMString loading;47 [CEReactions, EnabledAtRuntime=LazyImageLoading, ImplementedAs=loadingForBindings] attribute DOMString loading; 48 48 49 49 // Extensions -
trunk/Source/WebCore/html/parser/HTMLPreloadScanner.cpp
r248846 r251637 162 162 return nullptr; 163 163 164 // Do not preload if lazyload is possible but metadata fetch is disabled. 165 if (equalLettersIgnoringASCIICase(m_lazyloadAttribute, "lazy")) 166 return nullptr; 167 164 168 auto request = makeUnique<PreloadRequest>(initiatorFor(m_tagId), m_urlToLoad, predictedBaseURL, type.value(), m_mediaAttribute, m_moduleScript, m_referrerPolicy); 165 169 request->setCrossOriginMode(m_crossOriginMode); … … 206 210 m_sizesAttribute = attributeValue; 207 211 break; 212 } 213 if (RuntimeEnabledFeatures::sharedFeatures().lazyImageLoadingEnabled()) { 214 if (match(attributeName, loadingAttr) && m_lazyloadAttribute.isNull()) { 215 m_lazyloadAttribute = attributeValue; 216 break; 217 } 208 218 } 209 219 processImageAndScriptAttribute(attributeName, attributeValue); … … 371 381 String m_asAttribute; 372 382 String m_typeAttribute; 383 String m_lazyloadAttribute; 373 384 bool m_metaIsViewport; 374 385 bool m_metaIsDisabledAdaptations; -
trunk/Source/WebCore/loader/ImageLoader.cpp
r250735 r251637 40 40 #include "InspectorInstrumentation.h" 41 41 #include "JSDOMPromiseDeferred.h" 42 #include "LazyLoadImageObserver.h" 42 43 #include "Page.h" 43 44 #include "RenderImage.h" 44 45 #include "RenderSVGImage.h" 46 #include "RuntimeEnabledFeatures.h" 45 47 #include <wtf/NeverDestroyed.h> 46 48 … … 198 200 document.cachedResourceLoader().m_documentResources.set(newImage->url(), newImage.get()); 199 201 document.cachedResourceLoader().setAutoLoadImages(autoLoadOtherImages); 200 } else 201 newImage = document.cachedResourceLoader().requestImage(WTFMove(request)).value_or(nullptr); 202 } else { 203 if (m_lazyImageLoadState == LazyImageLoadState::None) { 204 if (is<HTMLImageElement>(element())) { 205 auto& imageElement = downcast<HTMLImageElement>(element()); 206 if (imageElement.isLazyLoadable() && RuntimeEnabledFeatures::sharedFeatures().lazyImageLoadingEnabled()) 207 m_lazyImageLoadState = LazyImageLoadState::Deferred; 208 } 209 } 210 newImage = document.cachedResourceLoader().requestImage(WTFMove(request), (m_lazyImageLoadState == LazyImageLoadState::Deferred) ? ImageLoading::DeferredUntilVisible : ImageLoading::Immediate).value_or(nullptr); 211 } 202 212 203 213 // If we do not have an image here, it means that a cross-site … … 252 262 updateRenderer(); 253 263 264 if (m_lazyImageLoadState == LazyImageLoadState::Deferred) 265 LazyLoadImageObserver::observe(element()); 266 254 267 // If newImage is cached, addClient() will result in the load event 255 268 // being queued to fire. Ensure this happens after beforeload is … … 307 320 ASSERT(m_failedLoadURL.isEmpty()); 308 321 ASSERT_UNUSED(resource, &resource == m_image.get()); 322 323 if (m_lazyImageLoadState == LazyImageLoadState::Deferred) { 324 LazyLoadImageObserver::unobserve(element()); 325 m_lazyImageLoadState = LazyImageLoadState::FullImage; 326 } 309 327 310 328 m_imageComplete = true; … … 561 579 } 562 580 563 } 581 void ImageLoader::loadDeferredImage() 582 { 583 if (m_lazyImageLoadState != LazyImageLoadState::Deferred) 584 return; 585 m_lazyImageLoadState = LazyImageLoadState::FullImage; 586 updateFromElement(); 587 } 588 589 } -
trunk/Source/WebCore/loader/ImageLoader.h
r250735 r251637 76 76 static void dispatchPendingErrorEvents(); 77 77 78 void loadDeferredImage(); 79 80 bool isDeferred() const { return m_lazyImageLoadState == LazyImageLoadState::Deferred; } 81 78 82 protected: 79 83 explicit ImageLoader(Element&); … … 81 85 82 86 private: 87 enum class LazyImageLoadState { None, Deferred, FullImage }; 88 83 89 virtual void dispatchLoadEvent() = 0; 84 90 virtual String sourceURI(const AtomString&) const = 0; … … 115 121 bool m_loadManually : 1; 116 122 bool m_elementIsProtected : 1; 123 LazyImageLoadState m_lazyImageLoadState { LazyImageLoadState::None }; 117 124 }; 118 125 -
trunk/Source/WebCore/loader/cache/CachedImage.h
r248438 r251637 92 92 93 93 void setForceUpdateImageDataEnabledForTesting(bool enabled) { m_forceUpdateImageDataEnabledForTesting = enabled; } 94 94 95 bool stillNeedsLoad() const override { return !errorOccurred() && status() == Unknown && !isLoading(); } 96 95 97 private: 96 98 void clear(); … … 128 130 // For compatibility, images keep loading even if there are HTTP errors. 129 131 bool shouldIgnoreHTTPStatusCodeErrors() const override { return true; } 130 131 bool stillNeedsLoad() const override { return !errorOccurred() && status() == Unknown && !isLoading(); }132 132 133 133 class CachedImageObserver final : public RefCounted<CachedImageObserver>, public ImageObserver { -
trunk/Source/WebCore/loader/cache/CachedResourceLoader.cpp
r251594 r251637 208 208 } 209 209 210 ResourceErrorOr<CachedResourceHandle<CachedImage>> CachedResourceLoader::requestImage(CachedResourceRequest&& request )210 ResourceErrorOr<CachedResourceHandle<CachedImage>> CachedResourceLoader::requestImage(CachedResourceRequest&& request, ImageLoading imageLoading) 211 211 { 212 212 if (Frame* frame = this->frame()) { … … 221 221 } 222 222 223 auto defer = clientDefersImage(request.resourceRequest().url()) ? DeferOption::DeferredByClient : DeferOption::NoDefer; 224 return castCachedResourceTo<CachedImage>(requestResource(CachedResource::Type::ImageResource, WTFMove(request), ForPreload::No, defer)); 223 if (imageLoading == ImageLoading::Immediate) 224 imageLoading = clientDefersImage(request.resourceRequest().url()); 225 return castCachedResourceTo<CachedImage>(requestResource(CachedResource::Type::ImageResource, WTFMove(request), ForPreload::No, imageLoading)); 225 226 } 226 227 … … 825 826 #endif 826 827 827 ResourceErrorOr<CachedResourceHandle<CachedResource>> CachedResourceLoader::requestResource(CachedResource::Type type, CachedResourceRequest&& request, ForPreload forPreload, DeferOption defer)828 ResourceErrorOr<CachedResourceHandle<CachedResource>> CachedResourceLoader::requestResource(CachedResource::Type type, CachedResourceRequest&& request, ForPreload forPreload, ImageLoading imageLoading) 828 829 { 829 830 if (!frame() || !frame()->page()) { … … 949 950 auto& cookieJar = page.cookieJar(); 950 951 951 RevalidationPolicy policy = determineRevalidationPolicy(type, request, resource.get(), forPreload, defer);952 RevalidationPolicy policy = determineRevalidationPolicy(type, request, resource.get(), forPreload, imageLoading); 952 953 switch (policy) { 953 954 case Reload: … … 1011 1012 } 1012 1013 1013 if ((policy != Use || resource->stillNeedsLoad()) && defer == DeferOption::NoDefer) {1014 if ((policy != Use || resource->stillNeedsLoad()) && imageLoading == ImageLoading::Immediate) { 1014 1015 resource->load(*this); 1015 1016 … … 1120 1121 } 1121 1122 1122 CachedResourceLoader::RevalidationPolicy CachedResourceLoader::determineRevalidationPolicy(CachedResource::Type type, CachedResourceRequest& cachedResourceRequest, CachedResource* existingResource, ForPreload forPreload, DeferOption defer) const1123 CachedResourceLoader::RevalidationPolicy CachedResourceLoader::determineRevalidationPolicy(CachedResource::Type type, CachedResourceRequest& cachedResourceRequest, CachedResource* existingResource, ForPreload forPreload, ImageLoading imageLoading) const 1123 1124 { 1124 1125 auto& request = cachedResourceRequest.resourceRequest(); … … 1176 1177 1177 1178 // Do not load from cache if images are not enabled. The load for this image will be blocked in CachedImage::load. 1178 if ( defer == DeferOption::DeferredByClient)1179 if (imageLoading == ImageLoading::DeferredUntilVisible) 1179 1180 return Reload; 1180 1181 … … 1321 1322 } 1322 1323 1323 boolCachedResourceLoader::clientDefersImage(const URL&) const1324 { 1325 return !m_imagesEnabled;1324 ImageLoading CachedResourceLoader::clientDefersImage(const URL&) const 1325 { 1326 return m_imagesEnabled ? ImageLoading::Immediate : ImageLoading::DeferredUntilVisible; 1326 1327 } 1327 1328 … … 1333 1334 bool CachedResourceLoader::shouldDeferImageLoad(const URL& url) const 1334 1335 { 1335 return clientDefersImage(url) || !shouldPerformImageLoad(url);1336 return clientDefersImage(url) == ImageLoading::DeferredUntilVisible || !shouldPerformImageLoad(url); 1336 1337 } 1337 1338 … … 1339 1340 { 1340 1341 for (auto& resource : m_documentResources.values()) { 1341 if (is<CachedImage>(*resource) && resource->stillNeedsLoad() && !clientDefersImage(resource->url()))1342 if (is<CachedImage>(*resource) && resource->stillNeedsLoad() && clientDefersImage(resource->url()) == ImageLoading::Immediate) 1342 1343 downcast<CachedImage>(*resource).load(*this); 1343 1344 } -
trunk/Source/WebCore/loader/cache/CachedResourceLoader.h
r250528 r251637 63 63 using ResourceErrorOr = Expected<T, ResourceError>; 64 64 65 enum class ImageLoading : uint8_t { Immediate, DeferredUntilVisible }; 66 65 67 // The CachedResourceLoader provides a per-context interface to the MemoryCache 66 68 // and enforces a bunch of security checks and rules for resource revalidation. … … 80 82 ~CachedResourceLoader(); 81 83 82 ResourceErrorOr<CachedResourceHandle<CachedImage>> requestImage(CachedResourceRequest&& );84 ResourceErrorOr<CachedResourceHandle<CachedImage>> requestImage(CachedResourceRequest&&, ImageLoading = ImageLoading::Immediate); 83 85 ResourceErrorOr<CachedResourceHandle<CachedCSSStyleSheet>> requestCSSStyleSheet(CachedResourceRequest&&); 84 86 CachedResourceHandle<CachedCSSStyleSheet> requestUserCSSStyleSheet(Page&, CachedResourceRequest&&); … … 164 166 165 167 enum class ForPreload { Yes, No }; 166 enum class DeferOption { NoDefer, DeferredByClient }; 167 168 ResourceErrorOr<CachedResourceHandle<CachedResource>> requestResource(CachedResource::Type, CachedResourceRequest&&, ForPreload = ForPreload::No, DeferOption = DeferOption::NoDefer); 168 169 ResourceErrorOr<CachedResourceHandle<CachedResource>> requestResource(CachedResource::Type, CachedResourceRequest&&, ForPreload = ForPreload::No, ImageLoading = ImageLoading::Immediate); 169 170 CachedResourceHandle<CachedResource> revalidateResource(CachedResourceRequest&&, CachedResource&); 170 171 CachedResourceHandle<CachedResource> loadResource(CachedResource::Type, PAL::SessionID, CachedResourceRequest&&, const CookieJar&); … … 176 177 177 178 enum RevalidationPolicy { Use, Revalidate, Reload, Load }; 178 RevalidationPolicy determineRevalidationPolicy(CachedResource::Type, CachedResourceRequest&, CachedResource* existingResource, ForPreload, DeferOption) const;179 RevalidationPolicy determineRevalidationPolicy(CachedResource::Type, CachedResourceRequest&, CachedResource* existingResource, ForPreload, ImageLoading) const; 179 180 180 181 bool shouldUpdateCachedResourceWithCurrentRequest(const CachedResource&, const CachedResourceRequest&); … … 186 187 void performPostLoadActions(); 187 188 188 boolclientDefersImage(const URL&) const;189 ImageLoading clientDefersImage(const URL&) const; 189 190 void reloadImagesIfNotDeferred(); 190 191 -
trunk/Source/WebCore/rendering/RenderImage.cpp
r250238 r251637 424 424 } 425 425 426 static bool isDeferredImage(Element* element) 427 { 428 return is<HTMLImageElement>(element) && downcast<HTMLImageElement>(element)->isDeferred(); 429 } 430 426 431 void RenderImage::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paintOffset) 427 432 { … … 437 442 LayoutUnit missingImageBorderWidth(1 / deviceScaleFactor); 438 443 439 if (!imageResource().cachedImage() || shouldDisplayBrokenImageIcon()) {444 if (!imageResource().cachedImage() || isDeferredImage(element()) || shouldDisplayBrokenImageIcon()) { 440 445 if (paintInfo.phase == PaintPhase::Selection) 441 446 return;
Note: See TracChangeset
for help on using the changeset viewer.