2주차 프로젝트

순수 자바스크립트만 사용하여 Virtual Dom을 사용하는 것이 이번 과제이다. 개념부터 이해하는게 너무 어려웠다. 

VirtualDOM을 사용하지 않으면 브라우저가 연산을 많이 해야해서 전체적인 프로세스를 비효율적으로 만든다. 트리를 재생성하고 레이아웃을 만들고 페인팅을 하는 과정을 줄여야하는데, 이것을 VirtualDOM이 해결해준다.
이러한 VirtualDOM을 이해하고 구현하는 것이 2주차 프로젝트의 목표이다.


문제

일단 각 함수들을 구현하는 것인데.. 개념 확립이 젤 문제였다. 각 함수들이 무슨 역할을 하는지도 몰랐기에 골치가 아팠다. 간단하게 설명하면 다음과 같다. 

1. createVNode : 가상 노드를 만드는 과정인데, 이 과정에서 평탄화작업을 해줘야한다. 평탄화 작업은 자식의 구조를 쫙 펼쳐서 일관되게 구성하는 작업이다. 
2. normalizeVNode는 사용자가 null, undefined, boolean 값, 문자열, 숫자, 또는 함수를 자식으로 전달할 수 있습니다. 이 모든 다른 타입들을 실제 DOM 요소로 변환하기 전에, 특정 규칙에 따라 통일된 VNode 형태로 만들어야 다음 처리 단계(예: createElement)가 혼란 없이 작동함. vNode가 다음 단계로 넘어가는 것을 방지하기도함.

3. createElement : VNode 객체를 인자로 받아, 실제 브라우저의 DOM 요소로 변환하여 생성하는 역할을 한다. 이 함수는 가상 DOM과 실제 DOM을 연결하는 역할을 한다.

4. eventManager : 이벤트 위임을 구현하는 데 사용됨. 각 개별 DOM 요소에 이벤트 리스너를 일일이 등록하는 것은 많은 메모리를 소비하고 성능을 저하시킬 수 있는데, 특히 목록처럼 수많은 자식 요소가 있는 경우 더욱 그렇다. eventManager는 최상위 root 요소에 단 하나의 이벤트 리스너를 등록하고, 실제 이벤트가 발생한 하위 요소를 event.target을 통해 식별하여 적절한 핸들러를 실행하게 한다.

5. renderElement : VNode를 실제 DOM에 렌더링하는 역할을 한다. 

시도

초기 렌더링 이슈가 문제가 있어 자꾸 화면이 이상하게 나왔다. 알고보니 createVNode와 createElement가 문제였다. 그 이후에 확인을 해보니, 정방향 diff 알고리즘 문제가 있었고, 렌더링을 리셋하지 않아 E2E 테스트중에 문제가 발생하였다.

 

결론 

이 후에 createElement에 정방향 diff 알고리즘을 추가하고, renderElement에 렌더링할 때 기존내용을 지우고 렌더링을 하니까 E2E테스트가 통과하였다. 

// createElement 일부

.....
if (newNode && oldNode && typeof newNode === "object" && typeof oldNode === "object") {
  // 타입이 다르면 교체

  const newChildren = newNode.children || [];
  const oldChildren = oldNode.children || [];
  const minLength = Math.min(oldChildren.length, newChildren.length);

  // 1. 겹치는 부분 먼저 업데이트
  for (let i = 0; i < minLength; i++) {
    updateElement(element, newChildren[i], oldChildren[i], i);
  }

  // 2. oldChildren이 더 많으면 초과 부분 역순으로 제거
  if (oldChildren.length > newChildren.length) {
    for (let i = oldChildren.length - 1; i >= newChildren.length; i--) {
      if (element.childNodes[i]) {
        element.removeChild(element.childNodes[i]);
      }
    }
  }
  // 3. newChildren이 더 많으면 초과 부분 정방향으로 추가
  else if (newChildren.length > oldChildren.length) {
    for (let i = oldChildren.length; i < newChildren.length; i++) {
      updateElement(element, newChildren[i], null, i);
    }
  }
}

// renderElement
export function renderElement(vNode, container) {
  // vNode를 표준화
  const normalizedVNode = normalizeVNode(vNode);

  // 이전 vNode 가져오기
  const oldNode = container._vNode;

  if (!oldNode) {
    // 최초 렌더링: createElement로 DOM을 생성하고 container에 추가
    container.innerHTML = ""; // 기존 내용 제거
    const element = createElement(normalizedVNode);
    container.appendChild(element);
  } else {
    // 이후 렌더링: container의 첫 번째 자식을 업데이트
    if (container.firstChild) {
      updateElement(container, normalizedVNode, oldNode, 0);
    } else {
      // 예외적으로 첫 번째 자식이 없는 경우 새로 생성
      const element = createElement(normalizedVNode);
      container.appendChild(element);
    }
  }

  // 현재 vNode를 container에 저장 (다음 렌더링을 위해)
  container._vNode = normalizedVNode;

  // 렌더링이 완료되면 container에 이벤트를 등록
  setupEventListeners(container);
}

멘토링

18일날 멘토링을 진행했는데, 준일 코치님에게 처음으로 리뷰를 받았다.  내가 질문 했던 것은 프론트엔드 신입으로 들어가기 위해선 어떻게 준비를 해야할지에 대한 질문이였다. 정말 좋은 말씀 많이해주셔서 공감이 되었다. 말씀해주신 내용에 대한 답변은 다음과 같다.

1. 코테 -> 프로그래머스 3까지 풀면 왠만한 스타트 기업은 통과

2. 자바스크립트 공부 : 자바스크립트 자체에 대한 공부하기 ex) 실행 컨텍스트, 이벤트루프, 클로저 등등

3. 리액트 같은 프레임워크에 대한 이해 : 어떤 문제를 리액트를 해결해주는지 내가 알고있는가에 대한 것이다. 즉 리액트 내부 동작에 대한 원리를 이해하기 
4. AI 잘쓰기 : 요즘 AI가 너무 핫하다보니 AI가 제일 중요하다고 말씀주셨다. 굳이 AI를 프로젝트에 적용을 하지 않아도되고 다양한 방법에 대해 문제를 해결하는 것이 중요하다. 예를 들면, 회고를 쓰기 귀찮은 문제가 있다, AI를 활용해 컴퓨터 스피커 음성으로 회고록을 작성하여 정리해주는 방법으로 AI를 사용했다고 말씀주셨다. 

5. 변화 만들기 : 밑의 내용은 실제로 수기로 작성해주신 부분이다. 

 

변화를 만들어내는 방법?

  • “우리 프로젝트에 테스트코드를 적용하고 싶은데, 어떻게 팀원들을 설득하여 적용할 수 있을까?”
  • “매주 회고를 토대로 조직의 성장을 만들어내고 싶은데, 어떻게 회고하는 문화를 적용할 수 있을까?”
  • 제가 생각하는 방법은, “설득보단 용서”
    • 일단 테스트코드를 은근슬쩍 적용하고, “잘 돌아가!”
    • 일단 나 혼자 회고 하고, 회고하는 과정을 팀원들에게 보여주고, “ 저 이렇게 회고 하니까 좋아요~ “

 

변화 만들기란? 내가 먼저 주체가 되어 그 과정을 공유하고 긍정적인 경험을 전달함으로써, 다른 사람들이 자발적으로 변화에 관심을 갖고 참여하도록 이끄는 것이라 생각한다. 사실 마지막 변화 만들기에 대해 가장 공감이 되었다. 회사든 스터디든 개인적인 프로젝트든 먼저 작게라도 변화를 시도하고 그 긍정적인 결과를 보여주고, 결과가 괜찮다면 설득에 대한 중요한 요소가 되지 않을까 생각한다.

'회고록' 카테고리의 다른 글

[WIL] 항해 프론트엔드 6기 1주차 후기  (8) 2025.07.13
[TIL] 20250130  (0) 2025.01.30
[TIL] 20250126  (0) 2025.01.26
[회고록] 20231016  (0) 2023.10.16
[회고록] 20231015  (0) 2023.10.15

+ Recent posts