⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 268192 in webkit


Ignore:
Timestamp:
Oct 8, 2020, 10:59:50 AM (6 years ago)
Author:
sihui_liu@apple.com
Message:

Adjust heuristic for checking whether view reaches visually non-empty state
https://bugs.webkit.org/show_bug.cgi?id=217400

Reviewed by Geoffrey Garen.

Source/WebCore:

We decide that view reaches visually non-empty state and fire corresponding events when main document is parsed
and no more content (font or css resources) is to be loaded. An edge case is when the page has an empty document
and depends on async scripts to fill content (like wpt.fyi), then we may fire the events too early. To mitigate
this issue, now we don't set the state if content is completely empty and there are scripts to be loaded. Also,
because lazily loading elements need rendering update to decide if they can be loaded, we should not wait for
scripts where there are such elements.

API Test: WebKit.FirstVisuallyNonEmptyMilestoneWithDeferredScriptInEmptyDocument

  • page/FrameView.cpp:

(WebCore::FrameView::checkAndDispatchDidReachVisuallyNonEmptyState):

Tools:

  • TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
  • TestWebKitAPI/Tests/WebKit/deferred-script-load-in-empty-document.html: Added.
  • TestWebKitAPI/Tests/WebKitCocoa/FirstVisuallyNonEmptyMilestone.mm:

(-[RenderingProgressNavigationDelegate _webView:renderingProgressDidChange:]):
(TEST):

Location:
trunk
Files:
1 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r268187 r268192  
     12020-10-08  Sihui Liu  <sihui_liu@apple.com>
     2
     3        Adjust heuristic for checking whether view reaches visually non-empty state
     4        https://bugs.webkit.org/show_bug.cgi?id=217400
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        We decide that view reaches visually non-empty state and fire corresponding events when main document is parsed
     9        and no more content (font or css resources) is to be loaded. An edge case is when the page has an empty document
     10        and depends on async scripts to fill content (like wpt.fyi), then we may fire the events too early. To mitigate
     11        this issue, now we don't set the state if content is completely empty and there are scripts to be loaded. Also,
     12        because lazily loading elements need rendering update to decide if they can be loaded, we should not wait for
     13        scripts where there are such elements.
     14
     15        API Test: WebKit.FirstVisuallyNonEmptyMilestoneWithDeferredScriptInEmptyDocument
     16
     17        * page/FrameView.cpp:
     18        (WebCore::FrameView::checkAndDispatchDidReachVisuallyNonEmptyState):
     19
    1202020-10-08  Tuomas Karkkainen  <tuomas.webkit@apple.com>
    221
  • trunk/Source/WebCore/page/FrameView.cpp

    r268075 r268192  
    45784578
    45794579            auto& resources = resourceLoader.allCachedResources();
     4580            bool shouldWaitForScriptIfEmpty = false;
     4581#if ENABLE(INTERSECTION_OBSERVER)
     4582            shouldWaitForScriptIfEmpty = !document.numberOfIntersectionObservers();
     4583#endif
     4584            bool isLoadingScript = false;
    45804585            for (auto& resource : resources) {
    45814586                if (resource.value->isLoaded())
    45824587                    continue;
    4583                 if (resource.value->type() == CachedResource::Type::CSSStyleSheet || resource.value->type() == CachedResource::Type::FontResource)
     4588                auto type = resource.value->type();
     4589                if (type == CachedResource::Type::CSSStyleSheet || type == CachedResource::Type::FontResource)
    45844590                    return true;
     4591                if (type == CachedResource::Type::Script)
     4592                    isLoadingScript = true;
    45854593            }
     4594
     4595            if (shouldWaitForScriptIfEmpty && !m_visuallyNonEmptyPixelCount && isLoadingScript)
     4596                return true;
     4597
    45864598            return false;
    45874599        };
  • trunk/Tools/ChangeLog

    r268169 r268192  
     12020-10-08  Sihui Liu  <sihui_liu@apple.com>
     2
     3        Adjust heuristic for checking whether view reaches visually non-empty state
     4        https://bugs.webkit.org/show_bug.cgi?id=217400
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
     9        * TestWebKitAPI/Tests/WebKit/deferred-script-load-in-empty-document.html: Added.
     10        * TestWebKitAPI/Tests/WebKitCocoa/FirstVisuallyNonEmptyMilestone.mm:
     11        (-[RenderingProgressNavigationDelegate _webView:renderingProgressDidChange:]):
     12        (TEST):
     13
    1142020-10-07  Aditya Keerthi  <akeerthi@apple.com>
    215
  • trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj

    r268123 r268192  
    796796                932AE53D1D371047005DFFAF /* focus-inputs.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 93575C551D30366E000D604D /* focus-inputs.html */; };
    797797                933D631D1FCB76200032ECD6 /* Hasher.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 933D631B1FCB76180032ECD6 /* Hasher.cpp */; };
     798                93494FFE252E66BA0099F171 /* deferred-script-load-in-empty-document.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 93494FFD252E65440099F171 /* deferred-script-load-in-empty-document.html */; };
    798799                935786CC20F6A2700000CDFC /* IndexedDB.sqlite3-wal in Copy Resources */ = {isa = PBXBuildFile; fileRef = 934FA5C520F69FED0040DC1B /* IndexedDB.sqlite3-wal */; };
    799800                935786CD20F6A2910000CDFC /* IndexedDB.sqlite3 in Copy Resources */ = {isa = PBXBuildFile; fileRef = 934FA5C720F69FEE0040DC1B /* IndexedDB.sqlite3 */; };
     
    13591360                                F457A9D6202D68AF00F7E9D5 /* DataTransfer.html in Copy Resources */,
    13601361                                F4512E131F60C44600BB369E /* DataTransferItem-getAsEntry.html in Copy Resources */,
     1362                                93494FFE252E66BA0099F171 /* deferred-script-load-in-empty-document.html in Copy Resources */,
    13611363                                118153442208B7AC00B2CCD2 /* deferred-script-load.html in Copy Resources */,
    13621364                                118153462208B7E500B2CCD2 /* deferred-script.js in Copy Resources */,
     
    23862388                9331407B17B4419000F083B1 /* DidNotHandleKeyDown.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DidNotHandleKeyDown.cpp; sourceTree = "<group>"; };
    23872389                933D631B1FCB76180032ECD6 /* Hasher.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Hasher.cpp; sourceTree = "<group>"; };
     2390                93494FFD252E65440099F171 /* deferred-script-load-in-empty-document.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "deferred-script-load-in-empty-document.html"; sourceTree = "<group>"; };
    23882391                934FA5C520F69FED0040DC1B /* IndexedDB.sqlite3-wal */ = {isa = PBXFileReference; lastKnownFileType = file; path = "IndexedDB.sqlite3-wal"; sourceTree = "<group>"; };
    23892392                934FA5C620F69FED0040DC1B /* IndexedDB.sqlite3-shm */ = {isa = PBXFileReference; lastKnownFileType = file; path = "IndexedDB.sqlite3-shm"; sourceTree = "<group>"; };
     
    42774280                                5C9E56861DF9148E00C9EE33 /* contentBlockerCheck.html */,
    42784281                                290F4274172A1FDE00939FF0 /* custom-protocol-sync-xhr.html */,
     4282                                93494FFD252E65440099F171 /* deferred-script-load-in-empty-document.html */,
    42794283                                118153432208B7AC00B2CCD2 /* deferred-script-load.html */,
    42804284                                118153452208B7E500B2CCD2 /* deferred-script.js */,
  • trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/FirstVisuallyNonEmptyMilestone.mm

    r260366 r268192  
    3838static bool didFirstVisuallyNonEmptyLayout;
    3939static bool receivedMessage;
     40static bool receivedMessageBeforeFirstVisuallyNonEmptyLayout;
    4041
    4142@interface FirstPaintMessageHandler : NSObject <WKScriptMessageHandler>
     
    5556- (void)_webView:(WKWebView *)webView renderingProgressDidChange:(_WKRenderingProgressEvents)progressEvents
    5657{
    57     if (progressEvents & _WKRenderingProgressEventFirstVisuallyNonEmptyLayout)
     58    if (progressEvents & _WKRenderingProgressEventFirstVisuallyNonEmptyLayout) {
     59        receivedMessageBeforeFirstVisuallyNonEmptyLayout = receivedMessage;
    5860        didFirstVisuallyNonEmptyLayout = true;
     61    }
    5962}
    6063@end
     
    7275
    7376    receivedMessage = false;
     77    receivedMessageBeforeFirstVisuallyNonEmptyLayout = false;
    7478    didFirstVisuallyNonEmptyLayout = false;
    7579
     
    7882    TestWebKitAPI::Util::run(&receivedMessage);
    7983    EXPECT_TRUE(didFirstVisuallyNonEmptyLayout);
     84    EXPECT_FALSE(receivedMessageBeforeFirstVisuallyNonEmptyLayout);
     85}
     86
     87TEST(WebKit, FirstVisuallyNonEmptyMilestoneWithDeferredScriptInEmptyDocument)
     88{
     89    auto webViewConfiguration = adoptNS([[WKWebViewConfiguration alloc] init]);
     90    auto messageHandler = adoptNS([[FirstPaintMessageHandler alloc] init]);
     91    [[webViewConfiguration userContentController] addScriptMessageHandler:messageHandler.get() name:@"firstpaint"];
     92
     93    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:webViewConfiguration.get()]);
     94
     95    RetainPtr<RenderingProgressNavigationDelegate> delegate = adoptNS([[RenderingProgressNavigationDelegate alloc] init]);
     96    [webView setNavigationDelegate:delegate.get()];
     97
     98    receivedMessage = false;
     99    receivedMessageBeforeFirstVisuallyNonEmptyLayout = false;
     100    didFirstVisuallyNonEmptyLayout = false;
     101
     102    [webView loadRequest:[NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"deferred-script-load-in-empty-document" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]]];
     103
     104    TestWebKitAPI::Util::run(&didFirstVisuallyNonEmptyLayout);
     105    EXPECT_TRUE(receivedMessage);
     106    EXPECT_TRUE(receivedMessageBeforeFirstVisuallyNonEmptyLayout);
    80107}
    81108
Note: See TracChangeset for help on using the changeset viewer.