
어드민 데이터 테이블을 전면 개편하면서 3일 연속 풀타임으로 매달린 적이 있습니다. 솔직히 시작 전에는 "레이아웃 좀 다듬으면 되겠지"라고 가볍게 봤는데, 막상 들어가 보니 그게 아니었습니다. 1만 행 이상의 데이터를 다루는 운영자들이 하루에도 수백 번씩 들여다봐야 하는 화면이라는 걸 실감하고 나서야, 데이터 테이블이 단순한 레이아웃 작업이 아니라는 걸 깨달았습니다.
왜 데이터 테이블이 UX에서 가장 어려운 과제인가
국내 B2B SaaS 어드민을 보면 공통적인 패턴이 있습니다. 페이지 하단에 단순 페이지네이션, 좁은 컬럼, 작은 폰트. 이 조합이 운영자의 실수율을 가장 빠르게 높이는 구조라고 제 경험상 확신합니다. 틀린 행을 수정하거나, 금액을 잘못 읽거나, 상태값을 오인하는 일이 반복되는 환경의 공통점이 바로 이것이었습니다.
데이터 테이블 UX에는 게슈탈트 근접성(Gestalt Proximity) 원리가 강하게 작동합니다. 게슈탈트 근접성이란 가까이 배치된 요소들을 사람이 하나의 그룹으로 인식하는 심리 법칙으로, 행 간격과 열 간격이 조금만 틀어져도 사용자가 데이터를 잘못 묶어서 읽는 원인이 됩니다. 그래서 행 높이를 넉넉하게 확보하는 것은 미적인 선택이 아니라 인지 오류를 줄이는 설계 결정입니다.
여기에 밀러의 청킹(Miller's Chunking) 개념도 함께 봐야 합니다. 밀러의 청킹이란 사람이 한 번에 처리할 수 있는 정보 단위가 7±2개로 제한된다는 인지심리학 이론으로, 한 화면에 컬럼을 무한정 늘리면 사용자가 정보를 처리하지 못하고 그냥 눈으로 훑고 지나치게 됩니다. 제가 기본 컬럼을 12개로 두고 사용자가 컬럼 가시성을 직접 토글할 수 있게 한 것도 이 이유에서였습니다. 모든 데이터를 보여주는 것이 목표가 아니라, 지금 이 사람이 봐야 할 데이터를 골라서 보여주는 것이 목표여야 합니다.
헤더 설계도 생각보다 훨씬 중요합니다. 일반적으로 헤더를 일반 행과 비슷하게 디자인하는 경우가 많은데, 실제로 써보니 사용자가 헤더를 데이터 행으로 혼동하거나, 클릭해서 정렬이 되는지조차 모르는 경우가 많았습니다. 정렬 가능하다는 신호를 회색 아이콘으로만 줄 경우 클릭률이 현저히 떨어집니다. 저는 헤더 클릭 시 화살표 아이콘과 함께 해당 컬럼의 배경색을 1단계 진하게 처리했더니 사용자들이 정렬 기능을 훨씬 적극적으로 활용하기 시작했습니다.
1만 행 환경에서 드러나는 설계의 진짜 한계
일반론 수준의 데이터 테이블 가이드가 놓치는 지점이 있습니다. 바로 대용량 데이터 환경에서의 렌더링 성능입니다. 제가 직접 다뤄본 케이스에서 단일 페이지 무한 스크롤 방식으로 1만 행을 불러올 경우, 스크롤 성능이 평균 22fps까지 떨어졌습니다. 60fps가 사용자가 부드럽다고 느끼는 기준인데, 22fps는 눈에 띄게 버벅이는 수준입니다.
이 문제를 해결하기 위해 적용한 방식이 가상 스크롤(Virtual Scroll)과 서버 사이드 페이지네이션의 하이브리드 구조였습니다. 가상 스크롤이란 화면에 실제로 보이는 행만 DOM에 렌더링하고, 스크롤로 벗어난 행은 메모리에서 제거하는 기법입니다. 이 구조를 적용한 후 스크롤 성능이 22fps에서 60fps로 회복됐고, 메모리 점유율도 1.2GB에서 380MB로 떨어졌습니다. 이건 단순한 수치 개선이 아니라 운영자가 하루 종일 쓰는 화면에서 브라우저가 버벅이다가 뻗는 사태를 막는 것이었습니다.
AG Grid와 TanStack Table을 비교하면서 흥미로웠던 지점이 있었습니다. 행 높이가 고정일 때는 두 라이브러리 모두 가상 스크롤을 깔끔하게 처리하는데, 행 높이가 콘텐츠에 따라 달라지는 다이내믹 행(Dynamic Row Height) 환경에서는 처리 방식이 갈립니다. AG Grid는 행 높이를 사전에 추정해서 스크롤 위치를 계산하고, TanStack Table은 렌더링 후 측정값을 반영하는 방식을 씁니다. 이 차이가 특정 케이스에서 스크롤 점프 현상으로 이어질 수 있어서, 선택 전에 반드시 실제 데이터로 테스트해보는 것을 권합니다.
필터 구조도 신경 써야 하는 부분입니다. 저는 컬럼 헤더 우측에 펀넬 아이콘을 두는 컬럼 단위 진입점과, 상단에 통합 필터 바 두 가지 진입점을 함께 제공했습니다. 활성화된 필터는 테이블 위에 칩 형태로 표시하고, X 버튼으로 개별 제거할 수 있도록 했습니다. 이렇게 하면 사용자가 현재 어떤 조건으로 데이터를 보고 있는지 한눈에 파악할 수 있고, 필터를 실수로 켜둔 채 데이터를 잘못 해석하는 상황을 방지할 수 있습니다.
UX 설계 기준과 관련해 참고할 만한 자료를 보면, Material Design의 Data Tables 가이드와 Atlassian Design System의 Dynamic Tables는 권장 컬럼 수와 인라인 편집 패턴에서 미묘하게 다른 입장을 취하고 있습니다(출처: Material Design). 두 시스템 모두 공신력 있는 가이드지만, 어느 쪽이 정답이라기보다는 자신의 사용자 컨텍스트에 맞게 조정하는 것이 현실적입니다.
실전에서 체감한 개선 포인트 정리
가장 즉각적인 효과를 체감한 변경 사항은 인라인 편집 패턴이었습니다. 기존에는 별도 편집 모달이나 사이드 패널로 이동하는 방식이었는데, 셀 더블클릭으로 편집 진입, Enter로 저장, Esc로 취소하는 인라인 편집(Inline Editing) 패턴으로 바꾼 뒤 편집 작업 평균 시간이 14초에서 6초로 줄었습니다. 인라인 편집이란 별도 화면 전환 없이 테이블 셀 자체를 클릭해서 값을 수정하는 방식으로, 컨텍스트 이동 없이 데이터를 수정할 수 있어 운영자의 집중을 끊지 않습니다.
날짜 형식도 사소해 보이지만 실수를 부르는 요소입니다. 숫자로만 된 날짜 표기는 월과 일이 헷갈리기 쉽습니다. Jan, Feb처럼 월 이름을 약어로 표기하면 이 혼동이 사라집니다. 상태값 표시도 텍스트만 쓰면 긴급도를 파악하기 어렵습니다. 상태 칩(Status Chip)을 도입하면 색상과 형태로 긴급도를 구분할 수 있어 운영자가 눈으로 훑는 속도가 빨라집니다.
피츠의 법칙(Fitts's Law)도 테이블 설계에서 자주 놓치는 원칙입니다. 피츠의 법칙이란 클릭 가능한 영역이 클수록, 그리고 목표와의 거리가 가까울수록 사용자가 더 빠르게 조작할 수 있다는 법칙으로, 검색 필드나 버튼이 너무 작으면 클릭 시도 자체를 포기하게 만듭니다. 검색 필드를 충분히 넓게 두고, 아이콘 버튼의 클릭 영역을 시각적 크기보다 넉넉하게 설정하는 것이 중요한 이유입니다.
접근성 측면에서도 데이터 테이블은 별도의 고려가 필요합니다. 키보드 내비게이션과 스크린리더 헤더 셀 처리가 제대로 되지 않으면 접근성 기준을 충족하지 못합니다. WCAG(Web Content Accessibility Guidelines)에 따르면 테이블의 헤더 셀에는 scope 속성을 명시해야 하며, 이것이 스크린리더 사용자가 컬럼과 행의 관계를 올바르게 이해하는 데 필수적입니다(출처: W3C WCAG).
실전에서 우선순위를 잡고 싶다면 다음 순서로 접근하는 것을 권합니다.
- 행 높이와 헤더 구분: 가장 빠르게 가독성을 올릴 수 있는 출발점
- 정렬·필터 피드백: 사용자가 현재 상태를 파악할 수 있어야 실수가 줄어듦
- 숫자 우측 정렬과 날짜 약어 표기: 데이터 비교 오류를 줄이는 세부 조정
- 가상 스크롤 또는 서버 사이드 페이지네이션: 데이터량이 많아질수록 필수
- 접근성 마크업: 키보드 내비게이션과 스크린리더 지원이 완성도를 결정
데이터 테이블은 "완성"이 없는 화면입니다. 운영자가 매일 붙어 있는 도구인 만큼, 한 번 개선하고 끝나는 게 아니라 실제 사용 패턴을 계속 지켜보면서 다듬어야 합니다. 제가 이번 개편에서 얻은 가장 큰 교훈은, 성능 수치보다 운영자가 "이제 이 화면이 좀 믿어진다"고 말할 때의 무게감이었습니다. 그게 데이터 테이블 UX가 궁극적으로 도달해야 할 지점이라고 생각합니다.