[9팀 박상수] Chapter 1-2. 프레임워크 없이 SPA 만들기 (2) - #50
Conversation
susmisc14
left a comment
There was a problem hiding this comment.
상수님! 요번주도 고생하셨습니다. 과제 항상 열심히 하시는 모습에 저도 많은 자극을 받고 있어요! 다음 3주차 과제도 지난 주차들 처럼 화이팅입니다!
| function flatten(arr) { | ||
| return arr.reduce((acc, val) => (Array.isArray(val) ? acc.concat(flatten(val)) : acc.concat(val)), []); | ||
| } |
There was a problem hiding this comment.
flatten 함수를 도입해서 중첩된 children 배열까지 유연하게 처리하도록 설계하신 점이 정말 돋보여요! 다만 임포트문 아래에 작성하는게 코드 가독성 면에서 좋을 것 같습니다!
| if (Array.isArray(vNode)) { | ||
| const fragment = document.createDocumentFragment(); | ||
| flatten(vNode).forEach((child) => { | ||
| if (child === null || child === undefined || child === false || child === true) return; | ||
| fragment.appendChild(createElement(child)); | ||
| }); | ||
| return fragment; | ||
| } |
There was a problem hiding this comment.
el.append(...elements)로 한번에 DOM에 추가하면 forEach 안에서 appendChild를 반복하는 것보다 브라우저 리페인트 횟수를 줄여 성능상 이점이 있다고 합니다. 이 방식도 함께 고려해보면 좋을 것 같아요!
| // 평탄화 함수: 중첩 배열을 1차원 배열로 | ||
| function flatten(arr) { | ||
| return arr.reduce((acc, val) => { | ||
| if (Array.isArray(val)) { | ||
| acc.push(...flatten(val)); | ||
| } else if (val !== null && val !== undefined && val !== false) { | ||
| acc.push(val); | ||
| } | ||
| return acc; | ||
| }, []); | ||
| } |
There was a problem hiding this comment.
flatten 함수를 createVNode 함수 밖으로 빼서 헬퍼 함수로 분리하면 createVNode가 호출될 때마다 함수가 새로 생성되는 것을 막을 수 있을 것 같아요.
| DELEGATED_EVENTS.forEach((eventType) => { | ||
| root.addEventListener( | ||
| eventType, | ||
| (e) => { | ||
| let target = e.target; | ||
| while (target && target !== root) { | ||
| const events = eventRegistry.get(target); | ||
| if (events && events[eventType]) { | ||
| for (const handler of events[eventType]) { | ||
| handler.call(target, e); | ||
| } | ||
| if (e.cancelBubble) return; | ||
| } | ||
| target = target.parentNode; | ||
| } | ||
| }, | ||
| eventType === "focus" ? true : false, // focus는 캡처링 필요 | ||
| ); | ||
| }); |
There was a problem hiding this comment.
focus 이벤트를 처리하기 위해 useCapture 옵션을 사용하신 부분과, handler.call(target, e)로 this 컨텍스트를 맞춰주시는 디테일이 좋은 것 같습니다!
| const events = eventRegistry.get(element); | ||
| if (!events[eventType]) { | ||
| events[eventType] = new Set(); | ||
| } |
There was a problem hiding this comment.
핸들러를 {[eventType]: Set} 구조로 관리해서 이벤트 탐색의 시간 복잡도를 O(1)로 만드신 점도 돋보입니다!
과제 체크포인트
배포 링크
https://parksangsoo.github.io/front_6th_chapter1-2/
기본과제
가상돔을 기반으로 렌더링하기
이벤트 위임
심화 과제
Diff 알고리즘 구현
과제 셀프회고
기술적 성장
가상돔이 실제로 어떻게 생성되고 어떻게 실제돔과 비교해서 바뀐 부분만 렌더링 하는 지 과정에 대해 좀 더 자세히 알게 된 거 같다
코드 품질
테스트 코드가 원하는 값을 받을 수 있도록 구현에만 초점 둬서 코드 품질에 대해서는 어떻게 하면 좋은 품질의 코드가 될 지 고민은 못해본 거 같다
학습 효과 분석
과제 피드백
리뷰 받고 싶은 내용
가상돔이 어떻게 작동하는 지에 대한 과제인 거 같아 뭘 리뷰를 받아야 할 지 모르겠습니다;