Closed
Bug 1312770
Opened 8 years ago
Closed 8 years ago
Set image load priorities according to their position in viewport
Categories
(Core :: Layout: Images, Video, and HTML Frames, defect, P1)
Core
Layout: Images, Video, and HTML Frames
Tracking
()
RESOLVED
FIXED
mozilla55
People
(Reporter: mayhemer, Assigned: schien)
References
(Blocks 1 open bug)
Details
Attachments
(1 file, 9 obsolete files)
(deleted),
patch
|
schien
:
review+
|
Details | Diff | Splinter Review |
We want to set correct priorities to image loads according their position on the screen (in the view port) during initial page rendering. There already is an api (nsISupportsPriority) for this, but the information is not set on the image load channels by layout.
Images that don't have size (width) set by markup should be raised priority to lower the number of reflows.
Stage 2 of this effort should be to react to scrolling, if that can even be separated to make the first implementation simpler. Noting here to keep it in mind.
Reporter | ||
Comment 1•8 years ago
|
||
SC, you mentioned you know or have touched imagelib and layout in the past. Could you take this one?
Assignee: nobody → schien
Assignee | ||
Comment 2•8 years ago
|
||
The size information can be either specified in <img> or CSS. https://dxr.mozilla.org/mozilla-central/source/layout/generic/nsImageFrame.cpp#287 should be a good place to look up size information and adjust the priority.
Assignee | ||
Comment 3•8 years ago
|
||
Here are the reflow we want to avoid:
https://dxr.mozilla.org/mozilla-central/rev/783356f1476eafd8e4d6fa5f3919cf6167e84f8d/layout/generic/nsImageFrame.cpp#581
https://dxr.mozilla.org/mozilla-central/rev/783356f1476eafd8e4d6fa5f3919cf6167e84f8d/layout/generic/nsImageFrame.cpp#693
The performance measurement can be done easily by repetitively loading our target test pages and counting the number of reflows triggered by these two places.
Assignee | ||
Comment 4•8 years ago
|
||
Here is the code to detect that image is in viewport but the image data is not ready.
https://dxr.mozilla.org/mozilla-central/rev/47e0584afe0ab0b867412189c610b302b6ba0ea7/layout/generic/nsImageFrame.cpp#1765
Assignee | ||
Comment 5•8 years ago
|
||
I noticed that imagelib doesn't notify size update to layout after image header decode completed, layout only get the size information after entire image decode completed.
@tnikkel do you think updating the original size of the image to layout as early as possible can reduce the total number of reflow?
Flags: needinfo?(tnikkel)
Comment 6•8 years ago
|
||
(In reply to Shih-Chiang Chien [:schien] (UTC+8) (use ni? plz) from comment #5)
> I noticed that imagelib doesn't notify size update to layout after image
> header decode completed, layout only get the size information after entire
> image decode completed.
That shouldn't be true. We do a metadata-only decode (to get the size mainly) before a full decode of the image. The full decode and the metadata decode happen off-the-main thread, so they could both easily complete before the main thread has a chance to accept the results and send notifications. Try testing with a large image that takes a significant amount of time to decode?
Flags: needinfo?(tnikkel)
Assignee | ||
Comment 7•8 years ago
|
||
(In reply to Timothy Nikkel (:tnikkel) from comment #6)
> (In reply to Shih-Chiang Chien [:schien] (UTC+8) (use ni? plz) from comment
> #5)
> > I noticed that imagelib doesn't notify size update to layout after image
> > header decode completed, layout only get the size information after entire
> > image decode completed.
>
> That shouldn't be true. We do a metadata-only decode (to get the size
> mainly) before a full decode of the image. The full decode and the metadata
> decode happen off-the-main thread, so they could both easily complete before
> the main thread has a chance to accept the results and send notifications.
> Try testing with a large image that takes a significant amount of time to
> decode?
Thanks for the correction. I misunderstood how our metadata decoding works.
Metadata decode is fired at RasterImage::Init, which is triggered by the first available HTTP data received. Layout will be notified via nsImageFrame::Notify, which is the same callback function as full image decode.
Assignee | ||
Comment 8•8 years ago
|
||
Here is the place we know the size of the real image is important to layout
https://dxr.mozilla.org/mozilla-central/rev/79feeed4293336089590320a9f30a813fade8e3c/layout/generic/nsImageFrame.cpp#794
We can slightly turn up the priority of those image not too much, because we still want to load JS and CSS file at this very beginning stage.
Assignee | ||
Comment 9•8 years ago
|
||
Here is the place we know image is in viewport and ready to be rendered:
https://dxr.mozilla.org/mozilla-central/rev/13f49da109ea460665ad27c8497cb1489548450c/layout/generic/nsImageFrame.cpp#1764
We can raise the loading priority to high priority at this time.
Or, we can do it earlier while the visibility of the image frame is changed and request for decode:
https://dxr.mozilla.org/mozilla-central/rev/13f49da109ea460665ad27c8497cb1489548450c/layout/generic/nsImageFrame.cpp#710
Assignee | ||
Comment 10•8 years ago
|
||
1. raise some priority for size-decode-required image if the image size is demanded by layout.
2. raise more priority for full-decode-required image if the image content is demanded by rendering.
Reporter | ||
Comment 11•8 years ago
|
||
Comment on attachment 8812098 [details] [diff] [review]
[WIP] image-priority.patch
Review of attachment 8812098 [details] [diff] [review]:
-----------------------------------------------------------------
I'll try to find time and test this patch locally. It's great you found the right spots!
::: layout/generic/nsImageFrame.cpp
@@ +898,5 @@
> + if (!imageBroken && mLoadUrgency < NEED_SIZE) {
> + mLoadUrgency = NEED_SIZE;
> + nsCOMPtr<nsISupportsPriority> p = do_QueryInterface(currentRequest);
> + if (p) {
> + p->AdjustPriority(1);
is this a typo? you are actually lowering the priority a bit here.
Assignee | ||
Comment 12•8 years ago
|
||
(In reply to Honza Bambas (:mayhemer) from comment #11)
> Comment on attachment 8812098 [details] [diff] [review]
> [WIP] image-priority.patch
>
> Review of attachment 8812098 [details] [diff] [review]:
> -----------------------------------------------------------------
>
> I'll try to find time and test this patch locally. It's great you found the
> right spots!
>
> ::: layout/generic/nsImageFrame.cpp
> @@ +898,5 @@
> > + if (!imageBroken && mLoadUrgency < NEED_SIZE) {
> > + mLoadUrgency = NEED_SIZE;
> > + nsCOMPtr<nsISupportsPriority> p = do_QueryInterface(currentRequest);
> > + if (p) {
> > + p->AdjustPriority(1);
>
> is this a typo? you are actually lowering the priority a bit here.
should be -1, WIP updated.
Assignee | ||
Comment 13•8 years ago
|
||
Attachment #8812098 -
Attachment is obsolete: true
Reporter | ||
Comment 14•8 years ago
|
||
sc, what is the status here? What updated the wip patch needs?
(This is one of the most important CDP bugs.)
Flags: needinfo?(schien)
Assignee | ||
Comment 15•8 years ago
|
||
Sorry for the late response, putting most of my time on PBackground-ify bugs.
Tried to verify if my WIP works today and found it doesn't work as expected.
1. AdjustPriority() doesn't take effect because we don't allow priority changed by other than the first imageRequestProxy. https://searchfox.org/mozilla-central/rev/848c29538ab007fb95dc6cff194f0e3d3809613d/image/imgRequest.cpp#539
2. The timing of AdjustPriority() is still to late (even if we workaround 1), so that it is hard to have impact on the loading order.
3. The code for updating priority for image size request doesn't filter the case that height/width is already provided on the <img> element.
4. Priority doesn't affect the loading sequence if image is loaded from cache.
I'll provide a patch to fix 2) and 3) this week.
Flags: needinfo?(schien)
Assignee | ||
Comment 16•8 years ago
|
||
Here is the test case I used to verify the order of image loading.
https://people-mozilla.org/~schien/image-test/img-load-order.html
It is hosted on HTTP1.1 server and cache is disabled for all the resources so we can monitor the order of pending transactions to see if our algorithm takes effect.
There are totally 10 images in this test case, each of them has different attributes.
The perfect loading order in theory will be:
8no-size.png (need both image size and content for layout and rendering)
7known-size.png (only need image content for rendering)
rnd-3m.png (background image, need image content for rendering)
1hidden.png (need image size for layout)
4not-in-view.png (need image size for layout)
(follow the order in html since we don't need both size and image content for these <img>)
2display-none.png
3hidden-size.png
5sure-not-in-view.png
6end-of-doc.png
9zero-size.png
Assignee | ||
Comment 17•8 years ago
|
||
(In reply to Shih-Chiang Chien [:schien] (UTC+8) (use ni? plz) from comment #15)
> 2. The timing of AdjustPriority() is still to late (even if we workaround
> 1), so that it is hard to have impact on the loading order.
This is actually caused by bug 1338096.
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Assignee | ||
Updated•8 years ago
|
Attachment #8835951 -
Attachment is obsolete: true
Assignee | ||
Updated•8 years ago
|
Attachment #8835952 -
Attachment is obsolete: true
Assignee | ||
Comment 22•8 years ago
|
||
Assignee | ||
Comment 23•8 years ago
|
||
Here is the summary of latest status:
1. In patch part 1 I introduce `forceAdjustPriority` in imgIRequest in order to by pass the first proxy restriction in imgRequestProxy[1], since the first proxy is usually created by nsHtml5SpeculativeLoad. You'll not be able to adjust priority via nsISupportsPriority in layout since it'll always get the second one.
2. Priority boost for size query is moved to nsImageFrame::Init, this will be the earliest timing I can find.
3. In my experiment, most of the image-rich websites already specify the height/width of each <img>. Therefore, most of the load priority boost is made by the visibility in viewport.
Assignee | ||
Comment 24•8 years ago
|
||
From the test result of WebPageTest this patch shows performance improvement on Alexa top 100. I'll start the review process for my patches.
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Assignee | ||
Updated•8 years ago
|
Attachment #8812638 -
Attachment is obsolete: true
Comment 27•8 years ago
|
||
(In reply to Shih-Chiang Chien [:schien] (UTC+8) (use ni? plz) from comment #23)
> 3. In my experiment, most of the image-rich websites already specify the
> height/width of each <img>. Therefore, most of the load priority boost is
> made by the visibility in viewport.
(In reply to Shih-Chiang Chien [:schien] (UTC+8) (use ni? plz) from comment #24)
> From the test result of WebPageTest this patch shows performance improvement
> on Alexa top 100. I'll start the review process for my patches.
Where are we getting the performance increase from this? How much? What are we measuring? How long it takes to get the page load event?
Why do we want to increase the priority of all images (even those that layout doesn't depend on)? Aren't things like css and fonts more important?
Is the goal to improve page load time? Or improve the user experience by having visible things load sooner?
Reporter | ||
Comment 28•8 years ago
|
||
(In reply to Timothy Nikkel (:tnikkel) from comment #27)
> (In reply to Shih-Chiang Chien [:schien] (UTC+8) (use ni? plz) from comment
> #23)
> > 3. In my experiment, most of the image-rich websites already specify the
> > height/width of each <img>. Therefore, most of the load priority boost is
> > made by the visibility in viewport.
>
> (In reply to Shih-Chiang Chien [:schien] (UTC+8) (use ni? plz) from comment
> #24)
> > From the test result of WebPageTest this patch shows performance improvement
> > on Alexa top 100. I'll start the review process for my patches.
>
> Where are we getting the performance increase from this?
Not sure I understand the question - does "where" means on "which web sites?" Or what?
> How much?
Gary would know better. Gary?
> What are
> we measuring?
AFAIK, speed index and perceived speed index as part of Web Page Test.
> How long it takes to get the page load event?
Can't answer that.
>
> Why do we want to increase the priority of all images (even those that
> layout doesn't depend on)?
We shouldn't. How do we recognize that layout doesn't depend on an element/image?
> Aren't things like css and fonts more important?
Depends, but head referenced sync scripts definitely are more important than images. Do you see us going against that?
>
> Is the goal to improve page load time?
No.
> Or improve the user experience by
> having visible things load sooner?
Yes.
Flags: needinfo?(xeonchen)
Comment 29•8 years ago
|
||
(In reply to Honza Bambas (:mayhemer) from comment #28)
> > Why do we want to increase the priority of all images (even those that
> > layout doesn't depend on)?
>
> We shouldn't. How do we recognize that layout doesn't depend on an
> element/image?
The HaveSpecifiedSize check should do that.
> > Aren't things like css and fonts more important?
>
> Depends, but head referenced sync scripts definitely are more important than
> images. Do you see us going against that?
There is only a finite amount of bandwidth to go around, if we increase images we implicitly decrease priority of everything else.
In nsImageFrame::Init we should only increase the priority of images that do not have a specified size.
nsImageFrame::BuildDisplayList is relatively late, we know that the image is visible sooner than that. If you put the priority adjustment in nsImageFrame::MaybeDecodeForPredictedSize then that will be called at important times: after reflow, when the image is determined to be visible, as well as BuildDisplayList (if we haven't already).
Also, Init can be called more than once because we can re-create the frame. So the priority would keep getting adjusted higher each time. We'd want to avoid that. We could either keep track either on the content node (nsImageLoadingContent) or on the imgRequestProxy.
So there seems to be two separate things we want to do:
1) increase priority of images without a specified size because layout depends on them
2) increase priority of visible images so the page appears to be visibly complete faster
We should separate out these changes and measure their effect on the testsuite you are using. So we know how much they each improve the results.
Comment 30•8 years ago
|
||
(In reply to Honza Bambas (:mayhemer) from comment #28)
> (In reply to Timothy Nikkel (:tnikkel) from comment #27)
> > (In reply to Shih-Chiang Chien [:schien] (UTC+8) (use ni? plz) from comment
> > #23)
> > > 3. In my experiment, most of the image-rich websites already specify the
> > > height/width of each <img>. Therefore, most of the load priority boost is
> > > made by the visibility in viewport.
> >
> > (In reply to Shih-Chiang Chien [:schien] (UTC+8) (use ni? plz) from comment
> > #24)
> > > From the test result of WebPageTest this patch shows performance improvement
> > > on Alexa top 100. I'll start the review process for my patches.
> >
> > Where are we getting the performance increase from this?
>
> Not sure I understand the question - does "where" means on "which web
> sites?" Or what?
>
> > How much?
>
> Gary would know better. Gary?
>
We're running top-100 sites ([1]) on WebPageTest private instance to check performance results.
Every site for 30 times of firstView (no cache) & repeateView (with cache).
It suggested that this patch improves the Speed Index metric, but after investigation, we found it needs to re-test because the tests were not run at the same day, and the contents may vary.
I'm afraid it may take more than a week (1-min * 30-time * 2-view * 100-site * 2-browser) for the result.
> > What are
> > we measuring?
>
> AFAIK, speed index and perceived speed index as part of Web Page Test.
>
Only speed index. [2] lists the values we have.
[1] https://docs.google.com/a/mozilla.com/spreadsheets/d/1xErRcxgK2eXdJMZAmSwD6wSjz12xoK8rPpIIHdJK87g/edit?usp=sharing
[2] https://sites.google.com/a/webpagetest.org/docs/advanced-features/raw-test-results
Flags: needinfo?(xeonchen)
Comment 31•8 years ago
|
||
To move forward with this I think we need:
1) split the change into two parts: one part that increases the priority of images who's sizes are needed for layout, and one part that increases priority of images that are visible to the user
2) we need to do some tests to show that this improves our speed and doesn't hurt us anywhere else.
Comment 32•8 years ago
|
||
(In reply to Timothy Nikkel (:tnikkel) from comment #31)
> 2) we need to do some tests to show that this improves our speed and doesn't
> hurt us anywhere else.
Testing the two parts separately to see what effect each part has.
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Assignee | ||
Comment 36•8 years ago
|
||
[test set]
test build for increasing for size query
https://treeherder.mozilla.org/#/jobs?repo=try&revision=e12c7af02bbf54d77ae21503fca7924bd779abc4
test build for increasing for displaying
https://treeherder.mozilla.org/#/jobs?repo=try&revision=2c663258f0817445627ae1f42d1407571478ee3d
[control set]
https://treeherder.mozilla.org/#/jobs?repo=try&revision=c9c3ed1da71c236ce36a30099ea02e31a93b5d7d
@xeonchen can you run WebPageTest against these three versions?
Flags: needinfo?(xeonchen)
Comment 37•8 years ago
|
||
mozreview-review |
Comment on attachment 8837980 [details]
Bug 1312770 - Part 2, slightly increase loading priority for images that need size information for layout.
https://reviewboard.mozilla.org/r/112990/#review124292
::: layout/generic/nsImageFrame.cpp:287
(Diff revision 3)
> // Give image loads associated with an image frame a small priority boost!
> nsCOMPtr<imgIRequest> currentRequest;
> imageLoader->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
> getter_AddRefs(currentRequest));
> if (currentRequest) {
> - currentRequest->ForceAdjustPriority(-1);
> + int32_t delta = -1;
We should just increase the priority when !HaveSpecifiedSize. Increasing priority of all images could work against us.
Comment 38•8 years ago
|
||
mozreview-review |
Comment on attachment 8849371 [details]
Bug 1312770 - Part 3, increase loading priority for images that are visible in viewport.
https://reviewboard.mozilla.org/r/122158/#review124294
::: layout/generic/nsImageFrame.cpp:1793
(Diff revision 1)
> if (!(status & imgIRequest::STATUS_DECODE_COMPLETE)) {
> MaybeDecodeForPredictedSize();
> }
> +
> + // Increase loading priority if the image is ready to be displayed.
> + if (!(status & imgIRequest::STATUS_LOAD_COMPLETE) &&
This seems like a big priority boost (10). Why not just increase by 1 like in Init?
Assignee | ||
Comment 39•8 years ago
|
||
mozreview-review-reply |
Comment on attachment 8837980 [details]
Bug 1312770 - Part 2, slightly increase loading priority for images that need size information for layout.
https://reviewboard.mozilla.org/r/112990/#review124292
> We should just increase the priority when !HaveSpecifiedSize. Increasing priority of all images could work against us.
This is the logic we have in tree, see https://searchfox.org/mozilla-central/rev/ee7cfd05d7d9f83b017dd54c2052a2ec19cbd48b/layout/generic/nsImageFrame.cpp#288. Apperently it was introduced by bug 278531 long time ago. Do you think we should remove it and just (-1) for `!HaveSpecifiedSize`?
Assignee | ||
Comment 40•8 years ago
|
||
mozreview-review-reply |
Comment on attachment 8849371 [details]
Bug 1312770 - Part 3, increase loading priority for images that are visible in viewport.
https://reviewboard.mozilla.org/r/122158/#review124294
> This seems like a big priority boost (10). Why not just increase by 1 like in Init?
All the image are initially loaded in low priority (+10) [1]. I think we should raise the priority of visible images back to normal priority (0) so they have same priority as XHR.
JS/CSS are marked as blocking items and fonts are initially loaded in high priority (-10) [2]. They'll still be loaded before images.
[1] https://searchfox.org/mozilla-central/rev/ee7cfd05d7d9f83b017dd54c2052a2ec19cbd48b/image/imgLoader.cpp#857
[2] https://searchfox.org/mozilla-central/rev/ee7cfd05d7d9f83b017dd54c2052a2ec19cbd48b/layout/style/FontFaceSet.cpp#643
Comment 41•8 years ago
|
||
mozreview-review |
Comment on attachment 8837980 [details]
Bug 1312770 - Part 2, slightly increase loading priority for images that need size information for layout.
https://reviewboard.mozilla.org/r/112990/#review124348
::: layout/generic/nsImageFrame.cpp:287
(Diff revision 3)
> // Give image loads associated with an image frame a small priority boost!
> nsCOMPtr<imgIRequest> currentRequest;
> imageLoader->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
> getter_AddRefs(currentRequest));
> if (currentRequest) {
> - currentRequest->ForceAdjustPriority(-1);
> + int32_t delta = -1;
The bug that your part 1 patches fixes means that we don't adjust the priority of any image, right?
So currently we don't adjust priority of any image.
If we want to increase the priority of all images in nsImageFrame::Init we should have some data to back that up.
Comment 42•8 years ago
|
||
mozreview-review-reply |
Comment on attachment 8849371 [details]
Bug 1312770 - Part 3, increase loading priority for images that are visible in viewport.
https://reviewboard.mozilla.org/r/122158/#review124294
> All the image are initially loaded in low priority (+10) [1]. I think we should raise the priority of visible images back to normal priority (0) so they have same priority as XHR.
>
> JS/CSS are marked as blocking items and fonts are initially loaded in high priority (-10) [2]. They'll still be loaded before images.
>
> [1] https://searchfox.org/mozilla-central/rev/ee7cfd05d7d9f83b017dd54c2052a2ec19cbd48b/image/imgLoader.cpp#857
> [2] https://searchfox.org/mozilla-central/rev/ee7cfd05d7d9f83b017dd54c2052a2ec19cbd48b/layout/style/FontFaceSet.cpp#643
That's a valid argument. But why should visible images be increased by 10 when images whose size information is needed to layout the page (!HaveSpecifiedSize) only get a boost of 1? Those images would seem to be just as important.
Comment 43•8 years ago
|
||
mozreview-review |
Comment on attachment 8837980 [details]
Bug 1312770 - Part 2, slightly increase loading priority for images that need size information for layout.
https://reviewboard.mozilla.org/r/112990/#review124352
::: layout/generic/nsImageFrame.cpp:290
(Diff revision 3)
> getter_AddRefs(currentRequest));
> if (currentRequest) {
> - currentRequest->ForceAdjustPriority(-1);
> + int32_t delta = -1;
> +
> + // Increase load priority further if intrinsic size might be important for layout.
> + if (!HaveSpecifiedSize(StylePosition())) {
We should also check if the currentRequest has size available already. If the size is available then we don't need to increase the priority. There is already a function to check that: SizeIsAvailable.
Assignee | ||
Comment 44•8 years ago
|
||
mozreview-review-reply |
Comment on attachment 8837980 [details]
Bug 1312770 - Part 2, slightly increase loading priority for images that need size information for layout.
https://reviewboard.mozilla.org/r/112990/#review124348
> The bug that your part 1 patches fixes means that we don't adjust the priority of any image, right?
>
> So currently we don't adjust priority of any image.
>
> If we want to increase the priority of all images in nsImageFrame::Init we should have some data to back that up.
The `AdjustPriority(-1)` in current code doesn't take effect because the nsImageFrame is not holding the first imgRequestProxy. So, yes, the runtime behavior of current Firefox will not increase the priority.
However I think this is an unawared side effect after speculative image loading in HTML parser was introduced in bug 482919. This patch changes the owner of first proxy. That's the reason why I try reactivate this priority change.
I'm fine with removing the `AdjustPriority(-1)` since it's a dead code for a while. We can focus on the new algorithm based on current behavior.
Assignee | ||
Comment 45•8 years ago
|
||
mozreview-review-reply |
Comment on attachment 8849371 [details]
Bug 1312770 - Part 3, increase loading priority for images that are visible in viewport.
https://reviewboard.mozilla.org/r/122158/#review124294
> That's a valid argument. But why should visible images be increased by 10 when images whose size information is needed to layout the page (!HaveSpecifiedSize) only get a boost of 1? Those images would seem to be just as important.
My theory is that complete rendering an image on viewport will stable a large chunk of pixels on screen. This can improve more on our metrics because SpeedIndex prefers pixels that rendered as early as possible. Obtaining size information earlier might not contribute that much pixels, so I only add small boost to create a local order among images without affecting the global order.
Comment 46•8 years ago
|
||
(In reply to Shih-Chiang Chien [:schien] (UTC+8) (use ni? plz) from comment #36)
> @xeonchen can you run WebPageTest against these three versions?
Sure, it's running :)
Flags: needinfo?(xeonchen)
Assignee | ||
Comment 47•8 years ago
|
||
(In reply to Timothy Nikkel (:tnikkel) from comment #29)
> nsImageFrame::BuildDisplayList is relatively late, we know that the image is
> visible sooner than that. If you put the priority adjustment in
> nsImageFrame::MaybeDecodeForPredictedSize then that will be called at
> important times: after reflow, when the image is determined to be visible,
> as well as BuildDisplayList (if we haven't already).
>
> Also, Init can be called more than once because we can re-create the frame.
> So the priority would keep getting adjusted higher each time. We'd want to
> avoid that. We could either keep track either on the content node
> (nsImageLoadingContent) or on the imgRequestProxy.
Based on these two information, I'm thinking about providing boostForSizeQuery/boostForDisplay in imgIRequest and let imgRequest ensure priority is only increased once for each scenario.
Reporter | ||
Comment 48•8 years ago
|
||
Few notes:
- FYI, I want to change fonts to load as head-blocking (will file a bug)
- View port visible images should be raised by -10
- Missing size images should be increased by say -1 or -5
=> then, an image w/o size info visible in the view port will be raised by -15
=> load priorities will then be in the following order: visible-no-size, visible-size, invisible-no-size, invisible
Maybe the patches already do that :) (Haven't yet taken a look)
Comment 49•8 years ago
|
||
(In reply to Shih-Chiang Chien [:schien] (UTC+8) (use ni? plz) from comment #44)
> The `AdjustPriority(-1)` in current code doesn't take effect because the
> nsImageFrame is not holding the first imgRequestProxy. So, yes, the runtime
> behavior of current Firefox will not increase the priority.
>
> However I think this is an unawared side effect after speculative image
> loading in HTML parser was introduced in bug 482919. This patch changes the
> owner of first proxy. That's the reason why I try reactivate this priority
> change.
Okay, so we haven't been doing it for 7+ years
> I'm fine with removing the `AdjustPriority(-1)` since it's a dead code for a
> while. We can focus on the new algorithm based on current behavior.
I'm not advocating either way, but we need some kind of evidence to make these decisions otherwise we are just flying blindly and could be making things worse.
(In reply to Shih-Chiang Chien [:schien] (UTC+8) (use ni? plz) from comment #45)
> My theory is that complete rendering an image on viewport will stable a
> large chunk of pixels on screen. This can improve more on our metrics
> because SpeedIndex prefers pixels that rendered as early as possible.
> Obtaining size information earlier might not contribute that much pixels, so
> I only add small boost to create a local order among images without
> affecting the global order.
We need some kind of evidence to back this up. It could be argued that the page contents moving around (because we had to re-layout the page because we got needed size information from an image) is a worse user experience then an image not being loaded as quickly: the user can't read or interact with the page in any way until it stops moving around.
Assignee | ||
Comment 50•8 years ago
|
||
This is another approach that follows comment #29. I keep the priority boost for display in BuildDisplayList to keep the same result I described in comment #16.
I tried to move that part in to MaybeDecodeForPredictedSize with following code:
>nsCOMPtr<nsIImageLoadingContent> imageLoader = do_QueryInterface(mContent);
>if (imageLoader && IsVisibleForPainting()) {
> nsCOMPtr<imgIRequest> currentRequest;
> imageLoader->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
> getter_AddRefs(currentRequest));
> if (currentRequest) {
> currentRequest->BoostPriority(imgIRequest::CATEGORY_DISPLAY);
> }
>}
However I found the "4not-in-view.png" and "5sure-not-in-view.png" will still request for display boost. Those two 30x30 images are placed (-80,-80) so it is not in the viewport. Don't know if I misunderstand the meaning of `IsVisibleForPainting()`.
Attachment #8849984 -
Flags: feedback?(tnikkel)
Comment 51•8 years ago
|
||
(In reply to Shih-Chiang Chien [:schien] (UTC+8) (use ni? plz) from comment #50)
> Created attachment 8849984 [details] [diff] [review]
> store-request-in-imgrequest.patch
>
> This is another approach that follows comment #29. I keep the priority boost
> for display in BuildDisplayList to keep the same result I described in
> comment #16.
>
> I tried to move that part in to MaybeDecodeForPredictedSize with following
> code:
>
>
> >nsCOMPtr<nsIImageLoadingContent> imageLoader = do_QueryInterface(mContent);
> >if (imageLoader && IsVisibleForPainting()) {
> > nsCOMPtr<imgIRequest> currentRequest;
> > imageLoader->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
> > getter_AddRefs(currentRequest));
> > if (currentRequest) {
> > currentRequest->BoostPriority(imgIRequest::CATEGORY_DISPLAY);
> > }
> >}
>
> However I found the "4not-in-view.png" and "5sure-not-in-view.png" will
> still request for display boost. Those two 30x30 images are placed (-80,-80)
> so it is not in the viewport. Don't know if I misunderstand the meaning of
> `IsVisibleForPainting()`.
I don't quite understand, IsVisibleForPainting can only be called with a nsDisplayListBuilder argument, so it has to be called during painting, ie in BuildDisplayList.
If you're putting your code into MaybeDecodeForPredictedSize then I think I know the problem. MaybeDecodeForPredictedSize tries to decode images that are "close to visible" in that they could be scrolled into view without much scrolling. This is the menaing of APPROXIMATELY_VISIBLE here
https://dxr.mozilla.org/mozilla-central/rev/e03e0c60462c775c7558a1dc9d5cf2076c3cd1f9/layout/generic/nsImageFrame.cpp#722
Assignee | ||
Comment 52•8 years ago
|
||
(In reply to Timothy Nikkel (:tnikkel) from comment #51)
> (In reply to Shih-Chiang Chien [:schien] (UTC+8) (use ni? plz) from comment
> > However I found the "4not-in-view.png" and "5sure-not-in-view.png" will
> > still request for display boost. Those two 30x30 images are placed (-80,-80)
> > so it is not in the viewport. Don't know if I misunderstand the meaning of
> > `IsVisibleForPainting()`.
>
> I don't quite understand, IsVisibleForPainting can only be called with a
> nsDisplayListBuilder argument, so it has to be called during painting, ie in
> BuildDisplayList.
There is one `IsVisibleForPainting()` that takes no parameter, only two usages found in current code base.
https://dxr.mozilla.org/mozilla-central/rev/e03e0c60462c775c7558a1dc9d5cf2076c3cd1f9/layout/generic/nsFrame.cpp#7229
>
> If you're putting your code into MaybeDecodeForPredictedSize then I think I
> know the problem. MaybeDecodeForPredictedSize tries to decode images that
> are "close to visible" in that they could be scrolled into view without much
> scrolling. This is the menaing of APPROXIMATELY_VISIBLE here
>
> https://dxr.mozilla.org/mozilla-central/rev/
> e03e0c60462c775c7558a1dc9d5cf2076c3cd1f9/layout/generic/nsImageFrame.cpp#722
Yeah I'm also suspecting that APPROXIMATELY_VISIBLE check is too loose to be used in my case.
To be noticed that images with "visibility: hidden" will also pass the APPROXIMATELY_VISIBLE check. By using `IsVisibleForPainting` I mentioned above, I can filter out those images.
Comment 53•8 years ago
|
||
(In reply to Shih-Chiang Chien [:schien] (UTC+8) (use ni? plz) from comment #52)
> There is one `IsVisibleForPainting()` that takes no parameter, only two
> usages found in current code base.
> https://dxr.mozilla.org/mozilla-central/rev/
> e03e0c60462c775c7558a1dc9d5cf2076c3cd1f9/layout/generic/nsFrame.cpp#7229
Oh, that's a weird one. Looks like the only check it does besides visibility: hidden is when printing is limited to a selection.
> Yeah I'm also suspecting that APPROXIMATELY_VISIBLE check is too loose to be
> used in my case.
> To be noticed that images with "visibility: hidden" will also pass the
> APPROXIMATELY_VISIBLE check. By using `IsVisibleForPainting` I mentioned
> above, I can filter out those images.
Hmm, I think you might have found a bug. Looks like nsIFrame::UpdateVisibilitySynchronously (which we call to update visibility of one frame when we know that one frame changed and want to know it's visibility right away) doesn't consider the style visibility of the frame, but PresShell::MarkFramesInSubtreeApproximatelyVisible (which we call less frequently to update visibility of all frames) does consider the style visibility of frames.
Anyways, we can probably make a version of nsIFrame::UpdateVisibilitySynchronously that doesn't consider images that are just scrolled out of view to be visible that you could use for this. The difference would be that it would return true/false for visibile/not visible instead of calling EnsureFrameInApproximatelyVisibleList/RemoveFrameFromApproximatelyVisibleList, and then change the IsRectNearlyVisible call to only intersect with the scrollport without calling ExpandRectToNearlyVisible.
Comment 54•8 years ago
|
||
(In reply to Timothy Nikkel (:tnikkel) from comment #53)
> Hmm, I think you might have found a bug. Looks like
> nsIFrame::UpdateVisibilitySynchronously (which we call to update visibility
> of one frame when we know that one frame changed and want to know it's
> visibility right away) doesn't consider the style visibility of the frame,
> but PresShell::MarkFramesInSubtreeApproximatelyVisible (which we call less
> frequently to update visibility of all frames) does consider the style
> visibility of frames.
-> bug 1350463
Assignee | ||
Comment 55•8 years ago
|
||
(In reply to Timothy Nikkel (:tnikkel) from comment #53)
> (In reply to Shih-Chiang Chien [:schien] (UTC+8) (use ni? plz) from comment
> Anyways, we can probably make a version of
> nsIFrame::UpdateVisibilitySynchronously that doesn't consider images that
> are just scrolled out of view to be visible that you could use for this. The
> difference would be that it would return true/false for visibile/not visible
> instead of calling
> EnsureFrameInApproximatelyVisibleList/
> RemoveFrameFromApproximatelyVisibleList, and then change the
> IsRectNearlyVisible call to only intersect with the scrollport without
> calling ExpandRectToNearlyVisible.
It'll be great if we can differentiate the loading priority between *really* visible elements and approximately visible elements. Is there a bug for this modification?
We can have three categories of image boost to fine tune the image loading order.
- boost for size query
- boost for approximately visible items
- boost for really visible items
Assignee | ||
Comment 56•8 years ago
|
||
Just finish the result analysis of the previous WPT run.
1. Most of websites shows no major difference on SpeedIndex. (note: plus means better performance)
- Boost for size query:
51/60 sites are within ±5% range,
6 sites within -10%~-5%,
1 site within +5%~+10%,
3 sites within +10%~+20%.
- Boost for display:
46/60 sites are within ±5% range,
1 site within -10%~-20%,
5 sites within -10%~-5%,
8 sites within +5%~+10%.
My reading from the WPT test result is that loading order among images within the same origin doesn't have much influence on the SpeedIndex, the main difference is usually cause by switching order with cross-origin JS. The cross-origin JS is usually for Ad, social network gadget, and SEO. It will consume both network bandwidth and CPU cycle for downloading and executing them. If images happens to load before that, SpeedIndex will have better results. However, our current prioritization algorithm doesn't affect the global load order. Thus we cannot observe an obvious improvement on single prioritization algorithm.
2. Loading major images first can improve the SpeedIndex in some case.
Take https://techcrunch.com/2016/05/10/please-dont-learn-to-code/ as example. The codecode.jpg occupies a significant amount of viewport. Loading that image first will improve SpeedIndex, in this case around 10%
Loading sequence with boost for display: https://people-mozilla.org/~schien/image-test/major-pic-first.png
Loading sequence of current m-c: https://people-mozilla.org/~schien/image-test/major-pic-later.png
The codecode.jpg loads 0.09s earlier can still make differences on the performance.
Comment 57•8 years ago
|
||
These results almost seem like a wash. Do we still want to proceed with this?
Assignee | ||
Comment 58•8 years ago
|
||
The second bullet point in comment #56 still shows positive effect under certain circumstances. To make the performance improvement more observable, we need to do more flow control and prioritization among all the connections. I think this is the path we are taking for the entire CDP project. I'll suggest to continue the review process.
Comment 59•8 years ago
|
||
Too late for firefox 52, mass-wontfix.
Reporter | ||
Updated•8 years ago
|
Priority: -- → P1
Reporter | ||
Comment 60•8 years ago
|
||
Timothy, ping on review here. We would like to take the patch as is ASAP to start getting a field results (for potential regressions mainly). If there are any major changes that could be done in followups, let's file them and fix separately.
Thanks.
Flags: needinfo?(tnikkel)
Comment 61•8 years ago
|
||
We need something like store-request-in-imgrequest.patch before we can make any of these changes otherwise more than one copy of the image in the same document, or in other tabs can increase the priority by huge amounts. So lets start with the patch that does that, then implement the rest on top of that.
We should land each proposed change separately (so that they go onto different nightlies) so that if we get talos or telemetry changes (or other improvements or regressions reported) we can attribute them to a specific change. The three separate changes are:
1) giving all images a small boost (like we used to a very long time ago, but is currently broken)
2) giving visible images a big boost
3) giving images whose size is needed a boost.
Flags: needinfo?(tnikkel)
Comment 62•8 years ago
|
||
Comment on attachment 8849984 [details] [diff] [review]
store-request-in-imgrequest.patch
Yes, something like this makes sense. Let's base the other patches on this.
Attachment #8849984 -
Flags: ui-review+
Attachment #8849984 -
Flags: feedback?(tnikkel)
Attachment #8849984 -
Flags: feedback+
Updated•8 years ago
|
Attachment #8849984 -
Flags: ui-review+
Comment 63•8 years ago
|
||
Comment on attachment 8837979 [details]
Bug 1312770 - Part 1, allow any imgRequestProxy to adjust load priority.
I would like to see the patches rebased on top of something like store-request-in-imgrequest.patch
Attachment #8837979 -
Flags: review?(tnikkel)
Updated•8 years ago
|
Attachment #8837980 -
Flags: review?(tnikkel)
Updated•8 years ago
|
Attachment #8849371 -
Flags: review?(tnikkel)
Assignee | ||
Comment 64•8 years ago
|
||
(In reply to Timothy Nikkel (:tnikkel) from comment #63)
> Comment on attachment 8837979 [details]
> Bug 1312770 - Part 1, allow any imgRequestProxy to adjust load priority.
>
> I would like to see the patches rebased on top of something like
> store-request-in-imgrequest.patch
Thanks @tnikkel, I'll split my patch and file separated bugs for each of them.
Reporter | ||
Comment 65•8 years ago
|
||
Just a note we would like to land the patches as soon as possible, since this is an important part of the CDP project. I definitely don't want to land each patch on a different release number. Landing them (in an order to be determined) in few days intervals is preferred. Thanks.
Assignee | ||
Comment 66•8 years ago
|
||
Conflict will need to be resolved if landed after bug 1357327.
Attachment #8837979 -
Attachment is obsolete: true
Attachment #8837980 -
Attachment is obsolete: true
Attachment #8849371 -
Attachment is obsolete: true
Attachment #8849984 -
Attachment is obsolete: true
Attachment #8859144 -
Flags: review?(tnikkel)
Comment 67•8 years ago
|
||
(In reply to Honza Bambas (:mayhemer) from comment #65)
> Just a note we would like to land the patches as soon as possible, since
> this is an important part of the CDP project. I definitely don't want to
> land each patch on a different release number. Landing them (in an order to
> be determined) in few days intervals is preferred. Thanks.
I definitely did not want to land them in different release _number_, thats way too far apart. Just landed one day apart so they are on different nightlies.
Updated•8 years ago
|
Attachment #8859144 -
Flags: review?(tnikkel) → review+
Assignee | ||
Comment 68•8 years ago
|
||
rebase to latest m-c, carry r+
Attachment #8859144 -
Attachment is obsolete: true
Attachment #8861260 -
Flags: review+
Assignee | ||
Updated•8 years ago
|
Keywords: checkin-needed
Comment 69•8 years ago
|
||
Pushed by ryanvm@gmail.com:
https://hg.mozilla.org/integration/mozilla-inbound/rev/abb953c4e429
Slightly increase loading priority for images that need size information for layout. r=tnikkel
Keywords: checkin-needed
Comment 70•8 years ago
|
||
bugherder |
Status: NEW → RESOLVED
Closed: 8 years ago
status-firefox55:
--- → fixed
Resolution: --- → FIXED
Target Milestone: --- → mozilla55
Updated•6 years ago
|
Product: Core → Core Graveyard
Updated•6 years ago
|
Product: Core Graveyard → Core
You need to log in
before you can comment on or make changes to this bug.
Description
•