Vue SSR에서 하이드레이션 오류 해결

3723 단어 Vue.jsnuxt.js
참고 기사
What to do when Vue hydration fails
Client Side Hydration

(Vue) 하이드레이션이란?



하이드레이션은 Vue가 서버 측에서 렌더링 된 마크 업을 변환하고이를 다시 활성화하여 Vue의 동적 변경을 반영 할 수있게하는 프로세스입니다.

Vue가 기대하고 있는 마크업과 실제로 렌더링된 HTML이 다르면 하이드레이션 에러가 된다.

Vue에서 개발하는 동안 다음과 같은 Warning을 만날 때가 있습니다.
[Vue warn]: The client-side rendered virtual DOM tree is not matching server-rendered content.
 This is likely caused by incorrect HTML markup, for example nesting block-level elements inside <p>,
 or missing <tbody>. Bailing hydration and performing full client-side render.



Warning 내용↓

클라이언트 측에서 렌더링된 가상 DOM 트리가 서버에서 렌더링된 것과 일치하지 않음

이 Warning은 개발 환경에서만 표시됩니다.
프로덕션 환경에서는 오류로 출력되거나 렌더링이 완료되지 않습니다.
그래서이 문제는 해결해야합니다.

이번에는 이 오류가 발생한 위치를 확인하는 방법에 대해 메모해 둡니다.

덧붙여서, 이미 상기 Warning의 2개상 근처에, 이하 로그가 나오면 거기가 발생 개소입니다.
Parent: <~~>...</~~>

다만, 이것이 사람에 따라서는 표시되지 않기 때문에 다른 특정 방법을 제시합니다.
또한 발생 원인도.

출처 식별



Warning의 상세를 열면 다음과 같이 되어 있습니다.
이제 hydrate 호출자를 클릭합니다.
이미지로 말하면 hydrate @ vue.runtime.esm.js?2b0e:6378


그러면 Vue의 하이드레이션 기능 소스 코드가 확장되고,
펼쳐진 행의 조금 위 근처에 이러한 코드가 있습니다.
if (process.env.NODE_ENV !== 'production') {
  if (!assertNodeMatch(elm, vnode, inVPre)) {
    return false
  }
}



여기의 6374행 부분에 디버거를 설정합니다. (6374곳을 클릭)
return false

그리고이 상태에서 화면을 다시로드하면 렌더링이 도중에 멈 춥니 다.

그리고는 DevTool의 Console 탭이나 Elments 탭으로부터,
하이드레이션에 실패한 DOM 요소를 식별해 갑니다.
(마지막으로 표시되는 DOM 요소와 다르므로 여기에서 확인할 수 있습니다.)

발생 원인/수정 방법 등



가능한 원인은 다음과 같습니다.

1. 서버측과 클라이언트측 상태가 다르다



이 원인이 가장 많은 것 같고,
이 경우의 해결책으로서는, 데이터의 취득 방법이나 타이밍을 수정하는 등입니다.

2. 잘못된 HTML을 설명합니다.



잘못된 HTML을 작성하지 않았는지 확인합니다.

예를 들어 다음과 같은 HTML을 작성한 경우,
올바르게 table 태그 안에 tbody 태그가 있어야합니다.

[악성 HTML]
<table>
  <tr><td>hoge</td></tr>
</table>

[유효한 HTML]
<table>
  <tbody>
    <tr><td>hoge</td></tr>
  </tbody>
</table>

하지만 브라우저에서는 이 악성 HTML에 자동으로 tbody 태그를 삽입해 줍니다.
따라서 DOM 트리에 불일치가 발생합니다.

3. 최종 수단



client-only 태그로 래핑하여 서버 측에서 렌더링을 피합니다.

<client-only></client-only>

※여담



개발환경에서는
클라이언트와 서버에서 렌더링된 DOM 트리가 일치하지 않더라도,
기존 DOM을 파기하고 처음부터 다시 렌더링해 줍니다.
그러나 프로덕션 환경에서는
퍼퍼맨스를 극대화하기 위해 이 기능을 사용할 수 없습니다.

또한 하이드레이션은 서버가 처음 페이지를 렌더링할 때(첫 번째 요청 시)에만 발생합니다.

좋은 웹페이지 즐겨찾기