03-개별 Vue 구성 요소 지연 로드와 미리 가져오기

업데이트: Link

개별 Vue 구성 요소 지연 로드와 미리 가져오기

Part 3 of 6 in our Vue.js Performance series.
Written by Filip Rakowski

지연 로딩의 목적은 초기 페이지 로드 시 사용자가 필요로 하지 않는 애플리케이션 부분의 다운로드를 연기하여 훨씬 더 빠르게 로딩 하는 것입니다.

이전 기사에서 모든 경로를 분리하여 지연 로드하여 번들 크기를 크게 줄일 수 있음을 확인했습니다. 이 기술을 사용하면 크기를 크게 줄일 수 있지만 더 많이 저장하기 위해 지연 로드할 수 있는 항목이 많이 있습니다.

이 기사에서는 어떤 유형의 구성 요소를 느리게 로드할 수 있는지, 더 중요한 것은 다운로드하는 데 필요한 대기 시간을 처리하는 방법을 살펴보겠습니다.

어떤 구성 요소를 지연 로드해야 합니까?

이 질문에 대한 대답은 사소하고 직관적입니다. 초기 렌더링에 필요하지 않은 모든 것입니다.

이것은 일반적으로 사용자가 어떤 식으로든 앱과 상호 작용할 때까지 사용자가 볼 수 없는 모든 것을 의미합니다. 가장 일반적인 예 중 하나는 일반적으로 모달 창이나 사이드바와 같은 v-if 지시문으로 조건부로 숨기는 구성 요소입니다. 이러한 구성 요소는 일반적으로 지연 로드하기에 좋은 후보입니다.

코드 분할 구성 요소를 가져오는 시기를 정확히 이해하는 것이 중요합니다. 이 시리즈의 첫 번째 부분에서는 일반적으로 지연 로드된 리소스가 import() 함수가 호출될 때 다운로드되고 구성 요소가 렌더링을 요청할 때만 발생하는 Vue 구성 요소의 경우 다운로드 된다고 가정할 수 있다는 것을 읽었습니다.

조금 더 깊이 파헤쳐 보겠습니다. 아래 예를 살펴보십시오.

<modal-window v-if="isModalVisible" />
<modal-window v-show="isModalVisible" />

isModalVisible 변수가 false로 설정되어 있다고 가정하면 v-if 지시문은 DOM에서 구성 요소를 완전히 제거하는 반면 v-showdisplay: none CSS 속성입니다.

그 동작의 의미는 v-show를 사용하면 내부의 값이 무엇이든 관계없이 항상 다운로드되고 v-if 지시문 구성 요소는 해당 값이 true가 된 후에만 다운로드 된다는 것이므로 기억하십시오. 지연 로드된 구성 요소에는 항상 v-if를 사용해야 합니다!

흥미로운 참고 사항: Vue 인스턴스의 components 속성에 구성 요소를 전달하면 전달된 값 유형이 Object 또는 function인지 확인합니다. 함수인 경우 구성 요소에 렌더링이 요청될 때만 호출이 발생합니다. 이것이 v-if의 트릭이 작동하는 이유입니다.

따라서 구성 요소를 느리게 로드하기 위해 해야 할 일은 다음과 같이 v-if 지시문과 동적 import 문을 결합하는 것뿐입니다.

<template>
  <div>
    <button @click="isModalVisible = true">Open modal</button>
    <modal-window v-if="isModalVisible" />
  </div>
</template>

<script>
export default {
  data () {
    return {
      isModalVisible: false
    }
  },
  components: {
    ModalWindow: () => import('./ModalWindow.vue')
  }
}
</script>

사용자 경험에 미치는 영향

구성 요소를 지연 로드하면 초기 다운로드 시간을 많이 절약할 수 있지만 사용자가 나중에 지불해야 하는 대가가 따릅니다.

저장된 모든 바이트는 애플리케이션이 제대로 작동하는 데 여전히 필요합니다. 사용자는 특정 시점에서 다운로드해야 하므로 연기된 리소스가 다운로드될 때까지 기다려야 합니다. 리소스를 다운로드하는 데 걸리는 시간에 따라 사용자 경험이 좋지 않거나 매우 나빠질 수 있습니다.

이러한 지연은 UI의 개별 부분이 나타날 때까지 기다리는 데 익숙하지 않기 때문에 전체 페이지보다 구성 요소에서 훨씬 더 나쁩니다. 버튼을 클릭하면 즉시 반응을 기대합니다. 웹 사이트와 상호 작용할 때 아무 일도 일어나지 않으면 응용 프로그램이 느리거나 손상된 것으로 인식하고 대부분은 사이트를 떠납니다.

RAIL 모델 가이드라인에 따르면 모든 사용자 입력은 100ms 이내에 응답을 생성해야 합니다. 애플리케이션이 응답하기 전에 리소스를 다운로드해야 합니다. 그래서 우리는 무엇을 할 수 있습니까?

솔루션은 매우 간단합니다. prefetching이라고 합니다.

Prefetching

간단히 말해서 프리페치는 브라우저에서 요청하기 전에 미래에 필요할 수 있는 특정 리소스를 다운로드하는 것입니다. 우리의 경우 이것은 느리게 로드된 모달 창일 수 있습니다. 또한 느리게 로드된 경로를 미리 가져오는 것도 의미가 있습니다. 예를 들어 전자 상거래 상점의 카테고리 페이지에 있는 경우 사용자가 방문할 가능성이 높기 때문에 제품 페이지를 미리 가져올 수 있습니다.

브라우저가 초기 로드를 완료하고 유휴 상태가 된 후에만 프리페치가 시작된다는 점에 유의하는 것이 중요합니다. 미리 가져오기는 페이지 로드나 앱이 대화형이 되는 속도(TTI)에 영향을 주지 않습니다.

프리페칭을 사용하면 페이지 성능에 전혀 영향을 주지 않고 지연 로딩의 나쁜 UX 결과를 제거할 수 있습니다. 이 얼마나 멋진가요?

흥미로운 참고 사항: Nuxt.js를 사용하는 경우 현재 열려 있는 경로의 모든 <nuxt-link>는 콘텐츠를 자동으로 미리 가져옵니다. 이 동작에 대한 자세한 내용은 여기를 참조하세요.

리소스를 미리 가져오려면(일반적으로 화면 밖의 구성 요소나 경로와 같이 코드로 분할된 것을 미리 가져옴) <link rel="prefetch" href="url" /> 태그에 추가하기만 하면 됩니다.

모듈 확인 순서에 따라 번들 이름을 생성하는 webpack을 사용할 때 쉽지 않습니다. 다행히 리소스를 쉽게 미리 가져오는 데 도움이 되는 기능이 있습니다. - 매직 코멘트

Webpack의 매직 코멘트는 코멘트에서 사용될 때 빌드 프로세스에 영향을 미치는 특별한 문구입니다. 이러한 매직 코멘트 중 하나는 /* webpackPrefetch: true */입니다. 이 주석을 아래 예제와 같이 동적 가져오기 함수 안에 넣으면 리소스를 미리 가져옵니다.

components: {
  ModalWindow: () => import(/* webpackPrefetch: true */ './ModalWindow.vue')
}

코드를 실행하는 순간 웹팩은 이와 같은 모든 마법의 주석을 찾고 애플리케이션의 <head> 섹션에 <link rel="prefetch" url="resource-url" /> 태그를 동적으로(즉, 빌드 시간이 아닌 코드 실행 시간) 추가합니다.

<link rel="prefetch" href="path-to-chunk-with-modal-window" />

이제 사용자가 ModalWindow.vue로 청크를 요청할 때 이미 메모리에 있고 즉시 나타납니다.

팁: Vue CLI 3를 사용하는 경우 지연 로드된 모든 리소스는 기본적으로 미리 가져옵니다!

중요: 빌드 구성에 따라 프리페치는 프로덕션 모드에서만 작동할 수 있습니다.

마법의 주석 대신 webpack prefetch 플러그인 또는 workbox와 같은 보다 일반적인 솔루션을 사용할 수 있습니다.

프리페칭은 우리의 모든 문제를 해결하는 것처럼 보이지만 이 기능에 대한 브라우저 지원은 아직 일부 문제에 대해 존재하지 않습니다. 특히 Safari 지원 부족은 고통스러울 수 있습니다.

Async components

고맙게도 Vue에는 이 문제를 우아하게 해결하는 async components라는 매우 유용한 기능이 있습니다.

비동기 구성 요소는 기본적으로 다음을 포함하는 개체입니다.

  • dynamic component 이는 import() 함수로 느리게 로드됩니다.
  • loading component 동적 구성 요소가 로드될 때까지 표시됩니다.
  • error component 동적 컴포넌트 로딩이 실패한 경우(즉, Promise가 reject된 경우)에만 표시됩니다.

두 번째 속성은 프리페치를 지원하지 않는 브라우저를 처리하는 좋은 방법이고 세 번째 속성은 프리페치가 실패하는 드문 경우에 오프라인 우선 애플리케이션에서 오류 처리를 처리하도록 합니다.

비동기 구성 요소는 동적 가져오기와 마찬가지로 함수로 래핑됩니다. 따라서 구성 요소와 동일한 방식으로 사용할 수 있습니다.

const ModalWindow = () => ({
  component: import('./ModalWindow.vue'),
  loading: LoadingComponent,
  error: ErrorComponent,
  // The error component will be displayed if a timeout is
  // provided and exceeded. Default: Infinity.
  timeout: 3000
})

export default {
  components: {
    ModalWindow
  }
}

Vue Storefront 기본 테마에서 비동기 컴포넌트를 사용한 방법은 다음과 같습니다.

TIP: navigator.onLine 속성을 사용하여 네트워크 연결 부족으로 인해 가져오기에 실패한 경우 다른 오류 메시지를 표시할 수 있습니다. navigator object는 브라우저에 대한 정보를 담고 있습니다.

요약

이 기사에서 우리는 개별 구성 요소의 지연 로딩에 대해 깊이 파고 들었습니다. 사용자가 어느 시점에서 지연 로드된 청크를 다운로드해야 하므로 지연된 리소스가 다운로드될 때까지 기다려야 하지만 사전 가져오기로 요청하기 전에 다운로드할 수 있으며 브라우저에서 지원하지 않는 경우에는 다음을 수행할 수 있습니다. 여전히 비동기 구성 요소로 훌륭한 대기 경험을 제공합니다.

다음 단계

이제 자신을 지연 로드 구성 요소의 마스터라고 부를 수 있습니다! Vue 성능의 또 다른 영역을 마스터할 시간입니다! 다음 부분에서는 타사 라이브러리를 현명하게 지연 로드 할 때 , 그 중 어느 것이 너무 큰지 식별하는 방법 및 더 작은 라이브러리를 쉽게 찾는 방법을 배웁니다.

댓글남기기