페이지 로드 속도를 높이기 위해 최신 브라우저에 최신 코드 제공하기

모든 주요 브라우저에서 원활하게 작동하는 웹사이트를 빌드하는 것은 개방형 웹 생태계의 핵심 원칙입니다. 그러나 이는 작성하는 모든 코드가 타겟팅할 각 브라우저에서 지원되는지 확인하는 추가 작업을 의미합니다. 새로운 JavaScript 언어 기능을 사용하려면 아직 지원하지 않는 브라우저에서 이러한 기능을 이전 버전과 호환되는 형식으로 변환 컴파일해야 합니다.

Babel은 다양한 브라우저와 환경(예: Node)에서 이해할 수 있는 최신 문법을 코드로 컴파일하는 데 가장 널리 사용되는 도구입니다. 이 가이드에서는 개발자가 Babel을 사용한다고 가정하므로, 아직 하지 않았다면 설정 안내에 따라 애플리케이션에 포함해야 합니다. 앱에서 webpack을 모듈 번들러로 사용하는 경우 Build Systems에서 webpack를 선택합니다.

Babel을 사용하여 사용자에게 필요한 항목만 트랜스파일하려면 다음을 수행해야 합니다.

  1. 타겟팅할 브라우저를 식별합니다.
  2. @babel/preset-env를 적절한 브라우저 타겟과 함께 사용합니다.
  3. <script type="module">를 사용하면 트랜스파일된 코드가 필요하지 않은 브라우저에 더 이상 전송되지 않습니다.

타겟팅할 브라우저 식별

애플리케이션의 코드가 트랜스파일되는 방식을 수정하기 전에 애플리케이션에 액세스하는 브라우저를 식별해야 합니다. 사용자가 현재 사용 중인 브라우저와 정보에 입각한 결정을 내리기 위해 타겟팅할 브라우저를 분석합니다.

@babel/preset-env 사용

일반적으로 코드를 트랜스파일하면 원래 형식보다 파일 크기가 더 커집니다. 컴파일하는 양을 최소화하면 번들의 크기를 줄여 웹페이지의 성능을 개선할 수 있습니다.

사용 중인 특정 언어 기능을 선택적으로 컴파일하기 위해 특정 플러그인을 포함하는 대신 Babel은 플러그인을 번들로 묶는 여러 사전 설정을 제공합니다. @babel/preset-env를 사용하여 타겟팅할 브라우저에 필요한 변환 및 polyfill만 포함합니다.

Babel 구성 파일 .babelrcpresets 배열 내에 @babel/preset-env를 포함합니다.

{
 "presets": [
   [
     "@babel/preset-env",
     {
       "targets": ">0.25%"
     }
   ]
 ]
}

targets 필드를 사용하여 browsers 필드에 적절한 쿼리를 추가하여 포함할 브라우저 버전을 지정합니다. @babel/preset-env는 브라우저를 타겟팅하기 위해 여러 도구 간에 공유되는 오픈소스 구성인 Browserlist와 통합됩니다. 호환되는 쿼리의 전체 목록은 browserslist 문서에서 확인할 수 있습니다. 또 다른 옵션은 .browserslistrc 파일을 사용하여 타겟팅하려는 환경을 나열하는 것입니다.

">0.25%" 값은 Babel에 전체 사용량의 0.25% 이상을 차지하는 브라우저를 지원하는 데 필요한 변환만 포함하도록 지시합니다. 이렇게 하면 극소수의 사용자가 사용하는 브라우저에 관한 불필요하게 트랜스파일된 코드가 번들에 포함되지 않습니다.

대부분의 경우 다음 구성을 사용하는 것보다 이 방법이 더 좋습니다.

  "targets": "last 2 versions"

"last 2 versions" 값은 모든 브라우저의 마지막 두 버전에 대한 코드를 컴파일합니다. 즉, Internet Explorer와 같이 사용 중단된 브라우저도 지원됩니다. 이러한 브라우저를 사용하여 애플리케이션에 액세스할 필요가 없을 경우 번들의 크기가 불필요하게 증가할 수 있습니다.

궁극적으로 필요에 맞는 브라우저만 타겟팅하려면 적절한 쿼리 조합을 선택해야 합니다.

최신 버그 수정 사용

@babel/preset-env는 여러 자바스크립트 구문 기능을 컬렉션으로 그룹화하여 지정된 타겟 브라우저에 따라 사용 설정/사용 중지합니다. 이 방법은 원활히 작동하기는 하지만, 타겟팅된 브라우저에 1개의 기능이 있는 버그가 포함된 경우 구문 기능 전체 컬렉션이 변환됩니다. 이로 인해 필요한 것보다 더 많이 변환된 코드가 생성되는 경우가 많습니다.

원래 별도의 사전 설정으로 개발된 @babel/preset-env버그 수정 옵션은 일부 브라우저에서 손상된 최신 구문을 해당 브라우저에서 손상되지 않는 가장 유사한 구문으로 변환하여 이 문제를 해결합니다. 그 결과 모든 대상 브라우저에서 호환성을 보장하는 몇 가지 약간의 구문 조정을 포함해 거의 동일한 최신 코드가 구현됩니다. 이 최적화를 사용하려면 @babel/preset-env 7.10 이상이 설치되어 있는지 확인한 다음 bugfixes 속성을 true로 설정하세요.

{
 "presets": [
   [
     "@babel/preset-env",
     {
       "bugfixes": true
     }
   ]
 ]
}

Babel 8에서는 bugfixes 옵션이 기본적으로 사용 설정됩니다.

<script type="module"> 사용

자바스크립트 모듈 또는 ES 모듈은 모든 주요 브라우저에서 지원되는 비교적 새로운 기능입니다. 모듈을 사용하여 다른 모듈에서 가져오고 내보낼 수 있는 스크립트를 만들 수 있지만 @babel/preset-env와 함께 사용하여 모듈을 지원하는 브라우저만 타겟팅할 수도 있습니다.

특정 브라우저 버전이나 시장점유율을 쿼리하는 대신 .babelrc 파일의 targets 필드 내에 "esmodules" : true를 지정하는 것이 좋습니다.

{
   "presets":[
      [
         "@babel/preset-env",
         {
            "targets":{
               "esmodules": true
            }
         }
      ]
   ]
}

Babel로 컴파일된 많은 최신 ECMAScript 기능은 JavaScript 모듈을 지원하는 환경에서 이미 지원되고 있습니다. 이렇게 하면 실제로 필요한 브라우저에 트랜스파일된 코드만 사용되도록 하는 프로세스를 간소화할 수 있습니다.

모듈을 지원하는 브라우저는 nomodule 속성이 있는 스크립트를 무시합니다. 반대로 모듈을 지원하지 않는 브라우저는 type="module"가 있는 스크립트 요소를 무시합니다. 즉, 컴파일된 대체와 모듈을 포함할 수 있습니다.

애플리케이션의 두 버전 스크립트가 다음과 같이 포함되는 것이 이상적입니다.

  <script type="module" src="main.mjs"></script>
  <script nomodule src="compiled.js" defer></script>

모듈을 지원하는 브라우저는 main.mjs를 가져오고 실행하고 compiled.js를 무시합니다. 모듈을 지원하지 않는 브라우저는 그 반대로 이루어집니다.

webpack을 사용하는 경우, 애플리케이션의 두 가지 별도 버전에 대해 구성에서 서로 다른 대상을 설정할 수 있습니다.

  • 모듈을 지원하는 브라우저 전용 버전입니다.
  • 모든 기존 브라우저에서 작동하는 컴파일된 스크립트가 포함된 버전 변환 컴파일이 더 광범위한 브라우저를 지원해야 하므로 이 방법은 파일 크기가 더 큽니다.

리뷰를 작성해 주신 코너 클라크와 제이슨 밀러에게 감사드립니다.