Skip to content

[3팀 이정우] Chapter 1-2. 프레임워크 없이 SPA 만들기#58

Open
JungWoo0203 wants to merge 6 commits into
hanghae-plus:mainfrom
JungWoo0203:main
Open

[3팀 이정우] Chapter 1-2. 프레임워크 없이 SPA 만들기#58
JungWoo0203 wants to merge 6 commits into
hanghae-plus:mainfrom
JungWoo0203:main

Conversation

@JungWoo0203
Copy link
Copy Markdown

@JungWoo0203 JungWoo0203 commented Jul 17, 2025

과제 체크포인트

배포 링크

https://jungwoo0203.github.io/front_6th_chapter1-2/

기본과제

가상돔을 기반으로 렌더링하기

  • createVNode 함수를 이용하여 vNode를 만든다.
  • normalizeVNode 함수를 이용하여 vNode를 정규화한다.
  • createElement 함수를 이용하여 vNode를 실제 DOM으로 만든다.
  • 결과적으로, JSX를 실제 DOM으로 변환할 수 있도록 만들었다.

이벤트 위임

  • 노드를 생성할 때 이벤트를 직접 등록하는게 아니라 이벤트 위임 방식으로 등록해야 한다
  • 동적으로 추가된 요소에도 이벤트가 정상적으로 작동해야 한다
  • 이벤트 핸들러가 제거되면 더 이상 호출되지 않아야 한다

심화 과제

Diff 알고리즘 구현

  • 초기 렌더링이 올바르게 수행되어야 한다
  • diff 알고리즘을 통해 변경된 부분만 업데이트해야 한다
  • 새로운 요소를 추가하고 불필요한 요소를 제거해야 한다
  • 요소의 속성만 변경되었을 때 요소를 재사용해야 한다
  • 요소의 타입이 변경되었을 때 새로운 요소를 생성해야 한다

과제 셀프회고

기술적 성장

코드 품질

학습 효과 분석

과제 피드백

리뷰 받고 싶은 내용

@JungWoo0203
Copy link
Copy Markdown
Author

현재 구현된 Diff알고리즘의 시간복잡도는 O(N) 인데, 이를 더 효율적으로 하는 방법이 무엇이 있을까요?

@realstone2
Copy link
Copy Markdown

결국 다 돌아야되니까 다른 방법이 없지 않으려나요?
뭘해도 최소 O(N) 이상 아닌가...? 싶네요.

@tooth-is-silver
Copy link
Copy Markdown

https://calendar.perfplanet.com/2013/diff/
리액트 diff알고리즘 자체가 O(N)이어서 더 효율적일 수 없을거같아요!

@hyojin-k
Copy link
Copy Markdown

Map을 활용해서 key 기반으로 하면 O(1)도 가능하다고 하네요?

function diffChildren(parent, newChildren, oldChildren) {
  const oldKeyMap = new Map();

  // 1. 이전 노드들을 key 기준으로 Map에 저장
  oldChildren.forEach((child, index) => {
    if (child.key !== undefined) {
      oldKeyMap.set(child.key, { child, index });
    }
  });

  const usedOldIndexes = new Set();

  // 2. 새로운 자식 노드 순회
  newChildren.forEach((newChild, newIndex) => {
    let oldMatch = null;

    if (newChild.key !== undefined) {
      const match = oldKeyMap.get(newChild.key);
      if (match) {
        oldMatch = match.child;
        usedOldIndexes.add(match.index);
        oldKeyMap.delete(newChild.key);
      }
    } else {
      // fallback: index 순서로 비교 (key가 없을 경우)
      if (newIndex < oldChildren.length && !usedOldIndexes.has(newIndex)) {
        oldMatch = oldChildren[newIndex];
        usedOldIndexes.add(newIndex);
      }
    }

    updateElement(parent, newChild, oldMatch, newIndex);
  });

  // 3. 사용되지 않은 이전 노드는 제거
  oldChildren.forEach((oldChild, oldIndex) => {
    if (!usedOldIndexes.has(oldIndex)) {
      updateElement(parent, null, oldChild, oldIndex);
    }
  });
}

이상 챗지피티였습니다.

@realstone2
Copy link
Copy Markdown

근데 Map을 셋팅하면서 O(N)을 실행하지 않나요!? ㅋㅋ

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants