Today I Learned

날짜별 업무 및 학습 회고입니다. 매일 무엇을 했고, 무엇을 배웠는지 기록합니다.

2026년 10월

2026-10-01

'관련 테스트만 돌린다'는 그래프를 못 믿을 때 전체로 돌아가는 규칙이 있어야 안전하다

병렬 작업마다 전체 단위 테스트를 반복하던 푸시 훅과 PR CI를 변경 기반 선택 실행으로 바꾸면서, 기준점을 추측하지 않는 법과 삭제·전역 설정 변경을 전체 실행으로 보내는 규칙을 정리한 기록

  • 변경 기반 테스트 선택은 import 그래프의 정확도에 기대는 최적화라서, 그래프를 못 믿는 변경(삭제·이름 변경·전역 설정)은 전체 실행으로 흘려보내는 규칙이 같이 있어야 한다
  • 기준점은 추측하지 않는다. CI는 PR의 base 커밋, 푸시 훅은 Git이 넘겨 주는 이전 원격 SHA를 쓰고, 새 브랜치는 사람이 명시하게 한다

2026년 9월

2026-09-25

두 키를 같이 두 번 눌렀더니 한 방향으로만 대시했다 — 첫 이벤트에서 확정하지 않기

브라우저가 동시에 누른 키도 keydown 이벤트로 따로 보내기 때문에, 첫 키에서 방향을 확정하면 두 번째 키가 합쳐지지 못한다는 것과 50ms 수집창으로 푼 방법

  • 브라우저는 동시에 누른 키도 키마다 keydown 이벤트를 따로, 순서를 가지고 보낸다
  • 첫 키 이벤트에서 결과를 확정하면 이벤트 사이에 프레임이나 시뮬레이션 스텝이 끼는 순간 두 번째 키가 합쳐지지 못한다

2026년 7월

2026-07-31

구형 브라우저 호환은 babel 하나가 아니다 — 문법·폴리필·조건 로드·스모크의 다층 계약

5년 넘은 구형 브라우저에서 앱이 통째로 죽는 버그를 고치며 배운 것 — 여러 기능이 동시에 죽으면 하이드레이션을 의심하고, 문법 다운레벨과 런타임 폴리필을 분리하고, 폴리필은 feature-detect로 옛 브라우저에만 로드하고, 스모크는 실제 인터랙션을 실행한다

  • 여러 UI 기능이 동시에 죽으면 개별 버그가 아니라 하이드레이션/번들 파싱 같은 공통 근본원인을 먼저 의심한다
  • 문법 다운레벨(babel)과 런타임 API(폴리필)는 별개 층이다 — 트랜스파일러는 문법은 바꿔도 없는 함수는 만들지 않는다
2026-07-07

중첩 UI 리렌더를 O(1)로 줄이기 — read-model과 렌더 카운트 테스트

불변 트리 에디터에서 한 줄만 고쳐도 전체가 다시 그려지는 문제를, 테스트로 먼저 고정한 뒤 정규화 projection과 id별 구독으로 행·컨테이너 리렌더를 줄인 과정

  • 불변 트리 patch는 조상도 새 ref를 받아 props 내리면 O(depth) 리렌더 — 정규화 entry + id별 구독으로 O(1)로 줄일 수 있다
  • entry 캐시는 입력 ref가 아니라 출력 값-동등으로 안정화해야 하고, 외부 store sync는 setState 직전 choke point에서 동기 실행한다
2026-07-05

블록 에디터 순서·협업·키보드 계약

fractional ordering, optimistic rebase, IME defer, keyboard undo 위임, scoped popover, Jest ESM shim 등 범용 패턴 정리

  • sibling 순서는 integer index보다 fractional position key + neighbor anchor + tie-break가 concurrent insert에 유리하다
  • optimistic UI는 inverse patch 없이는 rebase할 수 없고, remote seq가 merge 권위여야 한다