HTML є найпоширенішим підходом для відображення даних у вигляді таблиць, і це має сенс, оскільки HTML надає вичерпну модель форматування, щоб ви не вигадували велосипед.
Ця стаття орієнтована на технічних лідерів, які тихо оцінюються за погану продуктивність інтерфейсу користувача. Неможливо бути більш прямолінійним :)_
Усе це чудово, проте можуть виникнути проблеми при відображенні великих або потенційно великих обсягів даних:
- Велика кількість вузлів DOM може уповільнити продуктивність
- Велика кількість вузлів DOM може призвести до помітних витрат на переробку (reflow)
Ви і ваш розкішний Macbook M3, можливо, не відчуєте болю, але для користувача з пристроєм з низькими характеристиками це може стати справжнім випробуванням.
З часом кожна велика програмна організація з популярними веб-додатками стикається з цією проблемою, або важким шляхом, або легким.
Потім відбувається зустріч з дизайнером та фронтенд-розробниками, що призводить до:
- Очищення коду для зменшення кількості вузлів DOM та дорогих CSS-правил
- Обмеження або усунення анімацій
- Обмеження або усунення можливості прокручування для користувачів
Серйозні проекти з HTML мають багато обмежень, і як розробник, ваші інструменти профілювання стають вашими найкращими друзями.
Тепер, ви можете вирішити проблему з "великою кількістю вузлів DOM", реалізувавши рішення для віртуалізації списку, яке дозволяє завантажувати великі обсяги даних у пам'ять, при цьому рендериться лише частина DOM, що відповідає вікну користувача, схоже на occlusion culling в відеоіграх.
Незважаючи на віртуалізацію вашого списку елементів, ви все ще можете зіткнутися з проблемою переробки (reflow), через що анімації можуть стати ривками.
Будьмо відвертими, HTML та CSS давно потребують заміни, але наразі нам доводиться працювати з тим, що маємо.
Я не прихильник жертвувати UX через технологічні обмеження. У нас є Canvas 2D і WebGL, а також контекст WebGPU на горизонті. Обмеження цих технологій не є технічними, а швидше обумовлені тим, що талановитих спеціалістів для роботи з GPU в вебі дуже мало. Three.js допомагає в цій сфері, але загалом це ще дуже маленький світ.
Тож що ми можемо зробити?
Колись мені розповіли історію про людину, яка заплатила $2к за сайт, який виявився просто веб-сторінкою, а весь інтерфейс був лише jpeg зображенням.
Гаразд, припиняйте сміятися :), це і є передова стратегія UI, яку я обговорюю.
Отже, що ми можемо винести з цього в реальному контексті:
Переваги:
- Низька кількість вузлів: Зображення можуть значно зменшити кількість вузлів на сайті.
- Знижений рефлоу: Зображення не є ідеальними, але вони значно краще справляються з рефлоу, ніж вкладені дерева DOM.
- Можна генерувати: Ви можете генерувати зображення в браузері на льоту за допомогою canvas або offscreen-canvas, використовуючи BlobURL.
- Низьке споживання пам'яті: Зображення, такі як jpg, png, webp і avif, використовують менше пам'яті, ніж будь-яка кількість вузлів DOM, яку вони можуть замінити.
Вони також використовують менше пам'яті, ніж інтерфейс Canvas.
- Браузери
Недоліки:
- Неінтерактивні
- Погана доступність
- Відсутність можливості вибору даних
- Потрібна висока роздільна здатність для різних співвідношень пікселів або масштабування
Залежно від вашого випадку, ви можете повернутись до епохи PlayStation 1 і усунути білатеральне фільтрування текстур, використовуючи image-rendering для пікселізованих зображень.
Стратегія для плавного відображення великих таблиць даних
3D-трансформації CSS створюють шари композиції для відображення DOM на швидкостях GPU.
Єдине, що не повністю уникає перерисовування (reflow) в усіх випадках і інколи призводить до поганої якості рендерингу, коли елементи перебувають в нерухомому стані (не враховуючи моменти, коли вони рухаються).
Але можна застосувати таку стратегію для створення псевдокомпозитного шару, щоб замінити великі табличні дані під час руху:
- Отримання даних та рендеринг через offscreen-canvas: Використання нативного canvas (полотно) не є занадто складним, якщо розуміти, що контекст canvas є станом (stateful). Також можна використовувати щось на кшталт html2canvas (цей проект більше не підтримується).
- Рендеринг полотна у зображення чи зображення: Використовуйте BlobURLs і замінюйте складний DOM UI на зображення, створюючи своєрідну підробку 🙂
- Інтерактивний DOM-накладення: Потрібно створити інтерфейс, який буде накладатися на частину даних, що зараз у видимій області. Цей наклад буде поступово зникати під час анімацій чи прокручування, а потім знову з'являтися, коли перехід завершиться.
Хоча HTML накладення має бути схожим на зображення, дані, які воно містить, не повинні бути ідеальними, оскільки насправді зображення в основному буде видно під час зміни розміру, прокручування або анімації.
Чи варто це робити і чи підходить для вашого додатку?
Як завжди, це залежить. Це точно надмірно для помірної кількості даних, тому я категорично не раджу використовувати цей підхід для типових застосунків чи звітів.
Це слід використовувати лише тоді, коли ви стикаєтеся з проблемами продуктивності, але також потрібно враховувати витрати на розмір зображень.
Припустимо, у вас є 10 зображень формату avif, кожне розміром 2000 x 1000 пікселів, які ви плануєте використовувати для сценаріїв з даними в русі. Незважаючи на стиснення, кожне зображення займатиме 8 МБ пам'яті, що дає в результаті 80 МБ довгострокової пам'яті купи (BlobURLs зазвичай зберігаються в купі). Для порівняння, еквівалентні DOM-елементи (DOM nodes) займатимуть набагато менше місця, можливо близько 1 МБ, з відхиленнями.
У вищезазначеному сценарії, 80 МБ буде згенеровано, а не завантажено через HTTP.
Це розумно, особливо коли врахувати, що популярні додатки, як Instagram і Twitter, часто значно перевищують цю кількість, коли мова йде про зображення.
Підсумки
Це набагато амбіційніше, ніж віртуалізація списків, і в деяких аспектах є своєрідною віртуалізацією списків. Кінцевий результат має дозволити користувачеві насолоджуватися плавним користувацьким досвідом, при цьому створюючи ілюзію того, що тисячі чи мільйони DOM-елементів (DOM nodes) пролітають через сторінку.
Подумайте про це як про "Nanite для HTML-даних" але ще простіше і зрозуміліше
— Julien
Перекладено з: Rendering Large Tabular Data in the Browser