Разбиение на страницы, также известное как пейджинг, представляет собой процесс разделения документа на отдельные страницы, либо электронные страницы, либо печатные страницы.

.…

Разбиение на страницы может выполняться на стороне клиента или на стороне сервера. Разбивка на страницы на стороне сервера более распространена. Разбивку на страницы на стороне клиента можно использовать, когда требуется доступ к очень небольшому количеству записей, и в этом случае все записи могут быть возвращены, а клиент может использовать JavaScript для просмотра отдельных страниц. Используя AJAX, можно использовать гибридную разбивку на страницы на стороне сервера/клиента, в которой Javascript используется для запроса следующей страницы, которая загружается и вставляется в объектную модель документа через AJAX.

Разбивка на страницы на стороне сервера подходит для больших наборов данных, обеспечивая более быструю начальную загрузку страниц, доступность для тех, кто не использует Javascript, и сложную бизнес-логику представления.

https://en.wikipedia.org/wiki/Разбивка на страницы
— Википедия

Разбивка на страницы на стороне клиента означает, что сервер возвращает все результаты, соответствующие некоторым критериям поиска, а клиент неявно отображает их в виде фрагментов, называемых страницами. Это просто уловка, чтобы помочь пользователю сосредоточиться на подмножестве результатов.

Кроме того, клиент может позволить пользователю фильтровать результаты или применять другие правила упорядочения и т. д.

Конечно, если вы являетесь инженером-программистом, реализующим подобную систему, это гораздо более простая реализация и меньше работы для вас.

С другой стороны, разбиение на страницы на стороне сервера означает, что клиент будет запрашивать у сервера только те данные, которые он будет отображать. Бремя реализации логики разбиения на страницы теперь разделено как на стороне клиента, так и на стороне сервера, при этом серверная сторона берет на себя большую часть нагрузки.

Вот пример того, как Google и другие позволяют пользователю перемещаться между страницами данных результатов:

В этой статье я расскажу вам о разбивке на страницы на стороне сервера и попытаюсь убедить вас, почему всегда вы должны использовать ее.

Мое первое знакомство с пагинацией

Я думаю, что впервые я подумал о реализации разбиения на страницы на стороне сервера во время университетского курса веб-разработки, где нам нужно было создать веб-сайт вопросов и ответов, что-то вроде упрощенного StackOverflow.

Я думаю, частично вдохновленный Твиттером, я хотел бы, чтобы главная страница загружала вопросы динамически, когда пользователь будет прокручивать вниз.

С точки зрения сервера нет реальной разницы в том, как клиент решает представлять данные.

Клиент может свободно реализовывать такие страницы, как результаты Google, 9gag, Twitter или что-то еще.

Тогда это прекрасно сработало, и на самом деле с тех пор мне казалось, что это лучший способ реализовать пагинацию. Я думал, что для всех было бы естественно реализовать разбиение на страницы на стороне сервера, но, как я позже обнаружил, на самом деле это было не так!

Несчастье с пагинацией

Несколько лет спустя я работал в профессиональной среде.

Было приложение, разработанное и считавшееся законченным какой-то другой командой. Он находился в процессе тестирования на проникновение перед запуском в производство.

Тест пера провалился, и моя команда должна была выяснить, что пошло не так.

Результатом проверки пера было то, что время ожидания некоторых запросов истекло. Вероятно, пен-тест пометил эти запросы как потенциальные для DoS-атаки.

Очень скоро после изучения приложения мне стало очевидно, в чем проблема.

В приложении была классическая страница поиска с формой критериев, которая возвращала результаты и отображала их на страницах. Эта страница будет получать все данные с сервера, а затем реализовывать разбиение на страницы на стороне клиента.

Для целей пентеста были сгенерированы тестовые данные. Из этой службы было возвращено около 12000 записей.

Клиенту потребовалась минута или что-то около того, чтобы получить все данные, а затем было несколько десятков секунд, прежде чем браузер смог их правильно отобразить.

Кроме того, насколько я помню, даже такие действия, как смена страниц, были медленными, потому что у браузера было так много элементов в памяти, которые нужно было обработать.

Короче говоря, я реализовал разбивку на страницы на стороне сервера, и производительность значительно возросла. Все работало прекрасно. Приложение прошло проверку на проникновение и было запущено в срок всего за пару часов!

Тогда я впервые понял, насколько важна нумерация страниц на стороне сервера. Что-то, что я считал, естественно, лучшим выбором, и мой предпочтительный способ реализации разбивки на страницы теперь доказал мне, что это практически лучший способ.

Чего я не знал, так это того, насколько распространена эта ошибка.

Путь к успеху

С тех пор, когда я реализовывал такой сервис, я предоставлял разбиение на страницы, если у меня была возможность. Специфика реализации может варьироваться, но это не имеет большого значения.

Были времена, когда качество снижалось в пользу более быстрой доставки. В некоторых случаях не хватило времени для реализации пагинации на стороне сервера. Затем я попытался сообщить об опасностях отсутствия нумерации страниц. Я позаботился о том, чтобы это решение было задокументировано, и когда пришло время, мы могли быстро определить проблему и погасить наш долг.

И время всегда приходило. Он варьировался в зависимости от того, насколько быстро росли данные. Это может быть месяц, полгода или даже годы спустя. Но в конце концов это произойдет.

Я столкнулся с отсутствием разбивки на страницы на стороне сервера и на стороне клиента. Я снова позаботился о том, чтобы сообщить об этом бэкенд-команде.

Несколько раз я слышал в ответ, что мы могли бы реализовать нумерацию страниц в браузере, если бы захотели. Конечно, это никогда не было проблемой.

В других случаях я слышал, что они знают, но в данный момент у них нет времени, или что они знают, но, по их прогнозам, это не будет проблемой в следующие X лет.

Это было нормально. Я сочувствую разработчикам, которые делают осознанный выбор и идут на компромиссы по уважительным причинам. Я не люблю, когда что-то происходит случайно.

Больше безумия с нумерацией страниц

Как видите, не всегда мои проблемы были учтены.

Я помню, как работал в другом приложении, которое планировалось использовать во внутренней сети. Это очень распространенная настройка для приложений класса «предприятие».

Приложение получало все данные с сервера на каждом экране поиска. Он также обеспечивал фильтрацию на стороне клиента для каждого столбца.

Забавным фактом было то, что серверная служба реализовывала разбивку на страницы, но не реализовывала ее в клиенте. Клиент извлек все явно. (Однако сервис не реализовал фильтрацию!)

Я высказал свои опасения, но мне сказали, что все в порядке. Приложение планировалось использовать во внутренней сети. Это должно было работать, как и ожидалось, для большого количества результатов.

На некоторых экранах, где проблема была более очевидной, клиент принудительно применял несколько поисковых фильтров, чтобы ограничить результаты. Это не является пуленепробиваемым, так как снова через некоторое время это вызовет проблемы.

И знаешь, что. Это приложение отправилось клиентам для приемочного тестирования пользователем. Они загрузили его большим количеством тестовых данных и бум!

Ответ на некоторые запросы, как и ожидалось, стал занимать слишком много времени! Другие начали терпеть неудачу некоторые или все время с тайм-аутами!

Конечно, поведение менялось в зависимости от качества сети и нагрузки.

Со своей стороны мы убедили пользователей, что приложение работает нормально, на пару десятков тысяч результатов. Пользователи настаивали на том, что они получили ошибку раньше.

Причина была проста: их сеть работала медленнее. Мы протестировали приложение в быстрой локальной сети. Их тестовый сервер был во внутренней сети, но медленнее, с большим числом переходов и нагрузкой, чем наш. Так что задержка была больше.

Уроки выучены

Я надеюсь, что показал вам 2 реальный жизненный опыт, насколько неприятным может быть отсутствие нумерации страниц на стороне сервера. Будьте уверены, что у меня есть еще подобные истории, чтобы рассказать!

Уверен точно, что отсутствие пагинации на стороне сервера всегда рано или поздно будет проблемой. Это не преждевременная оптимизация. Это должно быть стандартом.

Это начнется с того, что приложение станет медленнее. Через некоторое время и в зависимости от конфигурации веб-сервера он начнет давать сбой для некоторых запросов и, в конечном итоге, для каждого запроса.

Итак, давайте напишем несколько пунктов, которые нам всем нравятся!

  • Разбивка на страницы на стороне сервера для небольших данных или локального сетевого приложения может быть оптимизацией. Для многих данных или приложений с выходом в Интернет это будет необходимостью.
  • Если разбиение на страницы на стороне сервера не реализовано, обязательно сообщите о потенциальных проблемах заинтересованным сторонам и задокументируйте их, чтобы в будущем вы могли двигаться быстрее, когда возникнет проблема.
  • Не думайте, что с вами этого не произойдет. Будет!
  • Протестируйте свое приложение с достаточным количеством данных. Учитывайте данные, которые будут накапливаться через несколько лет эксплуатации, а потом добавляйте еще. При правильно реализованной нумерации страниц это не должно иметь значения и должно работать одинаково независимо от объема.
  • При реализации разбивки на страницы на стороне сервера учитывайте, требуется ли поддержка фильтрации и/или упорядочения. Это абсолютно выполнимо, но может быть сложно.
  • Для того, чтобы это было сделано правильно, требуется правильная реализация как со стороны сервера, так и со стороны клиента.
  • Установите разумный размер страниц по умолчанию. Я бы не советовал устанавливать предел max, но вы можете рассмотреть его, если хотите убедиться, что клиент будет использовать разбиение на страницы.
  • Всегда делайте осознанный выбор!

Эпилог

Я надеюсь, что я был достаточно мотивирован, и вы всегда реализуете разбивку на страницы на стороне сервера (или, по крайней мере, серьезно обдумываете это)!

На самом деле это не так сложно, если у вас есть некоторый опыт. Современные фреймворки предоставляют часть необходимой функциональности и упрощают процесс.

Я мог бы спорить и обсуждать, как должен выглядеть (возможный) красивый API пагинации, но это вопрос второстепенной важности.

Я намеренно не упомянул в этой статье конкретные технологии, протоколы и т.д. Это не имеет значения. Разбивка на страницы на стороне сервера может быть реализована на любом языке, фреймворке или протоколе, и так и должно быть!

Итак, продолжайте и соответственно кодируйте!

Первоначально опубликовано на https://masterex.github.io.