Dropped frames while scrolling in list with multiple spans
See original GitHub issueI’m observing some pretty hefty main thread blockage using the latest Coil version (0.11.0) and older ones too. I just migrated from Glide on this app (I’ve used Coil before in other projects but never in a RV adapter) and everything was smooth until I tried scrolling on the RV. Anyway, tested with both ixel 3 and OnePlus 7T Pro so clearly not an hardware bottleneck.
My setup is a 5 span GridLayoutManager vertical scrolling. One device has +300 pictures, the other has ~50, so doesn’t seem related to the amount of pictures. What I observe is when I start scrolling when Coil is decoding the URIs and starting to display the thumbnails something seems to block the main thread and the whole thing gets blocked and it seems to suspend the entire operation. Sometimes I have to wait 3-4 seconds for it to finish whatever it seems to be doing and it then resumes.
In the screenrecord I’m attatching you can see a bit of the jank after I open the app fresh. I made each thumb 8px/8px because it’s my personal pictures library, but you get the picture. It obviously has worse jank with their actual decoded size (which should be device width / spancount) (5 in this case). The jank is halved if I decrease the span count to 3 or 4. Here’s the very simple code I’m using:
LoadRequest request = LoadRequest.builder(((ViewHolder) holder).b.picture.getContext())
.key(item.getUri().toString())
.data(item.getUri())
.crossfade(false)
.target(((ViewHolder) holder).b.picture)
.build();
Coil.execute(request);
Logcat is filled with these GC related operations when doing the scrolling:
2020-05-19 20:36:44.160 12402-12415/com.franco.graphice I/franco.graphic: Background young concurrent copying GC freed 11330(820KB) AllocSpace objects, 48(1172KB) LOS objects, 0% free, 8438KB/8438KB, paused 124us total 157.193ms
2020-05-19 20:36:44.455 12402-12415/com.franco.graphice I/franco.graphic: Background concurrent copying GC freed 22434(2113KB) AllocSpace objects, 127(3216KB) LOS objects, 49% free, 7161KB/13MB, paused 438us total 288.432ms
2020-05-19 20:36:45.609 12402-12415/com.franco.graphice I/franco.graphic: Background young concurrent copying GC freed 28249(2948KB) AllocSpace objects, 190(4884KB) LOS objects, 0% free, 13MB/13MB, paused 590us total 693.969ms
2020-05-19 20:36:45.772 12402-12437/com.franco.graphice I/franco.graphic: Waiting for a blocking GC ProfileSaver
2020-05-19 20:36:46.126 12402-12415/com.franco.graphice I/franco.graphic: Background concurrent copying GC freed 46990(4091KB) AllocSpace objects, 222(5452KB) LOS objects, 49% free, 10MB/20MB, paused 1.728ms total 515.818ms
2020-05-19 20:36:46.126 12402-12437/com.franco.graphice I/franco.graphic: WaitForGcToComplete blocked ProfileSaver on ClassLinker for 354.762ms
2020-05-19 20:36:48.146 12402-12415/com.franco.graphice I/franco.graphic: Background young concurrent copying GC freed 111714(5587KB) AllocSpace objects, 253(6552KB) LOS objects, 0% free, 22MB/22MB, paused 300us total 851.007ms
2020-05-19 20:36:48.421 12402-12415/com.franco.graphice I/franco.graphic: Background concurrent copying GC freed 125680(7618KB) AllocSpace objects, 372(9332KB) LOS objects, 49% free, 8377KB/16MB, paused 654us total 258.322ms
2020-05-19 20:36:50.169 12402-12415/com.franco.graphice I/franco.graphic: Background concurrent copying GC freed 122438(7099KB) AllocSpace objects, 230(5824KB) LOS objects, 49% free, 5686KB/11MB, paused 48us total 438.112ms
Also it’s a bit better when using BitmapConfig RGB_565, but just a tiny bit. With the default BitmapConfig I see tons of these logcat messages:
2020-05-19 20:38:15.978 12923-12923/com.franco.graphice I/Choreographer: Skipped 40 frames! The application may be doing too much work on its main thread.
2020-05-19 20:38:16.211 12923-12965/com.franco.graphice I/OpenGLRenderer: Davey! duration=914ms; Flags=0, IntendedVsync=5662959106048, Vsync=5663625772688, OldestInputEvent=9223372036854775807, NewestInputEvent=0, HandleInputStart=5663641456128, AnimationStart=5663641473576, PerformTraversalsStart=5663642302847, DrawStart=5663719940563, SyncQueued=5663865801775, SyncStart=5663866294692, IssueDrawCommandsStart=5663867129952, SwapBuffers=5663869075161, FrameCompleted=5663874209172, DequeueBufferDuration=187000, QueueBufferDuration=1022000,
2020-05-19 20:38:16.321 12923-12936/com.franco.graphice I/franco.graphic: Background concurrent copying GC freed 108152(11MB) AllocSpace objects, 478(11MB) LOS objects, 50% free, 17MB/34MB, paused 201us total 1.090s
Any clues or question that I can answer to help you narrow it down somehow?
Thanks I hope this was clear enough.
Issue Analytics
- State:
- Created 3 years ago
- Reactions:7
- Comments:42 (19 by maintainers)
Top GitHub Comments
I’ve just published
2.0.0-alpha01
which should completely fix any performance issues related to scrolling. I’ve set the sample app to run with 5 columns and it doesn’t drop any frames.Among other performance improvements, 2.x throttles the output of
BitmapFactoryDecoder
. The number of parallelBitmapFactory
decodes defaults to 4, but can be adjusted usingImageLoader.Builder.bitmapFactoryMaxParallelism
. Increasing the number allows more parallel decodes, but may (slightly) reduce scrolling FPS. I felt 4 was a good default, but depending on how much work your app does on the main thread, your app may be able to handle more.@leondeklerk Unfortunately, there isn’t a great solution for this at the moment aside from setting
ImageLoader.Builder.dispatcher(Dispatchers.Default)
. That said, this bug should be completely fixed in 2.0. I’m able to run 5 columns in the sample app no problem. The alpha will be out soon.