Pagination, also known as paging, is the process of dividing a document
into discrete pages, either electronic pages or printed pages.
Pagination can be handled client-side or server-side. Server-side pagination
is more common. Client-side pagination can be used when there are very few records
to be accessed, in which case all records can be returned, and the client can use
JavaScript to view the separate pages. By using AJAX, hybrid server/client-side
pagination can be used, in which Javascript is used to request the subsequent
page which is loaded and inserted into the Document Object Model via AJAX.
Server-side pagination is appropriate for large data sets providing faster
initial page load, accessibility for those not running Javascript, and complex
view business logic.
https://en.wikipedia.org/wiki/Pagination
— Wikipedia
Client-side pagination means that the server will return all the
results that match some search criteria and the client will under the hood
display them in chunks called pages. That just a trick to help the
user focus on a subset of the results.
Additionally, the client may let the user filter the results or apply
different ordering rules etc.
For sure, if you are the back-end software engineer implementing a system
like that is a much simpler implementation and less work for you.
On the other hand, server-side pagination means that the client will request
the server only the data that it will display. The burden of implementing
the pagination logic is now split both to client and server sides with
the server-side pulling most of the weight.
Here is an example of how Google and others let the user navigate between the
pages of the result data:
In this article I will talk to you about server-side pagination
and try to convince you why always you should go for it.
I think the first time I have considered implementing server-side
pagination was during a university web development course where we
had to build a Question and Answer website, something like a simplified
StackOverflow.
I think inspired partially by Twitter
I would like to have the main page
load the questions dynamically as the user would scroll down.
From the server perspective there is no actual difference regarding
how the client decides to represent the data.
The client is free to implement pages such as the Google results,
9gag, Twitter or whatever.
This worked out beautifully back then and actually since then it seemed to me that
this was the best way to implement pagination. I thought that it would
be natural for everyone to implement the pagination in the server-side
but as I later found it actually wasn’t!
A few years later I was working in a professional environment.
There was an application developed and considered finished by some other
team. It was in the process of being penetration tested before being
deployed to production.
The pen test has failed and it was up to my team to find out what was going wrong.
The outcome of the pen test was that some requests were timing out.
Probably the pen test flagged these requests as potential
for DoS attack.
Very soon after exploring the application it was obvious to me what was
the problem.
The application had a classic search page with a criteria form that
would return the results and display them in pages. This page
would fetch all the data from the server and then implement the
pagination in the client-side.
For the purposes of the pen test there were generated test data. There
were around 12000 entries returned from that service.
The client took a minute or something to fetch all the data
and afterwards there were a few dozens of seconds until the browser be actually
able to display them properly.
Also, as far as I remember even actions like changing pages were slow
because the browser had so many elements in memory to handle.
Long story short, I have implemented server-side pagination and there
was a tremendous boost in performance. Everything worked beautifully.
App passed the pen test and went live on time with just a couple
of over-hours!
That was the first time I realized how important is the server-side
pagination. Something that I thought was naturally a better choice
and my preferred way of implementing pagination was now proven to
me that it was practically the best way.
What I didn’t know was how common that mistake was.
Path to success
From then on when I was implementing such a service I was providing
pagination if I had the chance. The implementation specifics could vary
but that didn’t really matter.
There were times where quality would decreased in favor of delivering faster.
In some cases there wasn’t enough time for implementing server-side pagination.
Then, I tried to make sure to communicate the dangers of not having pagination.
I made sure that this decision was documented and when the time did
came we could identify quickly the problem and pay our debt.
And the time always came. It varied depending how fast the data were growing.
It could be one month, six months or even years later. But it would eventually
happen.
I have faced the lack of server-side pagination from the client-side too.
Again I made sure to let the back-end team know.
Some times I heard as a response that we
could implement pagination in the browser if we wanted to. Of course this
was never the problem.
Other times I have heard that they know but they didn’t have
time at the moment or that they know but by their projections
this wouldn’t be a problem for the next X years.
That was ok. I sympathize the developers who make an educated choice
and trade-offs for good
reasons. I dislike when things happen by coincidence.
As you can seen not always my concerns were addressed.
I remember working in another app that was going to be used in an
internal network. This is a very common setting
for "enterprise" class applications.
The app was fetching all the data from the server in each search screen.
It also did provide client-side filtering on each column.
Fun fact was that the back-end service was implementing the pagination but it
wasn’t implemented in the client. The client did fetch everything
explicitly. (However, the service didn’t implement the filtering!)
I have raised my concerns but I was told that it was OK. The app was going
to be used in an internal network. It was going to work as expected
for a big number of results.
In some screens where the problem was more apparent the client was enforcing
a few search filters as mandatory in order to limit the results. This is not bullet
proof as again after some time it will cause problems.
And you know what. This app went to the clients for user acceptance
test. They have loaded it with lots of test data and boom!
Some requests as expected started to take too much time to respond!
Others started to fail some or all of the times with timeouts!
Of course the behavior varied depending on the network quality and load.
From our end we ensured the users that the app was working OK for a couple
dozen thousands of results. The users insisted that they got the error sooner.
The cause was simple and it was that their network was slower. We tested
the app in a fast local network. Their test server was in an internal
network but slower, with more hops and load than ours. So the delay
was bigger.
Lessons learned
I hope to have made you see by presenting you 2 real life experiences
how nasty can be the lack of server-side pagination. Be sure that I have
more similar stories to tell!
I am convinced for sure that the lack of server-side pagination
will always sooner or later be a problem. It is not a premature optimization.
It should be a standard.
It will start with the application getting slower. After some time and depending
the web server configuration it will start failing for some of the requests
and eventually for every request.
So, let’s have some bullet points we all like!
-
Server-side pagination for little data or a local network application
may be an optimization.
For many data or an internet facing application it will be a necessity.
-
If server-side pagination is not implemented make sure to communicate
the potential problems with the involved parties and document it so
in the future you will move faster when the problem rise.
-
Don’t think that it won’t happen to you. It will!
-
Test your application with sufficient number of data. Consider the
data that will be accumulated after a few years of operation and
then add some more. With properly implemented pagination it shouldn’t
matter and it should work the same regardless the volume.
-
When implementing server-side pagination take into consideration if
it is required to support filtering and/or ordering. This is absolutely
doable but could be tricky.
-
It takes a correct implementation from both the server and the client
in order to have this done correctly.
-
Set a sensible default pages size. I wouldn’t suggest setting a max
limit but you can consider it if you want to make sure that the
client will use the pagination.
-
Always make educated choices!
Epilogue
I hope I have been motivational enough and you will always implement
server-side pagination (or at least seriously consider it)!
It is actually not so hard if you have some experience with it. Modern
frameworks provide some of the required functionality and make the
process easier.
I could argue and discuss how a (possible) beautiful pagination API should
look like but this is
a matter of secondary importance.
Deliberately, I haven’t mentioned specific technologies, protocols etc.
in this article. It doesn’t matter. Server-side pagination may be
implemented in any language, framework or protocol and it should!
So, carry on and code responsibly!