Bug 233266 - ImageAnalysisQueue should analyze image elements that are loaded after the call to enqueueAllImages()
Summary: ImageAnalysisQueue should analyze image elements that are loaded after the ca...
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Platform (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Wenson Hsieh
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2021-11-17 11:29 PST by Wenson Hsieh
Modified: 2022-01-17 12:18 PST (History)
7 users (show)

See Also:


Attachments
For EWS (17.99 KB, patch)
2022-01-16 15:32 PST, Wenson Hsieh
no flags Details | Formatted Diff | Diff
For EWS (17.97 KB, patch)
2022-01-16 22:09 PST, Wenson Hsieh
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Wenson Hsieh 2021-11-17 11:29:34 PST
.
Comment 1 Radar WebKit Bug Importer 2021-11-24 11:30:26 PST
<rdar://problem/85731875>
Comment 2 Wenson Hsieh 2022-01-16 15:32:14 PST
Created attachment 449292 [details]
For EWS
Comment 3 Darin Adler 2022-01-16 17:01:05 PST
Comment on attachment 449292 [details]
For EWS

View in context: https://bugs.webkit.org/attachment.cgi?id=449292&action=review

> Source/WebCore/page/ImageAnalysisQueue.cpp:68
> +    auto& renderImage = downcast<RenderImage>(*element.renderer());

I would just call this local variable "renderer". Yes the type is RenderImage, but that doesn’t need to be the name as well.

> Source/WebCore/page/ImageAnalysisQueue.cpp:99
> +    auto imageIterator = document.images()->createIterator();
> +    for (RefPtr node = imageIterator.next(); node; node = imageIterator.next()) {
> +        if (auto* element = dynamicDowncast<HTMLElement>(*node))
> +            enqueueIfNeeded(*element);
> +    }

It’s a mistake to use Document::images here. An HTMLCollection is designed as an API for use from JavaScript and offers no significant advantages over descendantsOfType<HTMLImageElement> for use in C++ code.

    for (auto& image : descendantsOfType<HTMLImageElement>(document))
        enqueueIfNeeded(image);

Using Document::images will just waste memory and time allocating objects to fulfill the abstraction needed to work with the JavaScript code.

Note also that the m_page check, the isConnected check, and document check in ImageAnalysisQueue::enqueueIfNeeded are all unnecessary here. But harmless I suppose.

> Source/WebCore/page/ImageAnalysisQueue.h:51
> +    void enqueueIfNeeded(HTMLElement&);

This can use HTMLImageElement.

> Source/WebCore/page/ImageAnalysisQueue.h:61
> +    WeakHashSet<HTMLElement> m_queuedElements;
> +    Deque<WeakPtr<HTMLElement>> m_queue;

These can use HTMLImageElement.
Comment 4 Wenson Hsieh 2022-01-16 21:11:13 PST
Comment on attachment 449292 [details]
For EWS

View in context: https://bugs.webkit.org/attachment.cgi?id=449292&action=review

Thanks for the review!

>> Source/WebCore/page/ImageAnalysisQueue.cpp:68
>> +    auto& renderImage = downcast<RenderImage>(*element.renderer());
> 
> I would just call this local variable "renderer". Yes the type is RenderImage, but that doesn’t need to be the name as well.

Renamed to `renderer`.

>> Source/WebCore/page/ImageAnalysisQueue.cpp:99
>> +    }
> 
> It’s a mistake to use Document::images here. An HTMLCollection is designed as an API for use from JavaScript and offers no significant advantages over descendantsOfType<HTMLImageElement> for use in C++ code.
> 
>     for (auto& image : descendantsOfType<HTMLImageElement>(document))
>         enqueueIfNeeded(image);
> 
> Using Document::images will just waste memory and time allocating objects to fulfill the abstraction needed to work with the JavaScript code.
> 
> Note also that the m_page check, the isConnected check, and document check in ImageAnalysisQueue::enqueueIfNeeded are all unnecessary here. But harmless I suppose.

Good point — changed this to just use `descendantsOfType<>`!

Also removed the unnecessary early returns.

>> Source/WebCore/page/ImageAnalysisQueue.h:51
>> +    void enqueueIfNeeded(HTMLElement&);
> 
> This can use HTMLImageElement.

Changed to HTMLImageElement.

>> Source/WebCore/page/ImageAnalysisQueue.h:61
>> +    Deque<WeakPtr<HTMLElement>> m_queue;
> 
> These can use HTMLImageElement.

Changed these to <HTMLImageElement> as well.
Comment 5 Wenson Hsieh 2022-01-16 22:09:05 PST
Created attachment 449305 [details]
For EWS
Comment 6 Darin Adler 2022-01-17 09:58:57 PST
Comment on attachment 449305 [details]
For EWS

View in context: https://bugs.webkit.org/attachment.cgi?id=449305&action=review

> Source/WebCore/page/ImageAnalysisQueue.h:60
> +    WeakHashSet<HTMLImageElement> m_queuedElements;
> +    Deque<WeakPtr<HTMLImageElement>> m_queue;

One other thought. The reason that ListHashSet exists is for use cases like this one where we want an ordered collection without duplicates. While it doesn’t have "deque" in its name, it does have an efficient takeFirst operation, and and new items are added at the end, so it’s much like a deque combined with a set.

I don’t know, though, how well it works with WeakPtr. But it would be nicer to use that combined data structure rather than building it out of the two pieces manually as we do here.
Comment 7 Wenson Hsieh 2022-01-17 10:01:11 PST
(In reply to Darin Adler from comment #6)
> Comment on attachment 449305 [details]
> For EWS
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=449305&action=review
> 
> > Source/WebCore/page/ImageAnalysisQueue.h:60
> > +    WeakHashSet<HTMLImageElement> m_queuedElements;
> > +    Deque<WeakPtr<HTMLImageElement>> m_queue;
> 
> One other thought. The reason that ListHashSet exists is for use cases like
> this one where we want an ordered collection without duplicates. While it
> doesn’t have "deque" in its name, it does have an efficient takeFirst
> operation, and and new items are added at the end, so it’s much like a deque
> combined with a set.
> 
> I don’t know, though, how well it works with WeakPtr. But it would be nicer
> to use that combined data structure rather than building it out of the two
> pieces manually as we do here.

In this case, elements are removed from `m_queue` when they're analyzed, but not removed from `m_queuedElements`, since want to avoid repeatedly re-analyzing elements.
Comment 8 EWS 2022-01-17 12:18:28 PST
Committed r288102 (246116@main): <https://commits.webkit.org/246116@main>

All reviewed patches have been landed. Closing bug and clearing flags on attachment 449305 [details].