Closed Bug 69534 Opened 24 years ago Closed 24 years ago

Unnecessary Reflows for animated GIF images: eliminate them now.

Categories

(Core :: Layout, defect, P2)

defect

Tracking

()

VERIFIED FIXED
mozilla0.8.1

People

(Reporter: attinasi, Assigned: attinasi)

References

Details

(Keywords: perf, topperf)

Attachments

(1 file)

nsImageFrame::UpdateImage is called whenever a new frame is to be displayed for an animated GIF. If the ImageFrame has a fixed width and height, there is no need to reflow it. Also, even if there are no width and height attributes, we can check if the iamge size is unchanged and avoid reflowing in that case as well. This should be a nice performance improvement, since most top100 pages have animated GIFs and we waste a whole lot of time relowing them when they almost never actually change size.
Accepting my own bug - marking perf kwd.
Status: NEW → ASSIGNED
Keywords: perf
Priority: -- → P2
Target Milestone: --- → mozilla0.9
Could this be causing bug 68228? If so, its not just a perf problem.
Mats - I'm not sure if this is the same problem, though it looks like it could be. Can you post a reduced testcase for the problem image in bug 68228? I'll cc myself on that bug and see if it is fixed too.
I did some performance analysis using a release build on Linux loading cnn.com. As a test I commented out the code which generated the reflow in nsImageFrame::UpdateImage. The page rendered correctly without this (Probably because the table ended up reflowing the image as content as appended.) cnn.com rendered 10% faster. A small change to nsImageFrame.cpp to cache the old width and height and only reflow if it has changed should speed up page loads on pages with animated gifs.
OK, I have a patch that checks to see if an image is fixed size (has explicit width and height) and bypasses the reflows on notifications if so. A further refinement is to handle the case where there is no width and height, but we know that the image has not changed size - I'm working on that.
Hyatt's playing around with similar hacks just now. /be
I just did this coincidentally. On jrgm's tests I got about a 4% speedup overall.
I did something a little different though. You may get better results.
I added code to the beginning of nsImageFrame that asked if you were doing a resizereflow. If you were, and your rect's width and height were the same as the reflow state's computed width and height, I just fill in those values and return immediately without calling GetDesiredSize, etc. Avoids thrashing around asking the image loader questions.
Kevin ran my patch against John's tests and we saw a ~20% improvement in the loadtimes - more than I expected. This is good, so I'm gonna go a little further and handle images that do not have an explicit width and height but we know that the intrinsic size has not changed. I think David's change will help too, but for a different reason: whereas my change prevents reflows on animated images, his changes will prevent reflows that DO get through from doing any unnecessary interactions with the imageloader.
Keywords: topperf
Are there any cases when moving to the next frame *does* affect the size of an image?
Yup, if the <img> has no width or height and the image's next frame is a different size, then we have to reflow because the size will change.
I produced a patch coincidentally on the same stuff. I sent it to you in email, attinasi and commented on mozilla.performance. I had some questions about your patch that I sent to you in email and to mozilla.performance.
sr=hyatt, although it seems that you can also fix the size for percentage widths/heights as well, and I have questions about values of 0 when used with width/height.
I'd love to see this checked in. However, it can be extended as well and pick up quite a few more pages/reflows. This turns off reflows for defined widths/heights (width=N, CSS equivalent, etc). (Hyatt's comment about percentages is good too, though you might need to make sure that we do reflow if the result of the percentage changes). Jesse Ruderman wrote: >Are there any cases when moving to the next frame *does* affect the size of an >image? Marc Attinasi wrote: >Yup, if the <img> has no width or height and the image's next frame is a >different size, then we have to reflow because the size will change. So, once we have a size for a single frame of an anim, if the next frame _is_ the same size, we should not reflow, right? I don't think the patch covers that case. I'd be happy to see the current patch checked in; but I'd like to see these other issues (especially the last one) dealt with as well.
For image frames that _do_ change size, would it make sense to make the allocated size monotonically increasing so that eventually it stops reflowing? Seems like this would only negatively impact cases where it was used to intentionally whack the contents around for some DHTML-like effect (and that wouldn't be done frequently would it?)
Isn't different framesizes _very_ rare? Shouldn't we in those rare cases do the RightThing and resize+reflow accordingly? I think it would give a very "buggy" look if we never decrease imagesize.
An animated GIF (the vast, vast majority of animated <IMG> content) cannot change its frame ('screen') size dynamically at all. I don't know about other animation formats such as MNG (I expect not, however).
Adam, is it part of the GIF specification that the individual frames are all the same size? I'm not familiar with the details there, but for some reason I assumed that each frame could be a different size (maybe I just infered it from the code.) Obviously it is an easier problem if the individual images in the animation MUST be the same size; in that case we never have to reflow for subsequent frames, and I do not have to cache the previous image size either. In either case, I'm gonna check in the simple change that checks for a fixed size (expanding the notion to include percentage width/height as well) and then worry about the case of the image size changing. Pavlov told me that his new image lib stuff makes this all pretty much obsolete anyway...
Hiya. It's part of the GIF spec that the dimensions of the outer frame ('screen size') are specified in the header and fixed for the duration of the GIF. Individual frames that constitute the animation are not necessarily the same size but are strictly restricted to the area defined by the outer frame[1], which should not expand and contract. So in short, the size of the image is fixed as far as layout is concerned. [1] Some broken GIFs have frames which overlap the edges of the image bounds but that's purely imagelib's problem (it should clip them, but AFAIK currently crashes) and not yours.
Thanks for the data, Adam. That makes the optimization much easier. I wonder if theis is now internalized in the new imagelib... We don't need new dimension notifications for each frame of the animation (in GIF anyweay)
Milestone shift --> Moz 0.8.1
Target Milestone: mozilla0.9 → mozilla0.8.1
Fix checked in: nsImageFrame.h/cpp
Status: ASSIGNED → RESOLVED
Closed: 24 years ago
Resolution: --- → FIXED
Blocks: 71668
Marking verified per last comments.
Status: RESOLVED → VERIFIED
*** Bug 60880 has been marked as a duplicate of this bug. ***
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: