diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 4f9cb727..69522b05 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -13,38 +13,105 @@ #### 가상돔을 기반으로 렌더링하기 -- [ ] createVNode 함수를 이용하여 vNode를 만든다. -- [ ] normalizeVNode 함수를 이용하여 vNode를 정규화한다. -- [ ] createElement 함수를 이용하여 vNode를 실제 DOM으로 만든다. -- [ ] 결과적으로, JSX를 실제 DOM으로 변환할 수 있도록 만들었다. +- [x] createVNode 함수를 이용하여 vNode를 만든다. +- [x] normalizeVNode 함수를 이용하여 vNode를 정규화한다. +- [x] createElement 함수를 이용하여 vNode를 실제 DOM으로 만든다. +- [x] 결과적으로, JSX를 실제 DOM으로 변환할 수 있도록 만들었다. #### 이벤트 위임 -- [ ] 노드를 생성할 때 이벤트를 직접 등록하는게 아니라 이벤트 위임 방식으로 등록해야 한다 -- [ ] 동적으로 추가된 요소에도 이벤트가 정상적으로 작동해야 한다 -- [ ] 이벤트 핸들러가 제거되면 더 이상 호출되지 않아야 한다 +- [x] 노드를 생성할 때 이벤트를 직접 등록하는게 아니라 이벤트 위임 방식으로 등록해야 한다 +- [x] 동적으로 추가된 요소에도 이벤트가 정상적으로 작동해야 한다 +- [x] 이벤트 핸들러가 제거되면 더 이상 호출되지 않아야 한다 ### 심화 과제 #### Diff 알고리즘 구현 -- [ ] 초기 렌더링이 올바르게 수행되어야 한다 -- [ ] diff 알고리즘을 통해 변경된 부분만 업데이트해야 한다 -- [ ] 새로운 요소를 추가하고 불필요한 요소를 제거해야 한다 -- [ ] 요소의 속성만 변경되었을 때 요소를 재사용해야 한다 -- [ ] 요소의 타입이 변경되었을 때 새로운 요소를 생성해야 한다 +- [x] 초기 렌더링이 올바르게 수행되어야 한다 +- [x] diff 알고리즘을 통해 변경된 부분만 업데이트해야 한다 +- [x] 새로운 요소를 추가하고 불필요한 요소를 제거해야 한다 +- [x] 요소의 속성만 변경되었을 때 요소를 재사용해야 한다 +- [x] 요소의 타입이 변경되었을 때 새로운 요소를 생성해야 한다 ## 과제 셀프회고 ### 아하! 모먼트 (A-ha! Moment) + +- Virtual DOM의 본질 이해 +Virtual DOM이 단순히 "성능 최적화 도구"라고만 생각했는데, 실제로 구현해보니 "DOM 형태를 본뜬 객체 덩어리"라는 것을 체감했습니다. Real DOM의 구조를 JavaScript 객체로 표현하고, 변경사항을 메모리에서 먼저 계산한 뒤 최종 결과만 실제 DOM에 반영한다는 개념이 명확해졌습니다. 브라우저의 렌더링 과정은 HTML을 파싱하여 DOM Tree를 생성하고, CSS를 파싱하여 CSSOM을 만든 후, 이 둘을 결합하여 Render Tree를 구성합니다. 그 후 Layout 단계에서 각 요소의 정확한 위치와 크기를 계산하고, 마지막으로 Painting 단계에서 픽셀을 화면에 그립니다. Virtual DOM은 이 과정에서 변경사항을 일괄 처리하여 불필요한 reflow와 repaint를 최소화합니다. + + +- JSX 변환 과정에서의 발견 +JSX에서 {null}, {undefined}, {false}, {true} 같은 표현식들이 Babel 변환 시 그대로 children 배열에 포함된다는 것을 알게 되었습니다. React에서 false, null, undefined, true는 유효한 children이지만 실제로 렌더링되지 않습니다. 이로 인해 normalizeVNode에서 이런 값들을 적절히 필터링하지 않으면 예상치 못한 동작이 발생할 수 있다는 점을 배웠습니다. ### 기술적 성장 + +#### 기존의 알고 있던 개념 되짚어보기 +#### 브라우저의 workflow + - 기존의 알고 있었던 원리였지만 이번 과제를 통해서 더 자세히 개념을 정립할 수 있는 기회가 되었습니다 + - Dom Tree 생성 -> Render Tree 생성 -> Layout -> Painting + - Dom에 변화가 생기면 렌더트리를 재생성하고 (모든 요소들의 스타일 재계산) 레이아웃을 만들고 페인팅 하는 과정의 반복 + 참고 : https://velopert.com/3236 + +#### Virtual Dom +- 리액트의 기존 원리가 되는 가상돔에 대해 개념을 한번 더 짚고 나가는 기회가 되었습니다. +- 뷰에 변화가 있을 시 실제 DOM에 적용되기 전에 가상의 DOM에 먼저 적용시키고 최종적인 결과 값만 실제 DOM에 전달 => 브라우저 내에서 발생하는 연산의 양을 줄이면서 성능 개선 효과를 보임 + +#### 새로 학습한 개념 + +#### js로 dom을 생성 시 babel의 역할 +- JSX의 문법을 일반 js 함수 호출로 변환 => 코드를 텍스트로 변환하는 컴파일러! +```js + + // 변환 전 (JSX) +
Hello
+ + // 변환 후 (JavaScript) + createElement('div', { className: 'box' }, 'Hello') + +``` + +####배열의 평탄화 arr.flat(depth) +- depth: 중첩 배열 구조를 평탄화 할 때 사용할 깊이 값이자 생략 시 기본값 1 + ``` js + const arr = [1, 2, [3, 4, [5, 6]]]; + arr.flat(); // [1, 2, 3, 4, [5, 6]] + arr.flat(2); // [1, 2, 3, 4, 5, 6] + const arr2 = [1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]]; + arr2.flat(Infinity); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] +``` + +#### documentFragment +- 여러 DOM 요소들을 메모리에 일시적으로 저장할 수 있는 객체 +- 여러 개의 요소들을 모아두었다가 DOcumentFragment요소를 한번에 HTML DOM 에 추가 + +=> createElement와의 차이점이 몰까 생각해봤다. +=> 단일 요소를 생성할 때는 createElement, 여러 요소를 한번에 추가할 때는 documentFlagment를 사용해야 불필요한 reflow 과정을 없앨 수 있다. + + +####기존 지식의 재발견/심화 + +자료구조 선택의 중요성: 이벤트 핸들러 저장을 위해 처음엔 배열을 고려했지만, 중복된 이벤트 타입 처리가 필요해 Map으로 변경했습니다. 이전 회사에서 사용했던 HashMap 경험이 도움이 되었습니다. + +####구현 과정에서의 기술적 도전과 해결 +- updateElement의 children 타입 불일치 문제 + +문제: children의 타입이 다를 경우 교체 로직 누락, DOM 인덱스가 어긋나면서 잘못된 위치에 요소 추가 +원인: normalizeVNode에서 빈 문자열이 children 배열에 포함되어 메인 화면에 빈 상품카드가 생성됨 +해결: updateElement의 타입 비교 로직을 정규화하고, 동적 인덱스를 추적하는 방식으로 개선 + + +- 이벤트 리스너 중복 등록 문제 + +문제: 기존 이벤트 리스너를 제거하지 않아 중복 등록 발생 +해결: rootEventHandlers.clear()를 사용하여 기존 핸들러 제거 (효율성에 대한 의문은 남음) ### 코드 품질 + +####리팩토링이 필요한 부분 +- updateElement.js , createElement.js 부분이 조건문 사용이 많아 깔끔해 보이지가 않아서 어떻게 리팩토링을 할 지 고민중입니다. ### 학습 효과 분석 + +####가장 큰 배움이 있었던 부분 + +Virtual DOM의 동작 원리를 이론이 아닌 실제 구현을 통해 체득했습니다. Virtual DOM은 성능 향상을 위해 변경사항을 JavaScript 엔진의 메모리에서 먼저 계산하고, 최소한의 DOM 조작만 수행하여 비용이 큰 reflow와 repaint를 줄입니다. Stack OverflowTalent500 + +####추가 학습이 필요한 영역 + +Diffing 알고리즘의 최적화: 현재 구현은 기본적인 비교만 수행하는데, React의 Fiber 아키텍처처럼 더 효율적인 업데이트 방식에 대해 학습이 필요합니다. +이벤트 핸들러 관리: 현재 방식보다 메모리 효율적이고 성능이 좋은 패턴을 연구하고 싶습니다. +