Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GIFs animate slowly with Glide 4.2 #2471

Open
moxie0 opened this issue Oct 11, 2017 · 56 comments
Open

GIFs animate slowly with Glide 4.2 #2471

moxie0 opened this issue Oct 11, 2017 · 56 comments

Comments

@moxie0
Copy link

moxie0 commented Oct 11, 2017

Here is a screen capture of two gifs playing w/ Glide 3.7:
fastgif

Here is a screen capture of the same two gifs playing w/ Glide 4.2:
slowgif

      GlideApp.with(context)
              .load(url)
              .diskCacheStrategy(DiskCacheStrategy.ALL)
              .into(view);

This happens with any gif that I've tried, here's an example:
https://media.giphy.com/media/3ohjV3cQ9lvPeCVLOg/giphy.gif

Glide Version: 4.2.0
Integration libraries: None
Device/Android Version: Nexus 5, OnePlus One, Pixel

@lbx2015
Copy link

lbx2015 commented Oct 18, 2017

same as me. Can you give me some advise about the hand on code to load gif with 4.2.0? call my 18221650910 from china?
RequestOptions o = new RequestOptions();
Glide.with(h.imageView3.getContext())
.load("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1508322038285&di=e0c474540228565f1271de3b4b2c56e7&imgtype=0&src=http%3A%2F%2Fwww.lia-edu.com%2Fupload%2Fimage%2F20170717%2F20170717151619_8233.gif").apply(o.diskCacheStrategy(DiskCacheStrategy.RESOURCE)).into(h.imageView3);

@sjudd
Copy link
Collaborator

sjudd commented Oct 28, 2017

I'm not able to reproduce this on a Nexus 5X on 7.1.1 if I download the gifs you've pointed to. The GIFs are however pretty small.

Can you attach the files you're having trouble with directly to the issue to make sure we're testing using the same exact data?

Can you also provide the XML or at least the dimensions of the view you're loading into?

@moxie0
Copy link
Author

moxie0 commented Oct 30, 2017

Hmm, I think I must have made a mistake in my original issue report. I just tried building a sample app with a jarjar'd version of 3.7 and an unmodified 4.2 together in the same app which loads the same GIF into two adjacent ImageViews using two different versions of Glide, and I'm also not able to reproduce this.

What I am seeing, however, is that GIFs render in slow-motion with both Glide 3.7 and 4.2 on Android 5.0 and Android 6.0 devices (a Nexus 5 and OnePlus One, respectively), but render at normal speed on an Android 8.0 device (Pixel).

I tried a sample app with a single 3.7 or 4.2 production dependency, loading a single GIF, and the results are the same. Things render fine (with both 3.7 and 4.2) on an Android 8.0 device, but not an Android 5.0 or 6.0 device.

Here's a sample layout I'm using:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center">
        
        <ImageView
                android:id="@+id/image"
                android:layout_gravity="center"
                android:layout_width="210dp"
                android:layout_height="210dp"/>

</LinearLayout>

The Glide 4.2 code:

    Glide.with(this)
         .load(R.raw.giphy)
         .apply(RequestOptions.diskCacheStrategyOf(DiskCacheStrategy.NONE))
         .into((ImageView)findViewById(R.id.image));

An attached GIF I've tested with:
giphy

@sjudd
Copy link
Collaborator

sjudd commented Nov 1, 2017

Thanks for the follow up.

That makes sense. The GIF decoder we use isn't necessarily as fast or optimized as it could be. We've fixed a few cases where it was slower than it needed to be, but there may be more relatively simple changes we could make. Otherwise it might require a more fundamental restructuring.

One other idea we've been looking in to is adding support for rastermill/framesequence or another third party gif decoder as an integration library.

@ssessa
Copy link

ssessa commented Nov 13, 2017

I ran into this issue on a Nexus 5 running 6.0.1.

When running the debug Build Variant gifs perform poorly.

Once I switched to release, gifs began performing as expected. Hope this helps out...

@sjudd
Copy link
Collaborator

sjudd commented Nov 20, 2017

I haven't found anything huge so far but two things worth noting:

  1. In Glide 4.3.0, the number of threads available for GIFs decreased to 2 or 1. These threads are used only for GIF frames which avoids delays loading frames for network operations, but reduced the number of threads available for GIF frames, especially on high end devices. Limiting the number of concurrently playing GIFs will help. I'll also add an API in Glide 4.4.0 to allow you to modify the number of threads used for animations.
  2. In Glide 4.4.0, I'll add an (experimental) API called clearOnDetach (name may change, suggestions welcome). clearOnDetach will free up resources used by ViewTargets when the View is detached from it's window and automatically restart the request if the View is ever reattached. That method is primarily meant for reducing memory usage, but it will also help reduce the number of running GIFs by pausing those as soon as they go off screen. I've seen this help significantly in RecyclerView, which doesn't set visibility for off screen views and doesn't call its RecyclerListener for every view that's off screen. I may also try to just build this in to ViewTarget so that it happens automatically.

More to come as I find it. If anyone else has any suggestions or can reproduce any particularly bad cases, I'd welcome the help.

@sjudd
Copy link
Collaborator

sjudd commented Nov 21, 2017

@ssessa Are you using proguard? Do you have optimizations enabled? If you disable proguard but otherwise leave you release variant the same, do you still see GIF performance improve on those builds?

sjudd added a commit to sjudd/glide that referenced this issue Nov 22, 2017
sjudd added a commit to sjudd/glide that referenced this issue Nov 22, 2017
Cuts ~40% off of frame rendering times on API 23 emulators and devices.

Progress towards bumptech#2471.
sjudd added a commit to sjudd/glide that referenced this issue Nov 22, 2017
sjudd added a commit to sjudd/glide that referenced this issue Nov 22, 2017
These small additive changes might save ~5-10% decoding some GIFs,
depending on the vagaries of the particular file.

Progress towards bumptech#2471.
sjudd added a commit to sjudd/glide that referenced this issue Nov 22, 2017
It adds complication and data copying and doesn’t seem to make much
of a difference in multiple low/high end devices or emulators. If it
seems like I/O might be a blocking issue, we can try just copying the
file into a byte[] in the ByteBufferGifDecoder the same as we do for the
stream decoder and wrapping it in ByteBuffer.

Progress towards bumptech#2471.
sjudd added a commit to sjudd/glide that referenced this issue Nov 22, 2017
@sjudd
Copy link
Collaborator

sjudd commented Nov 22, 2017

I've pushed a series of (hopefully) safe changes. Referencing the intermediate arrays in local variables seems to make a really large difference on API 23 devices, though I don't see the same difference on API 26. The rest of the changes are much smaller improvements.

I have a couple of larger fixes including automatic pausing of detached animatables and an option to cache color table indices for all GIF frames (one byte per changed pixel per frame vs four bytes per pixel for all pixels per frame if we cache the entire frame). I may hold off on those until 4.5 to give us some more time to test.

GIFs are difficult to test and there's lots of expected but not to spec behavior that can make things that seem like they ought to be safe unsafe.

@delacrixmorgan
Copy link

Realised that we are looking at the wrong place on this GIF issue. Problem isn't with Glide, but it how Android is recognising the.gif file. Try this.

Add this url into your Glide load, and it will load nicely. Although, in reality it's 7.2MB.
https://media.giphy.com/media/3o6Zt7YExBfE89p6Yo/giphy.gif

In fact, because the API that Giphy uses for that image was specify the content-type as image/gif. Thus, somehow made Android recognise.gif file and handles them respectively.

TLDR
Specifying content-type as image/gif will have your buttery smooth .gif. Simple indicator will be to enter your link in your browser and see whether it hosts the image on the page or prompt you to download.

  • If the .gif is hosted on the page, it'll work fine.
  • If the .gif prompted for a download, it'll have that lag we all have been dreading about.

@KimiChiu
Copy link

Hi,

I have the same problem too.
In Glide 3, we fix this problem by this way.

builder.setDiskCacheService(new FifoPriorityThreadPoolExecutor(4));
builder.setResizeService(new FifoPriorityThreadPoolExecutor(4));

But we can't found these APIs in Glide 4.

@Eggplant-Cui
Copy link

For me
I did some invesgate
Obviously this is related to hardware
I tested a high resolution gif (1920*1080 120 frames 867KB) on several devices
Perfect performance on:
XiaoMi 6 Qualcomm 845 published 2017
OnePlus 5 Qualcomm 845 published 2017
Normal performance on:
Samsung S5 Qualcomm 800 published 2014
Bad performance on:
Oppo R7 plus Qualcomm 615 published 2015

The test is not only on glide , i also try to play this gif with the default way the device offered.

But if i choose another gif (400*300, 7.2MB), it performance perfectly on all devices above.

So try to compress your gif or choose play it as movie will partly solve this problem.

Sorry for my poor English, I'll repeat my words in Chinese

gif动画帧率低的问题应该不只是glide的问题,各位如果能把设备信息和gif信息一起贴上来可能会更快的明确问题是关于设备还是这个库。
我的任务是为app添加开屏动画,动画尺寸是1080p,120帧,帧率60,文件大小867kb
在小米6,一加5上面完美播放
三星s5略有延迟,大概2.1-2.2秒才能播放完毕
oppo r7 plus 需要4-5秒才能播放完毕
而且调用系统相册播放gif也是相同的结果
而我换了一个400*300分辨率,7.2mb大小的gif文件,无论是用glide还是用系统的相册播放,都很流畅。所以我猜测这个问题应该是cpu解码gif的速度跟不上播放速度导致的

最终我的解决方案是用movie来播放gif,这样可能会导致丢帧,但是至少时间长度是一致的

@KimiChiu
Copy link

KimiChiu commented Apr 6, 2018

I tried this,

builder.setAnimationExecutor( GlideExecutor.newAnimationExecutor(4, GlideExecutor.UncaughtThrowableStrategy.DEFAULT) );
builder.setDiskCacheExecutor( GlideExecutor.newDiskCacheExecutor(4, "glideDiskCacheExecutor", GlideExecutor.UncaughtThrowableStrategy.DEFAULT) );
builder.setSourceExecutor( GlideExecutor.newSourceExecutor(4, "glideSourceExecutor", GlideExecutor.UncaughtThrowableStrategy.DEFAULT) );

But it still plays in slow motion in RecyclerView.
The ViewPager doesn't have this problem.
The test device is Nokia 6 with Android 8.

compileSdkVersion 27
buildToolsVersion '27.0.1'
minSdkVersion 19
targetSdkVersion 26

compile 'com.github.bumptech.glide:glide:4.6.1'
annotationProcessor 'com.github.bumptech.glide:compiler:4.6.1'
compile "com.github.bumptech.glide:okhttp3-integration:4.6.1"
compile 'com.squareup.okhttp3:okhttp:3.10.0'

@Svoka
Copy link

Svoka commented Apr 12, 2018

Any update on this?

@delacrixmorgan
Copy link

GIPHY wrote a blog post explaining the details of how Fresco handles GIF better and to quote the post.

Developers made it clear that performance can’t be improved, unless they rewrite their rendering engine from scratch.

https://engineering.giphy.com/giphy-android-app-and-fresco/

@idish
Copy link

idish commented Jan 24, 2019

Pretty major issue, this should be fixed somehow in the next release!

@skyfit2
Copy link

skyfit2 commented Mar 20, 2019

I have the same problem , i recomended change to Fresco , its more fast and complete compared to Glide

@takaoandrew
Copy link

@skyfit2 Do you know if Fresco allow playing GIFs from a url like Glide does?

@AndroidDeveloperLB
Copy link

@takaoandrew For the size of this library, it better be....

@nirukk52
Copy link

Adding crossfade on local image drawable worked for me.

Glide.with(context).load(stringImage).asGif()
   .crossFade().diskCacheStrategy(DiskCacheStrategy.SOURCE).into(postImage);

@andrewcking
Copy link

andrewcking commented May 5, 2019

Also experiencing this on most devices I have tested it on, from Galaxy s10 to nexus 5. It is much more subtle on higher end devices but is still noticeable.

@Zhuinden
Copy link

Zhuinden commented May 5, 2019

Have you tried with Glide 3.7.2?

@andrewcking
Copy link

andrewcking commented May 5, 2019

Wow..... just tried doing some rewrites to go back to 3.7.0 and gif performance dramatically improved (night and day difference). This makes me chuckle because they cited improved Gif performance as one of the reasons to upgrade to 4 (I started with 4). I have been sticking with Glide 4.2 because performance got a lot worse in the 4.3 update though I have been testing each version afterwards to see if it gets better and it hasn't.

Here is what I have found:
Glide 4.3-4.9: Terrible gif performance on all devices
Glide 4.2: Acceptable gif performance on most devices
Glide 3.7.0: Great gif performance (so far in my tests)

@AndroidDeveloperLB
Copy link

@andrewcking Can you please show a sample, so that I could see the difference?

@andrewcking
Copy link

andrewcking commented May 5, 2019

Visually? There are some examples above but here is what I am seeing in terms of performance difference between 3.7 and 4.9 download.zip

This is on a galaxy s10 displaying 4 low-res optimized gifs and 3.7 blows 4.9 out of the water.

@AndroidDeveloperLB
Copy link

@andrewcking I meant as projects, but visually I see on your sample that there is a difference...
How could it be so slow?
On which device and Android version have you tested it?

@andrewcking
Copy link

andrewcking commented May 5, 2019

I've tested on nexus 4,5,5x and galaxy s8,s10 and then also on OnePlus 6. It is noticeable on all devices at least for my use case. I don't know the android version of each device but it ranges from android 5 on the nexus 4 to android 9 on the galaxy devices. Note these gifs are all local on the device (not loading from the internet).

I don't have a project implementation I can share but my glide calls between 3 and 4 are pretty similar

3.7

Glide.with(mActivity).load(images.get(position))
        .crossFade()
        .placeholder(R.drawable.placeholder)
        .into(holder.image);

4.+

RequestOptions options = new RequestOptions()
         .placeholder(R.drawable.placeholder);
Glide.with(mActivity).load(images.get(position))
        .transition(withCrossFade())
        .apply(options)
        .into(holder.image);

@AndroidDeveloperLB
Copy link

AndroidDeveloperLB commented May 13, 2019

@andrewcking OK I've tested it myself on LG G5 with Android 8.

Attached sample project, using what you guys wrote.

MyApplication.zip

While I don't see much issue on how fluid it plays, here are the results in CPU usage via the profiler:

4.9.0:

image

3.7.0:

image

How did you perform the test?
I think it can get slower in some cases, which I'm not sure what they are.

@droidluv
Copy link

droidluv commented Jul 2, 2019

Wow was just wondering how good Glide performance was with gif's and this thread just opened my eyes, guess I'll jump onto the Fresco bandwagon for smooth gif playback

@AndroidDeveloperLB
Copy link

@droidluv Where exactly? Please show a sample showing the issue

@Zhuinden
Copy link

Zhuinden commented Jul 2, 2019

@droidluv technically, Glide 3.7.2 was ok

@droidluv
Copy link

droidluv commented Jul 3, 2019

@droidluv Where exactly? Please show a sample showing the issue

I don't have a sample anymore, I encountered a stutter/slowdown when my backend started sending a gif accidentally instead of an image, on a Galaxy On6, and I am using the latest version of Glide (4.9.0), I am hesitant to add Fresco though because of it's much larger size, but saw above that Fresco performed better than Glide with its native code usage, I'll try to generate samples soon enough to compare because a new requirement to support gif playback is incoming.

@AndroidDeveloperLB
Copy link

Can you please put a sample of the best Glide , the newest one, and of Fresco?

@droidluv
Copy link

@AndroidDeveloperLB I am attaching the videos below differentiating Fresco and Glide, this slowdown seems specific to only certain devices like I have encountered the Glide slowdown in two Samsung phones but works fine on everything else including other Samsung phones like the Galaxy S7, even though Fresco gives a uniform GIF experience throughout every device, Glide has better performance advantages when dealing with complex images and recyclerviews, like fresco doesn't even support PNG resizing (we can do some downsampling but..) when dealing with complex lists of images and gifs Glide wins hands down, I just switched back to Glide even though I might have to deal with slowed down GIFs in some devices

This comparison is between the newest glide and the latest version of Fresco

Glide and Fresco comparison.zip

@AndroidDeveloperLB
Copy link

@droidluv This is of the newest Glide, right?
And you also tried the version of Glide that works fine?
Can you please share the sample code too?

@droidluv
Copy link

@AndroidDeveloperLB Its on the latest Glide 4.9.0, I haven't tried the 3.x glide because I didn't want to go back to an older version, the code is just a basic vertical Recyclerview with horizontal list's of GIF's and PNG's, Also please do note my point, the slowdown happens only on CERTAIN devices, one such model is the Galaxy J7 Pro, with Android Pie(Android version 9) and OneUI 1.1 and is the stock OS, if you want I can try and generate logs from that device, if I could but I suppose the video should talk for itself, the other device was also a Samsung, a Samsung Galaxy A series device, I can get more info about that device as well if needed, and I'm fairly sure the slowdown is happening on some other devices as well, Fresco seemingly works smoothly everywhere though regarding GIF playback.

@AndroidDeveloperLB
Copy link

@droidluv Please share the project of Fresco.
I want to investigate it.

@mertceyhan
Copy link

mertceyhan commented Apr 22, 2020

I found a case. Gif is showing slowly when I using "wrap_content" for width and height of ImageView. There is no problem if I use with static width and height such as "80dp". Try this.

<androidx.appcompat.widget.AppCompatImageView
        android:id="@+id/imageViewLoadingGif"
        android:layout_width="80dp"
        android:layout_height="80dp" />

Also, Gif loader this (Glide 4.10.0);

 Glide
                    .with(this)
                    .asGif()
                    .load(R.raw.loading_animation)
                    .into(this)

@gmikhail
Copy link

I have similar problem with high frame rate GIFs (50fps). 30fps GIFs play as they should. For comparison - MIUI Gallery plays all GIFs smoothly.

Glide 4.13.2
Poco X3 NFC (Android 11)
GIF details: 50fps, 480x640px, 10 MB, looped

@cwaliimran
Copy link

Step 1. Make your gif height/width as small as possible, remove extra large background
Step 2. Imageview in XML must have static height/width (rather than 0dp/0dp in constraint layout), it will solve the problem

@smirza-pie
Copy link

None of the above solutions other than the following comment #2471 (comment)
Setting fixed height & width of the ImageView worked & resolves the issue of speed

@rastin-py
Copy link

Setting fixed height & width worked for me. Don't use wrap_content or 0dp in constraint layout.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests