조던 워크의 역발상

312025년 09월 15일4

팀원들의 회의적인 시선 앞에서, 조던 워크는 조금도 위축되지 않았다. 오히려 그의 눈빛은 도전을 즐기는 자의 총기로 빛나고 있었다. 성능이라는 거대한 벽. 모두가 그것을 넘을 수 없는 장애물로 여길 때, 그는 그것을 자신의 이론을 증명할 최고의 기회로 생각했다.

그는 기존의 접근 방식부터 다시 짚었다.
“우리가 지금까지 성능을 최적화하기 위해 사용했던 방법은 무엇이었습니까?”

맷이 대답했다. “변화가 발생하면, 그 변화에 영향을 받는 최소한의 DOM 요소만 정확히 찾아내서 업데이트하는 거죠. 백본의 이벤트 리스너가 바로 그 역할을 했고요.”

“맞습니다.” 조던이 동의했다. “그 방식은 ‘정밀 타격’과 같습니다. 변화의 원인과 결과를 정확히 추적해서 필요한 부분만 고치는 거죠. 하지만 우리는 이미 그 방식의 한계를 경험했습니다. 시스템이 복잡해지면, 무엇이 무엇에 영향을 미치는지 추적하는 것 자체가 버그의 온상이 되어버렸죠.”

그는 화이트보드에 ‘정밀 타격(Surgical Update)’이라고 적고 그 옆에 X자를 그었다.

“저는 완전히 반대의 생각을 했습니다.”

조던의 목소리에 힘이 실렸다.
“변화를 추적하는 복잡함을 감수하며 성능을 얻으려 하지 말고, 차라리 ‘변화를 추적하는 것’ 자체를 포기해 버리면 어떨까요?”

회의실에 있던 모두가 의아한 표정을 지었다. 변화를 추적하지 않고 어떻게 최적화를 한다는 말인가. 그것은 모순처럼 들렸다.

“생각해 보십시오. 개발자가 가장 힘들어하는 부분이 바로 이 ‘추적’입니다. 데이터 A가 바뀌면 UI 요소 B와 C를 업데이트해야 한다는 논리. 데이터 X가 바뀌면 요소 Y와 Z를 업데이트해야 한다는 논리. 이 논리들을 개발자가 직접 코드로 관리해야 하는 것이 모든 문제의 근원이었습니다.”

“우리의 새로운 모델, UI = f(data)는 이 추적의 책임을 개발자에게서 완전히 앗아갑니다. 개발자는 그저 데이터가 바뀔 때마다 함수 f를 호출해서 UI 전체의 새로운 모습을 선언하기만 하면 됩니다. 어떤 부분이 바뀌었는지에 대한 고민은 전혀 할 필요가 없죠.”

데이빗이 참지 못하고 끼어들었다. “하지만 그게 바로 성능 문제를 일으키는 원인이라고 우리가 계속 이야기하고 있지 않습니까, 조던!”

“그렇습니다.” 조던이 데이빗을 똑바로 바라보며 말했다. “개발자가 포기한 ‘변화 추적’의 책임을, 이제 라이브러리가 대신 짊어지는 겁니다. 그것도 훨씬 더 무식하고, 하지만 결과적으로는 훨씬 더 효율적인 방법으로요.”

그의 역발상은 이것이었다.
‘최소한의 변경’을 찾기 위해 복잡한 인과 관계를 추적하는 대신, 그냥 이전 상태의 스냅샷(Snapshot)과 현재 상태의 스냅샷을 통째로 비교해버리자는 것.

마치 틀린 그림 찾기 게임과 같았다.
이전 그림(Old UI Description)과 새 그림(New UI Description)을 나란히 놓고, 두 그림 사이의 다른 점을 모두 찾아내는 것이다. 이 작업은 오직 빠르고 가벼운 자바스크립트 객체들로만 이루어진 메모리 세상 안에서 이루어진다.

“이 ‘틀린 그림 찾기’가 끝나면, 우리는 변경이 필요한 부분들의 목록을 얻게 됩니다. ‘3층 창문이 바뀌었음’, ‘5층 현관문 색깔이 바뀌었음’ 같은 목록이죠. 그리고 나서야 비로소, 우리는 이 목록을 들고 느려터진 현실 세계, 즉 실제 DOM으로 가서 딱 한 번, 필요한 수술들을 일괄적으로 집도하는 겁니다.”

개발의 복잡성은 극도로 낮추고, 그 대가로 발생하는 계산의 복잡성은 기계(라이브러리)에 전부 떠넘긴다.
이것이 조던 워크의 대담한 역발상이었다. 그는 인간이 하기 힘든 ‘추적’이라는 일을 포기하는 대신, 컴퓨터가 가장 잘하는 ‘단순 비교’라는 작업을 선택한 것이다.

이제 남은 질문은 단 하나였다.
수천 개의 노드로 이루어진 두 개의 거대한 트리를 비교하는 이 ‘틀린 그림 찾기’ 알고리즘을, 과연 충분히 빠르게 만들 수 있는가? 그 해답에 프로젝트의 성패가 달려 있었다.