graphqlpaginationrelaymodern

Relay style (cursor based) pagination and sudden jumps many pages forward?


I have an infinite (windowed) list that currently works with a cursor based pagination system.

The problem with my current approach is that users have to scroll to the bottom of the list, wait for results to load, scroll to the bottom again, and so on.

I would like to allow users to scroll to the middle of the list without having to download all the data in between.

I don't understand how can this be done following the Relay pagination recommendations.


Solution

  • What you're trying to do isn't really normal pagination and can't be achieved by just using the relay pagination spec. I'm also not aware of any standardized way of achieving this, which does make sense since how it should be done is very case specific. The spec doesn't limit adding any additional functionality though so here's coupple options for you:

    Add a new parameter:

    Add a new parameter which you can use to skip to the certain point you want:

    itemConnection(skip: 10000) {
      edges {
        node {
          ...
        }
      }
    }
    

    This option is more simple assuming you already now how many items the feed contains.

    Return list of cursors to jump to

    Your server could return list of "jump points" which you can use with your scrolling. This has the benefit that you can include some additional information which you can show to the user when they're scrolling. Your return type for the connection could be something like:

    type ItemConnection {
      pageInfo: ItemConnectionPageInfo
      edges: [ItemConnectionEdge]
      totalCount: Int
      skipPoints: [SkipPoint]
    }
    
    type SkipPoint {
      cursor: String
      # This combined with totalCount could be used to calculate which point to start loading from
      # Alternatively some kind of percentage would work as well
      position: Int
      # Not mandatory, but could be used to show the date to where the user is scrolling to
      date: String
    }
    

    You wouldn't need to return all cursors there, I'd assume 100-200 would be good but you could experiment with that. Now when the user scrolls long discances you can use either method to avoid loading everything in between. After that you can use normal relay pagination when user scrolls up/down. If user starts to scroll long distances you can go back to step 1 by using either of these methods.