안녕하세요! 2채널 호환 게시판 시스템 「つゔぁいちゃんねる(2ch.biz)」 개발 기록, 제36회입니다.
지난번(제35회)에는 기능 추가 과정에서 사라졌던 과거 로그 묘사 메서드를 완전히 복원하고, 단위 테스트를 통해 견고한 가드라인을 구축했습니다.
묘사 파이프라인의 안전성이 확보됨에 따라, 우리의 관심은 다시 **'UI/UX의 극한 튜닝'**으로 향하게 되었습니다.
이번에 초점을 맞춘 것은 채팅 UI 설계에서 예로부터 엔지니어들을 고민하게 해온 **'발언 시간(타임스탬프)을 어떻게 표시할 것인가?'**라는 문제입니다.
매 줄마다 시간을 표시하면 화면이 글자와 숫자로 가득 차서 시끄럽습니다. 하지만 시간이 전혀 나오지 않으면 '이거 몇 분 전 발언?'이라며 혼란스러워집니다. 본고에서는 이 모순적인 두 가지 요구사항을 CSS 호버 애니메이션과 HTML 표준의 title 속성의 절묘한 조합으로 스마트하게 해결해 온 과정을 설명합니다!
실시간 채팅 UI를 설계할 때, 시간 표시에는 크게 두 가지 유파가 존재합니다.
| 유파 | 장점 | 단점 |
|---|
| A. 전 행 상시 표시형 (예: Discord, Slack) | 언제 발언되었는지 항상 알 수 있음 | ・'14:23:45'가 화면에 수십 개나 나열되어 시각적 노이즈가 심함 ・화면 폭이 좁으면 본문 영역을 압박함 |
| B. 완전 비표시/간헐 표시형 (예: LINE 일부, 옛 IRC) | 화면이 깔끔하여 본문에 집중할 수 있음 | ・'지금 몇 시 몇 분 발언에 응답하고 있는지' 알기 어려움 ・대화의 템포감(5분 전인지 30초 전인지)을 놓치기 쉬움 |
우리가 목표로 한 것은 IRC (XChat / HexChat)의 전통을 계승하는 **'극도로 간소화된 투 컬럼 레이아웃(발언자 | 본문)'**입니다.
아무리 아름다운 투 컬럼을 구현했더라도, 줄 맨 앞에 시간을 고정 표시해 버리면 미니멀리즘의 매력이 반감되어 버립니다.
그래서 우리가 도출한 결론은 **'평소에는 존재감을 지우고, 알고 싶다고 생각하는 순간에만 살짝 떠오르는 호버 타임스탬프'**였습니다.
사용자가 시간을 알고 싶은 상황에는 '대략 몇 시 몇 분인지 알고 싶다'는 라이트한 케이스와, '몇 년 몇 월 며칠, 초 단위까지 엄밀하게 알고 싶다'는 두 가지 종류가 있습니다.
이들을 만족시키기 위해, 다음의 이중 구조를 채택했습니다.
-
제1층: CSS 페이드인 버블 (: HH:mm:ss) - 마우스가 행 위를 통과하는 순간, 오른쪽 끝에 방해되지 않는 반투명한 등폭 글꼴로 페이드인합니다.
-
제2층: 네이티브 title 속성 (YYYY/MM/DD HH:mm:ss) - 행 전체에 title 속성을 부여함으로써, 마우스를 멈춘 독자에게 OS 네이티브의 완전 일시 시간 툴팁을 제공합니다.
-
행 전체에
이 UI를 구현하는 데 있어 가장 공들인 부분은 **'스크롤 성능을 전혀 희생시키지 않는 것'**입니다.
메시지가 수천 줄 흐르는 채팅 화면에서, 행마다 mouseenter / mouseleave의 JavaScript 이벤트 리스너를 등록하면, 가비지 컬렉션(GC)과 메모리 소비가 폭발하여 화면 스크롤이 버벅거리게 됩니다.
따라서 동적 표시 전환은 100% 순수한 CSS :hover만으로 완결시켰습니다.
메시지 행(일반 발언, 파일 공유 카드, 시스템 메시)을 묘사할 때, 타임스탬프 요소와 title 속성을 정적으로 단 한 번만 삽입합니다.
// 시간 포맷 유틸리티
function formatFullDateTime(ts) {
const d = new Date(ts);
...
}
/* 메시지 행의 기준 스타일 (상대 배치) */
.p2p-msg-row {
position: relative;
...
[!TIP]
pointer-events: none;을 지정해 둠으로써, 팝업된 타임스탬프 위에 커서가 겹쳐도 본문 텍스트 선택이나 URL 클릭이 방해받지 않도록 배려했습니다.
일반 발언 메시지뿐만 아니라, 채팅 로그에 흐르는 모든 요소에 통일된 UX를 적용했습니다.
- 일반 텍스트 발언: 오른쪽 끝에
HH:mm:ss
출현합니다. -
P2P 파일 공유 카드: 파일 카드에 마우스를 올리면, 파일이 공유된 정확한 시각이 팝업됩니다. -
시스템 메시지: 출입실 안내나 호스트 이양 통지(* Alice가 입장했습니다 등)에서도 유사하게 시간을 확인할 수 있습니다.
자동 테스트 및 실제 브라우저에서의 조작 검증을 진행했습니다.
-
시각적 노이즈의 극적인 감소:- 평상시 화면은 아름다운 백금색(또는 칠흑색)의 텍스트 로그만으로 구성되어, 숫자에 의한 압박감이 완전히 사라졌습니다.
-
60fps의 부드러운 스크롤:- CSS 트랜지션만으로 완결되었기 때문에, 수천 줄의 로그를 한 번에 고속 스크롤해도 FPS 저하는 전혀 관측되지 않아 매우 경쾌한 조작감을 유지합니다.
-
직관적인 시간 확인:- '저 발언 언제였더라?'라고 생각하는 순간 마우스를 살짝 올리는 것만으로, 밀리초 단위의 끊김 없이 시간이 떠오르는 기분 좋은 경험을 실현했습니다.
'평소에는 보이지 않게 하다가, 필요할 때 스마트하게 응답한다'――.
CSS의 힘을 최대한 활용한 호버 타임스탬프를 통해 XChat의 기능적 아름다움과 현대적인 인터랙션을 고차원적으로 융합시킬 수 있었습니다.
하지만 UI 개선에 잠시 안도했을 새도 없이, 다음 릴리스 직전에 또다시 트러블이 발생합니다.
JavaScript 파일을 경량화하고 최적화하는 과정에서, 단 한 글자의 구문 오류(Syntax Error)가 유입 된 것입니다.
그 결과, 게시판 전체 스크립트의 파싱이 중단되었고, P2P 채팅의 시작 버튼은 물론이고 게시판 일부 UI까지 영향을 받아 침묵해 버렸습니다.
순수 JavaScript 운영에서의 디버깅 함정, 그리고 캡슐화(IIFE)를 통한 방벽 구축 기록입니다.
실제 서비스: https://2ch.biz/