두 요소 스크롤 동기화
const box1 = document.getElementById('box1')
const box2 = document.getElementById('box2')
let isSyncing = false
function syncScroll(source, target, sourceWidth, targetWidth) {
const ratio = source.scrollLeft / (source.scrollWidth - sourceWidth)
target.scrollLeft = ratio * (target.scrollWidth - targetWidth)
}
box1.addEventListener('scroll', () => {
if (!isSyncing) {
isSyncing = true
syncScroll(box1, box2, 1280, 640)
isSyncing = false
}
})
box2.addEventListener('scroll', () => {
if (!isSyncing) {
isSyncing = true
syncScroll(box2, box1, 640, 1280)
isSyncing = false
}
})
isSyncing 플래그로 무한 이벤트 루프 방지
네트워크를 가정하고 캐시를 끼워맞추지 말고, 처음부터 로컬을 본진으로. UI는 항상 로컬(IndexedDB)을 보고, 서버는 동기화 대상으로 내려간다.
캐시는 “네트워크가 1순위”라는 전제 위에 덧대는 임시방편 — 무효화·로딩 상태·페이지네이션이 전부 거기서 파생된다. 로컬을 본진으로 뒤집으면 그 파생 문제들이 통째로 사라지고 “동기화” 하나로 응축된다.
신선했던 지점은 이게 all-or-nothing이 아니라 난이도가 단계적으로 점프한다는 것:
- 읽기 전용 = 재다운로드만. 충돌 없음. 지금 당장 가능.
- 쓰기 = optimistic + outbox로 대부분.
- 사용자별 분산 = 여기서부터 분산 시스템(Git 모델).
→ 읽기 전용 앱이면 오늘 시작할 수 있다.