8

I want to render many(about 1000) components and I am displaying them through aura:iteration in another aura:iteration. This is causing me performance issues. I want to display only 10 records at an instance, and on scroll of mouse, load next 10 and so on...It should be like the way feed is loaded on a FB page or chatter. Any ideas how can this be implemented?

markup:

<aura:iteration var="outerListElement" items="{!v.listOfLists}">
   <tr>
      <aura:iteration var="singleEntry" items="{outerList">
       <td >
           <div class="slds-truncate">
               <c:newComponent singleEntry="{!singleEntry}" outerListElement="{!outerListElement}" attr1="{!v.attr1OfParent}">
           </div> 
       </td>
      </aura:iteration>
   </tr>
</aura:iteration>

1 Answer 1

17

You could implement infinite scrolling similar to what I did for my custom Lightning Component that renders data table.

In your main component's render.js file attach a listener to the window.onscroll event. As the user scrolls down the page the below code detects once the user has neared the bottom then can take action. In my example, I invoke helper.getNextPage( component );

For your purposes, you might start with {!v.listOfLists} holding only 10 elements to start with, and then as the user scrolls you append more elements to the list.

Note, the below solution stores the JavaScript interval id in v.setIntervalId attribute of the component so that the polling can be stopped when the component is unrendered / destroyed.

({
    afterRender : function( component, helper ) {

        this.superAfterRender();

        // this is done in renderer because we don't get
        // access to the window element in the helper js.

        // per John Resig, we should not take action on every scroll event
        // as that has poor performance but rather we should take action periodically.
        // http://ejohn.org/blog/learning-from-twitter/

        var didScroll = false;

        window.onscroll = function() {
            didScroll = true;
        };

        // periodically attach the scroll event listener
        // so that we aren't taking action for all events
        var idOfSetInterval = window.setInterval( $A.getCallback( function() {

            // Since setInterval happens outside the component's lifecycle
            // We need to check if component exist, only then logic needs to be processed
            if ( didScroll && component.isValid() ) {

                didScroll = false;

                // adapted from stackoverflow to detect when user has scrolled sufficiently to end of document
                // http://stackoverflow.com/questions/4841585/alternatives-to-jquery-endless-scrolling
                if ( window['scrollY'] >= document.body['scrollHeight'] - window['outerHeight'] - 100 ) {
                    helper.getNextPage( component );
                }

            }

        }), 1000 );

        // Save the id.We need to use in unrender to remove the setInterval()
        component.set( "v.setIntervalId", idOfSetInterval );
    },

    unrender: function( component, helper ) {

        this.superUnrender();

        // Since setInterval() will be called even after component is destroyed
        // we need to remove it in the unrender
        window.clearInterval( component.get( "v.setIntervalId" ) );
    }
})
4
  • 3
    I have updated the answer with code to 1) check for component valid before the calling the getNextPage() since setInterval() is async. 2) To Remove the same in the unrender, since scope of setInterval() is different from the component's.
    – Praveen
    Commented Dec 22, 2016 at 14:14
  • @Doug Ayers : Thanks for you solution I am using it extensively. I had a problem in it though that renderer is catching horizontal scroll as well and executes helper.getNextPage in above code. This behaviour is happening in salesforce classic and salesforce service console and not in one.app. Do you have any clue about why this could be happening?
    – Sarang
    Commented Jan 31, 2017 at 4:55
  • I made it work. Edited the code with same.
    – Sarang
    Commented Feb 1, 2017 at 7:12
  • Does this still work? I'm am having trouble getting the event to fire. Commented May 20, 2019 at 4:34

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .