Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lazy image loading with GWT

Jquery and other JS frameworks got many lazy image loading plugins, code-blocks. Which basically loads image when its visible in visible area of browser.

How to achieve it in GWT? I am aware that I can use jquery plugin in GWT, but Looking for native GWT solution.

So, I would like to do something like this..

LazyImage img = new LazyImage("load.gif","original_thumb.png")
scrollContainer.add(img); //scrollContainer is added to ScrollPanel
like image 259
Nachiket Avatar asked Mar 03 '11 06:03

Nachiket


People also ask

How do you implement a lazy-load image?

Lazy Loading Techniques for images. Images on a webpage can be loaded in two ways - using the <img> tag, or using the CSS `background` property. Let's first look at the more common of the two, the <img> tag, and then move on to CSS background images.

Can I use lazy loading images?

In Chrome 76 onwards, you can use the loading attribute to lazy-load images without the need to write custom lazy-loading code or use a separate JavaScript library. Let's dive into the details.

How do you test for lazy loading images?

If you want to test the execution of lazy loading, I can recommend that you clear your browser's cache and try reloading. In Chrome's Developer Console (F12), you can tweak the speeds and simulate modem speeds. Hit F12 -> Network tab -> Change the "No throttling" dropdown . Choose a slower speed to experiment.

Does lazy loading improve performance?

Today, lazy loading is widely used in web applications to improve application performance. It helps developers reduce loading times, optimize data usage and improve the user experience. However, overusing lazy loading can affect the application performance negatively.


2 Answers

Basically the solution from Jason. Except that the image itself decides when it needs to get loaded.

class LazyImage extends Image {

    private String fUrl;
    private ScrollPanel fParent;
    private boolean fLoaded;

    public LazyImage(String url, ScrollPanel parent) {
        fUrl = url;
        fParent = parent;
        attachHandlers();
    }

    private void attachHandlers() {
        fParent.addScrollHandler(new ScrollHandler() {

            @Override
            public void onScroll(ScrollEvent event) {
                int imageTop = getAbsoluteTop();
                int viewport = fParent.getAbsoluteTop() + fParent.getOffsetHeight();
                if (imageTop < viewport) {
                    lazyLoad();
                }
            }
        });
    }

    @Override
    public void setUrl(String url) {
        fLoaded = false;
        fUrl = url;
    }

    public void lazyLoad() {
        if (!fLoaded) {
            super.setUrl(fUrl);
            fLoaded = true;
        }
    }
}
like image 136
z00bs Avatar answered Oct 01 '22 02:10

z00bs


This should be somewhat straightforward. There are two basic steps.

1.) Create a widget that can be told to load an image programatically instead of automatically showing it. Store the URL of the image to load and have a method to load it.

public class LazyImage extends Image {
  private String url;

  // Override behavior of base Image constructor to just store the URL.
  public LazyImage(String url) {
    this.url = url;
  }

  public void lazyLoad() {
    super.setUrl(url);
  }
}

This can be used in much the same way as the regular Image class, except you will need to call lazyLoad() to actually get the image to appear.

2.) Detect when the image is needed using a ScrollPanel.

I'm not totally sure of the code for this off the top of my head, but it will basically boil down to comparing the image's location vs. the scroll panel's scroll position. If the scroll position >= the image's distance from the top of the scroll panel, call lazyLoad() and the image will appear.

I haven't tried any of this code out, it's just a sketch of something that should work. Feel free to ask questions or give feedback if it works/doesn't work for you.

like image 33
Jason Hall Avatar answered Oct 01 '22 02:10

Jason Hall