ionic-team / ionic-framework

A powerful cross-platform UI toolkit for building native-quality iOS, Android, and Progressive Web Apps with HTML, CSS, and JavaScript.
https://ionicframework.com
MIT License
51.02k stars 13.51k forks source link

bug: Ion-image inside virtual scroll shows wrong image until new one loaded #19381

Closed jgermanis closed 3 years ago

jgermanis commented 5 years ago

Bug Report

Ionic version:

[x] 4.x

Current behavior:

When adding ion-image inside virtual scroll and scrolling it is showing old image for some time until the new image is loaded. gXngdrkfbg

Expected behavior:

Should not show wrong image, instead should be empty image until the image is loaded

Steps to reproduce:

Add virtual scroll and add image inside each item, then scroll trough to see wrong image displayed for short time.

Related code:

https://github.com/jgermanis/virtual-scroll-test

Other information:

Ionic info:

Scan0815 commented 5 years ago

the problem is on my site too with the virtual-scroll

omardoma commented 5 years ago

Facing the same issue here

Juanperezc commented 5 years ago

same problem

michael-roewin commented 4 years ago

I'm also experiencing the same behavior. Is there a solution for this?

SimonBrazell commented 4 years ago

Also experiencing this problem, it would be better if no image or a placeholder was displayed instead of the wrong image.

Seems virtual-scroll ion-img is still problematic... needs a workaround

michael-roewin commented 4 years ago

Hi guys,

The way I solved this issue is by not following the ionic guide wherein the ion-img should be used in ion-virtual-scroll. I used regular tags instead and they worked perfectly in the ion-virtual-scroll. There will only be a one time fetching of images from the http request(Assuming that the browser caches the images). After that, they will be stored in cache so it doesn't matter if they are re-rendered in the ionic virtual scroll several times.

austinhutchison commented 4 years ago

Wanted to +1 this issue. I quickly tried @michael-roewin's suggestion to use <img> instead of <ion-img> but it didn't seem to stop the image from the last DOM scroll staying in place until the new image is loaded.

In my mind there are two ways to address this

  1. It seems the virtual DOM elements are updated on scroll. If instead there were added and removed dynamically I think that would resolve the problem. Maybe this design is is a choice based on performance.
  2. If we must reuse the same DOM elements and update them with new data on scroll - then we should get some event where we can listen for when the item is out of view, then hide the image / replace with a skeleton placeholder etc.

It's not acceptable for me personally to have the images flash to the new image on load.

I'm pretty sure I will have to abandon virtual scroll and do some type of pagination.

michael-roewin commented 4 years ago

@austinhutchison I definitely agree with you, The ionic team should update the ion-virtual-scroll component and add/create an event where we can listen for when an item is out of view.

As for my solution, Our client really wanted to go with the virtual scroll functionality so I had no choice but to go with that approach. I did tell him about the drawbacks wherein the item image will stay in place until the new image loads.

If you are really required to use virtual-scroll then I guess using <img> tag would be a much better option then using the <ion-img> tag,

elvisgraho commented 4 years ago

Running in the same issue even by using locally stored images (no requests). Why this feature was pushed incomplete?

elvisgraho commented 4 years ago

To Fix this permanently:

  1. Use this: https://github.com/rintoj/ngx-virtual-scroller

  2. Do this in page where there is ion-content:

    @ViewChild(IonContent, {static: false}) ionContent: IonContent;
    
    ngAfterViewInit() {
    this.ionContent.getScrollElement().then(scrollElement => {
      this.importantElement = scrollElement;
    });
    }

    Now, you can use importantElement right away or store it in the service in case you need it in routes where there is no ion-content.

  3. Replace ion-virtual-scroll with the npm-plugin above.

    <virtual-scroller [parentScroll]='importantElement' #scroll [items]="helloItems">
      <div *ngFor="let item of scroll.viewPortItems">{{item}}</div>
    </virtual-scroller>

Bob IS your uncle.

Husnain-Asharf commented 4 years ago

How can i decrease scroll speed or limit scroll distance of list if user try to scroll fast. Any solution other than infinite-scroll. I am using ionic 5. Thanks

weathon commented 4 years ago

But I cannot use ion-img becuase it will cause all the images overlaping

austinhutchison commented 3 years ago

I revisited this issue and while it isn't a perfect fix, I can recommend a strategy that looks something like this:

  1. use a div (absolutely positioned) that acts as an overlay above an <ion-img> element
  2. set the div opacity as a variable declared in the ngOnInit() of the repeated virtual scroll component
    ngOnInit() {
    this.yourObject.overlayOpacity = 1
    }
  3. in the component template set the opacity [style.opacity]=yourObject.overlayOpacity
  4. use the (ionImgDidLoad) function to then set the opacity to 0 on the overlay div.

The template should look something like this

<YourComponent>
  <div class="overlay" [style.opacity]="yourObject.overlayOpacity"></div>
  <ion-img src="your-image" (ionImgDidLoad)="removeOverlay()"></ion-img>
</YourComponent>

You could do the same thing with z-index instead of opacity but this is the basic pattern that has worked for me and is visually a much better experience.

liamdebeasi commented 3 years ago

Thanks for the issue! With the release of Ionic 6 we will be deprecating ion-virtual-scroll in favor of JavaScript Framework solutions. As a result, we have a freeze on new development with the exception of critical bugs, such as security issues.

Using these new virtual scrolling solutions should provide a better developer experience, more performant app, and fewer bugs! We have created migration guides for the main 3 JavaScript Frameworks Ionic supports to make this migration easy for developers.

Migration for Angular users: https://ionicframework.com/docs/angular/virtual-scroll Migration for React users: https://ionicframework.com/docs/react/virtual-scroll Migration for Vue users: https://ionicframework.com/docs/vue/virtual-scroll

The documentation for ion-virtual-scroll still exists at https://ionicframework.com/docs/api/virtual-scroll.

ion-virtual-scroll will be removed in Ionic 7. Developers do not need to migrate off ion-virtual-scroll in order to upgrade to Ionic 6 or to continue using it in Ionic 4/5.

I am going to close this issue. Thank you!

ionitron-bot[bot] commented 2 years ago

Thanks for the issue! This issue is being locked to prevent comments that are not relevant to the original issue. If this is still an issue with the latest version of Ionic, please create a new issue and ensure the template is fully filled out.