어느 디자이너의 집착: Giscus 댓글창 Layout Shift(CLS) 완벽 해결기
남들은 안 보는 1px의 오차와 0.1초의 깜빡임. Iframe 로딩 시 발생하는 푸터 널뛰기와 이질감을 디자이너의 눈으로 잡아내고 CSS Grid로 완벽하게 통제한 과정.
전 세계 어디서든 유저의 '로컬 자정'을 기준으로 리더보드를 리셋하려면, 기존 데이터를 지우는 대신 '날짜별 버킷(Bucket)'을 만들고 클라이언트의 현지 날짜를 서버가 검증(±24시간 이내)하여 보여주는 방식이 가장 안전하고 효율적입니다.

듀오링고 하시는 분 계세요?
저는 매일매일 해요. 근데 어느날 비행기를 타고 뉴욕에 갔는데 랭킹이 그대로인 거예요. 제 스트릭이 깨재지도 않았고 리그 순위도 그대로고. 시간대가 완전히 바뀌었는데도 말이죠!
신기해서 한참 생각했어요. 어떻게 한 거지?
그러다가 글로우트리스에 데일리 리더보드를 만들면서 똑같은 문제를 맞닥뜨렸어요. 매일 자정에 리셋되는 리더보드인데, 문제는 ‘자정’이 어디 기준이냐는 거예요. 서울 자정? 뉴욕 자정? UTC 자정?
정답은 내 기준 자정이예요. 내가 어디에 있든 상관없이.
가장 간단한 방법은 매일 UTC 자정에 리더보드를 싹 지우는 거예요. 근데 그렇게 하면 서울 사람은 오전 9시에 리셋되고, 뉴욕 사람은 전날 저녁 7시에 리셋돼요. ”매일 순위가 바뀌는 리더보드 느낌이 전혀 없어요.
그럼 시간대마다 따로 리셋하면 어떨까요? 전 세계 시간대가 38개예요. 38개 리더보드를 따로 관리하는건 너무 복잡하고, 서울 리더보드에 뉴욕 사람이 없는 이상한 상황도 생겨요.
더 좋은 방법이 있었어요.
리더보드를 지우는 대신 날마다 새 리더보드를 만드는 거예요.
glowtris-daily-2026-06-04 ← 어제
glowtris-daily-2026-06-05 ← 서울 기준 오늘
glowtris-daily-2026-06-06 ← 뉴욕 기준 오늘
접속할 때 본인 기기의 현지 날짜를 서버에 보내요.
const localDate = `${d.getFullYear()}-${String(d.getMonth()+1).padStart(2,'0')}-${String(d.getDate()).padStart(2,'0')}`
fetch(`/api/leaderboard?date=${localDate}`)
서버는 그 날짜로 된 리더보드를 보여줘요. 자정이 지나면 날짜가 바뀌고, 자연스럽게 새 리더보드가 보여요. 예전 리더보드는 지우지 않아도 돼요. 그냥 안 보일 뿐이에요.
맞아요, 이론적으로는 어제 날짜를 보내서 예전 리더보드에 점수를 올릴 수 있어요.
function safeClientDate(raw) {
const utc = new Date().toISOString().slice(0, 10)
if (!raw || !/^\d{4}-\d{2}-\d{2}$/.test(raw)) return utc
// UTC 오늘과 1일 이상 차이나는 날짜는 거부
return Math.abs(new Date(raw) - new Date(utc)) <= 86400000 ? raw : utc
}
그래서 서버에서 간단하게 막아뒀어요. 전 세계에서 UTC와 가장 많이 차이나는 시간대가 +14시간(키리바시)이에요. 그래서 하루 이상 차이나는 날짜가 오면 그냥 거부해요. 합법적인 시간대는 전부 통과되고, 이상한 건 차단돼요.
Redis 키는 결국 만료시켜야 해요. 처음엔 26시간으로 설정했는데, 시간대를 고려하면 부족했어요.
서울(UTC+9) 사람이 어떤 날 리더보드를 처음 쓰는 시간, 그리고 샌프란(UTC-12) 사람이 같은 날 리더보드를 마지막으로 쓰는 시간 차이가 최대 약 50시간이에요. 그래서 TTL을 52시간으로 설정했어요.
서버는 자신의 UTC 시간을 유저에게 강요하지 않아요. 유저 기기의 현지 날짜를 믿고 따를 뿐이예요.
서울에서 자정 직전에 플레이하고, 비행기를 탄 다음 뉴욕에 내려요. 현지 시간으론 14시간이 지났고 다시 '어제'로 돌아왔네요?. 기기가 다시 어제 날짜를 보내기 때문에, 연속 기록이 끊기지 않고 어제 리더보드에서 계속 경쟁하게 되어요.
서버는 본인의 시간을 신경 쓰지 않아요. 오직 '내 기준의 자정'이 항상 자정이 될 수 있도록 보장해 줄 뿐이죠.
무료 네온 블록 퍼즐. 설치 없이 웹에서 바로 즐기세요!
남들은 안 보는 1px의 오차와 0.1초의 깜빡임. Iframe 로딩 시 발생하는 푸터 널뛰기와 이질감을 디자이너의 눈으로 잡아내고 CSS Grid로 완벽하게 통제한 과정.
군대 연등시간에 깃허브 퍼블릭 레포지토리에 보안 키를 올렸던 아찔한 경험과 그로부터 배운 교훈을 솔직하게 공유합니다.
군대에 있는 디자이너가 아이패드와 휴대폰으로 AI를 이용해 브라우저 게임을 만들었습니다. 그리고 Reddit에 올리자마자 테트리스 커뮤니티에서 산산조각이 났죠. 그 과정에서 배운 것들, 망한 것들, 그리고 왜 그게 오히려 중요했는지에 대한 솔직한 이야기입니다.