Skip to content

Conversation

@Ludovico7
Copy link
Collaborator

📝 변경 사항

  • 기존 innerHtml 문자열을 직접 변경하는 방식에서 documentFragment를 통해 DOM Api를 사용하는 방식으로 수정했습니다.

🔍 변경 사항 설명

  • setInnerHtml 함수에서 innerhtml text를 생성하는 부분을 documentFragment를 사용하도록 수정
  • 텍스트에 스타일이 없는 텍스트 노드를 span으로 감싸던 문제 해결

🙏 질문 사항

📷 스크린샷 (선택)

✅ 작성자 체크리스트

  • Self-review: 코드가 스스로 검토됨
  • Unit tests 추가 또는 수정
  • 로컬에서 모든 기능이 정상 작동함
  • 린터 및 포맷터로 코드 정리됨
  • 의존성 업데이트 확인
  • 문서 업데이트 또는 주석 추가 (필요 시)

Ludovico7 and others added 2 commits January 16, 2025 16:50
Co-authored-by: minjungw00 <minjungw00@naver.com>
Co-authored-by: Jang seo yun <pipisebastian@users.noreply.github.com>
@Ludovico7 Ludovico7 added Refactor refactor codes FE Front End labels Jan 20, 2025
@Ludovico7 Ludovico7 self-assigned this Jan 20, 2025
setInnerHTML({ element: blockRef.current, block });
}
}, [block.crdt.serialize()]);
}, [getTextAndStylesHash(block)]);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JSON형태로 문자열로 바꿔주면, 자주바뀔 수 있는 요소를 불필요한 렌더를 줄일 수 있게 되군요!
좀더 최적화 관련해서 알아보니 memo를 사용해서

  1. 직접 JSON.stringify 를 매번 실행할 것인지
  2. memo를 활용해서 메모리 비용을 소모할 것인지
    두가지가 있더라구요.

내부 요소의 값이 복잡하면, memo를 선호하고 값이 적으면 매번 stringify를 한다고 하네요.
블럭 내부에 다루는 값이 4개 밖에 안되니, 이경우에는 stringify 가 좀더 비용이 적겠네요..!

const serializedContent = useMemo(() => getTextAndStylesHash(block), [block]);

useEffect(() => {
  if (blockRef.current) {
    console.log(block.crdt.serialize());
    setInnerHTML({ element: blockRef.current, block });
  }
}, [serializedContent]);

Copy link
Collaborator

@minjungw00 minjungw00 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수고많으셨습니다!

@hyonun321
Copy link
Collaborator

리팩토링 목적

image

(변경 후) (변경 전)

  1. 일반 텍스트 노드도
    으로 묶이는 현상을 해결하기 위함
  2. XSS 공격을 막기위함.
  3. list가 바뀌면, 인덱스를 전부 순회하는 문제를 최적화하기위해 documentFragment 를 적용

Copy link
Collaborator

@hyonun321 hyonun321 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수고하셨습니다.

@github-actions github-actions bot merged commit a9818a9 into dev Jan 22, 2025
6 checks passed
Comment on lines -109 to 129
if (styleChanged) {
const className = getClassNames(targetState);
html += `<span class="${className}" style="white-space: pre;">`;
spanOpen = true;
flushCurrentText();

// 새로운 스타일 상태 설정
currentState = targetState;

// 새로운 스타일이 있는 경우에만 span 생성
if (hasStylesApplied(targetState)) {
currentSpan = document.createElement("span");
currentSpan.className = getClassNames(targetState);
currentSpan.style.whiteSpace = "pre";
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이전에는 'span' 태그가 진짜 문자열로 들어갔는데, 이번에는 dom API 사용해서 createElement 수정한거 너무 좋습니다!! 👍

Copy link
Member

@pipisebastian pipisebastian left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수고하셨습니다!!

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

Labels

FE Front End Refactor refactor codes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants