과제 체크포인트
배포 링크
https://jheejindev.github.io/front_6th_chapter1-2/
기본과제
가상돔을 기반으로 렌더링하기
- createVNode 함수를 이용하여 vNode를 만든다.
- normalizeVNode 함수를 이용하여 vNode를 정규화한다.
- createElement 함수를 이용하여 vNode를 실제 DOM으로 만든다.
- 결과적으로, JSX를 실제 DOM으로 변환할 수 있도록 만들었다.
이벤트 위임
- 노드를 생성할 때 이벤트를 직접 등록하는게 아니라 이벤트 위임 방식으로 등록해야 한다
- 동적으로 추가된 요소에도 이벤트가 정상적으로 작동해야 한다
- 이벤트 핸들러가 제거되면 더 이상 호출되지 않아야 한다
심화 과제
Diff 알고리즘 구현
- 초기 렌더링이 올바르게 수행되어야 한다
- diff 알고리즘을 통해 변경된 부분만 업데이트해야 한다
- 새로운 요소를 추가하고 불필요한 요소를 제거해야 한다
- 요소의 속성만 변경되었을 때 요소를 재사용해야 한다
- 요소의 타입이 변경되었을 때 새로운 요소를 생성해야 한다
과제 셀프회고
기술적 성장
- Virtual Dom은 객체 덩어리고 이 객체를 효율적으로 비교하면서 실제 DOM에 반영하는 것이 핵심
- Virtual Dom을 구현할 때 동적으로 변경되는 요소가 많아 이벤트 위임이 필수적
- 성능 최적화의 필요성
- 메모리 관리 위해 WeakMap 사용(container가 사라지면 자동으로 정리 - container 요소가 더 이상 필요 없어서 제거되면 WeakMap에 저장된 관련 Virtual DOM 데이터도 자동으로 가비지 컬렉션의 대상이 됨)
코드 품질
이벤트 리스너가 중복되는 문제를 겪었습니다. 원인 - 가상 DOM이 변경되면서 setupEventListeners가 실행될 때마다 새로운 이벤트 리스너가 추가되고 결과적으로 같은 이벤트에 대해 여러 개의 핸들러가 실행되면서 성능 저하와 의도치 않은 동작 발생하였습니다. 해결 - allEvents를 기반으로 등록된 이벤트 타입만 루프를 돌면서 리스너를 추가하도록 개선하였습니다. 그리고 이벤트 타입별 WeakMap을 저장하여, 각 요소에 대해 핸들러를 효과적으로 추적할 수 있도록 했습니다.
학습 효과 분석
-
최적화의 필요성 가상돔도 결국 자바스크립트 객체를 비교하는 작업 자체가 비용이기 때문에 컴포넌트를 적절히 분리하여 필요한 부분만 리렌더링 되게하기 상태관리를 효율적으로 하여 불필요한 리렌더링 방지하기등을 배울 수 있었습니다.
-
diff 알고리즘과 재귀 구조 구현
-
WeakMap
과제 피드백
프레임워크에 의해 추상화된 부분을 직접 구현해보면서 구조와 흐름을 알 수 있었습니다.
리뷰 받고 싶은 내용
현재 setupEventListeners 함수에서 최초 1회만 이벤트를 등록하고, 이후 addEvent를 통해 eventStore에 엘리먼트-핸들러 관계를 저장하고 있습니다. 이렇게 WeakMap + Set + 이벤트 위임 조합으로 구현한 구조가 메모리 관리나 성능 면에서 일반적으로 괜찮은 패턴인지, 개선할 만한 구조가 있는지 궁금합니다. 특히 bubbling 경로를 타고 올라가는 while 루프에서 이벤트 위임 대상이 너무 많아질 경우 퍼포먼스 문제가 생길 여지가 있을까요?
과제 피드백
안녕하세요 희진, 수고하셨습니다. 이번 과제는 React의 핵심 원리인 Virtual DOM과 diff 알고리즘을 직접 구현해보면서, 프레임워크가 어떻게 효율적인 렌더링을 수행하는지 체득하는 것이 목표였습니다. 특히 "Virtual DOM이 무엇인가"를 단순히 아는 것과 "Virtual DOM을 구현하기 위해 무엇이 필요한가"를 직접 경험하며 깊이 있는 학습을 하기 위한 방법을 익히는 것에 의의를 느꼈기를 바래요.
코드를 살펴보니 특히 이벤트 위임 시스템을 WeakMap + Set 조합으로 구현하신 점이 인상적입니다. 메모리 관리를 위해 WeakMap을 선택하고, 중복 이벤트 리스너 문제를 allEvents Set으로 해결한 것은 깊이 있는 이해를 보여줍니다. 또한 boolean 속성(checked, disabled 등)을 property로 처리하면서도 필요한 경우 attribute도 함께 관리하는 세심한 구현도 잘했습니다!
이렇게 직접 프레임워크의 핵심을 구현해보면 이론적 지식이 아닌 구조적 이해를 얻게 됩니다. 앞으로도 이런 방식으로 사용하는 도구의 원리를 파헤쳐보는 경험을 이어가시길 바랍니다. 너무 너무 잘했습니다!!
Q) 이벤트 위임 구조의 성능 및 개선점
=> 현재 구현하신 WeakMap + Set + 이벤트 위임 조합은 메모리 관리와 성능 면에서 매우 좋은 패턴입니다. React도 유사한 방식을 사용하고 있죠.
bubbling 경로의 성능 우려에 대해서는, 실제로 DOM 트리가 매우 깊거나(100+ depth) 이벤트가 매우 빈번한 경우(mousemove 등)가 아니라면 사실 큰 문제는 되지 않습니다. 이미 React도 그렇게 쓰고 있잖아요ㅎ
그리고 현재는 모든 이벤트 타입을 root에 등록하는데, 실제 사용되는 이벤트만 동적으로 등록방법도 한번 고민해보면 좋겠네요.
핵심 원리를 직접 구현하면서 원리를 이해하는 것이 더 선명해지는 경험을 했기를 바랍니다.
수고하셨습니다. 다음 주차도 화이팅입니다! :)