프런트 엔드 성능 2021: 환경 정의

게시 됨: 2022-03-10
요약 요약 ↬ 2021년을…빨리 만들자! 메트릭에서 도구 및 프론트 엔드 기술에 이르기까지 오늘날 웹에서 빠른 경험을 생성하기 위해 알아야 할 모든 것이 포함된 연간 프론트 엔드 성능 체크리스트. 2016년부터 업데이트되었습니다.

목차

  1. 준비하기: 계획 및 측정항목
  2. 현실적인 목표 설정
  3. 환경 정의
  4. 자산 최적화
  5. 빌드 최적화
  6. 배달 최적화
  7. 네트워킹, HTTP/2, HTTP/3
  8. 테스트 및 모니터링
  9. 빠른 승리
  10. 한 페이지에 모든 것
  11. 체크리스트 다운로드(PDF, Apple Pages, MS Word)
  12. 다음 가이드를 놓치지 않으려면 이메일 뉴스레터를 구독하세요.

환경 정의

  1. 빌드 도구를 선택하고 설정합니다.
    요즘 멋지다고 생각하는 것에 너무 많은 관심을 기울이지 마십시오. Grunt, Gulp, Webpack, Parcel 또는 도구 조합 등 빌드 환경에 따라 달라집니다. 필요한 결과를 얻고 빌드 프로세스를 유지 관리하는 데 문제가 없다면 잘 하고 있는 것입니다.

    빌드 도구 중에서 Rollup이 계속 인기를 얻고 있고 Snowpack도 마찬가지지만 Webpack은 말 그대로 수백 개의 플러그인을 사용하여 빌드 크기를 최적화할 수 있는 가장 확실한 도구인 것 같습니다. Webpack 로드맵 2021을 주목하십시오.

    최근 등장한 가장 주목할만한 전략 중 하나는 중복 코드를 최소화하기 위해 Next.js와 Gatsby에서 Webpack을 사용한 Granular 청킹입니다. 기본적으로 모든 진입점에서 공유되지 않는 모듈은 이를 사용하지 않는 경로에 대해 요청할 수 있습니다. 필요한 것보다 더 많은 코드가 다운로드되므로 결국 오버헤드가 됩니다. Next.js의 세분화된 청크를 사용하면 서버 측 빌드 매니페스트 파일 을 사용하여 다른 진입점에서 사용되는 출력 청크를 결정할 수 있습니다.

    Webpack 프로젝트에서 중복 코드를 줄이기 위해 기본적으로 Next.js 및 Gatsby에서 활성화된 세분화된 청킹을 사용할 수 있습니다.
    Webpack 프로젝트에서 중복 코드를 줄이기 위해 기본적으로 Next.js 및 Gatsby에서 활성화된 세분화된 청크를 사용할 수 있습니다. 이미지 크레디트: Addy Osmani. (큰 미리보기)

    SplitChunksPlugin을 사용하면 여러 경로에서 중복 코드를 가져오는 것을 방지하기 위해 여러 조건에 따라 여러 분할 청크가 생성됩니다. 이렇게 하면 탐색 중 페이지 로드 시간과 캐싱이 향상됩니다. Next.js 9.2 및 Gatsby v2.20.7에서 제공됩니다.

    Webpack을 시작하는 것은 어려울 수 있습니다. 따라서 Webpack에 대해 자세히 알아보려면 다음과 같은 훌륭한 리소스가 있습니다.

    • Webpack 문서는 — 분명히 — 좋은 출발점이며 Webpack — Raja Rao의 The Confusing Bits 및 Andrew Welch의 An Annotated Webpack Config도 마찬가지입니다.
    • Sean Larkin은 Webpack: The Core Concepts에 대한 무료 과정을 제공하고 Jeffrey Way는 모두를 위한 Webpack에 대한 환상적인 무료 과정을 공개했습니다. 둘 다 Webpack에 뛰어들기 위한 훌륭한 입문서입니다.
    • Webpack Fundamentals는 FrontendMasters에서 출시한 Sean Larkin과 함께 하는 매우 포괄적인 4시간 과정입니다.
    • Webpack 예제에는 주제 및 목적별로 분류된 수백 가지의 바로 사용할 수 있는 Webpack 구성이 있습니다. 보너스: 기본 구성 파일을 생성하는 Webpack 구성 구성자도 있습니다.
    • Awesome-webpack은 Angular, React 및 프레임워크에 구애받지 않는 프로젝트에 대한 기사, 비디오, 코스, 책 및 예제를 포함하여 유용한 Webpack 리소스, 라이브러리 및 도구의 선별된 목록입니다.
    • Webpack을 사용한 빠른 프로덕션 자산 빌드로의 여정은 팀이 RequireJS 기반 JavaScript 빌드 시스템 사용에서 Webpack 사용으로 전환한 방법과 평균 4분 만에 13,200개 이상의 자산을 관리하여 빌드를 최적화한 방법에 대한 Etsy의 사례 연구입니다.
    • Webpack 성능 팁은 Ivan Akulov의 금광 스레드로, Webpack에 특별히 초점을 맞춘 팁을 포함하여 많은 성능 중심 팁을 제공합니다.
    • Awesome-webpack-perf는 성능을 위한 유용한 Webpack 도구 및 플러그인이 포함된 금광 GitHub 리포지토리입니다. Ivan Akulov도 관리합니다.
Webpack을 사용한 빠른 프로덕션 빌드를 위한 Etsy의 여정 시각화
Webpack을 통한 빠른 프로덕션 빌드를 위한 Etsy의 여정(Addy Osmani를 통해)(큰 미리보기)
  1. 점진적 향상을 기본값으로 사용합니다.
    하지만 세월이 흘러도 프론트 엔드 아키텍처 및 배포의 기본 원칙으로 점진적인 향상을 유지하는 것이 안전한 방법입니다. 먼저 핵심 경험을 설계 및 구축한 다음, 지원 가능한 브라우저를 위한 고급 기능으로 경험을 향상시켜 탄력적인 경험을 만드십시오. 웹사이트가 최적이 아닌 네트워크의 열악한 브라우저에서 열악한 화면을 가진 느린 컴퓨터에서 빠르게 실행되는 경우 적절한 네트워크에서 좋은 브라우저가 있는 빠른 컴퓨터에서만 더 빠르게 실행됩니다.

    사실, 적응형 모듈 서비스를 통해 우리는 다른 수준으로 점진적인 향상을 가져오고, 저가형 장치에 "라이트" 핵심 경험을 제공하고 고급형 장치에 대한 보다 정교한 기능으로 향상시키는 것 같습니다. 점진적인 향상은 곧 사라지지 않을 것입니다.

  2. 강력한 성능 기준을 선택하십시오.
    네트워크, 열 제한, 캐시 제거, 타사 스크립트, 파서 차단 패턴, 디스크 I/O, IPC 대기 시간, 설치된 확장, 바이러스 백신 소프트웨어 및 방화벽, 백그라운드 CPU 작업, 하드웨어 및 메모리 제약 등 로드에 영향을 미치는 많은 알려지지 않은 사항이 있습니다. L2/L3 캐싱의 차이점, RTTS — JavaScript는 기본적으로 렌더링을 차단하는 웹 글꼴과 너무 많은 메모리를 사용하는 이미지 다음으로 경험 비용이 가장 높습니다. 성능 병목 현상이 서버에서 클라이언트로 이동함에 따라 개발자로서 우리는 이러한 알려지지 않은 모든 사항을 훨씬 더 자세히 고려해야 합니다.

    이미 임계 경로 HTML/CSS/JavaScript, 라우터, 상태 관리, 유틸리티, 프레임워크 및 애플리케이션 로직이 포함된 170KB 예산으로 네트워크 전송 비용, 구문 분석/컴파일 시간 및 런타임 비용을 철저히 조사해야 합니다. 우리가 선택한 프레임워크. 운 좋게도 지난 몇 년 동안 브라우저가 스크립트를 구문 분석하고 컴파일하는 속도가 크게 향상되었습니다. 그러나 JavaScript 실행은 여전히 ​​주요 병목 현상이므로 스크립트 실행 시간과 네트워크에 세심한 주의를 기울이는 것이 영향을 미칠 수 있습니다.

    Tim Kadlec은 최신 프레임워크의 성능에 대한 환상적인 연구를 수행했으며 "JavaScript 프레임워크에는 비용이 있습니다"라는 기사에 요약했습니다. 우리는 종종 독립 실행형 프레임워크의 영향에 대해 이야기하지만 Tim이 언급한 것처럼 실제로 여러 프레임워크를 사용하는 것은 드문 일이 아닙니다. 아마도 Angular의 이전 버전을 사용하는 몇 가지 레거시 애플리케이션과 함께 최신 프레임워크로 천천히 마이그레이션되는 이전 버전의 jQuery일 수 있습니다. 따라서 고급 장치에서도 사용자 경험을 거의 사용할 수 없게 만들 수 있는 JavaScript 바이트 및 CPU 실행 시간의 누적 비용 을 탐색하는 것이 더 합리적입니다.

    일반적으로 최신 프레임워크 는 덜 강력한 장치에 우선순위를 두지 않으므로 휴대전화와 데스크톱에서의 경험은 성능 면에서 극적으로 다른 경우가 많습니다. 연구에 따르면 React 또는 Angular를 사용하는 사이트는 다른 사이트보다 CPU에서 더 많은 시간을 소비합니다(물론 React가 Vue.js보다 CPU에서 더 비싸다고 말하는 것은 아닙니다).

    Tim에 따르면 한 가지 분명한 사실은 "사이트를 구축하기 위해 프레임워크를 사용하는 경우 최상의 시나리오에서도 초기 성능 측면에서 절충안을 만들고 있는 것입니다."

프레임워크 비용, JavaScript CPU 시간: SPA 사이트 성능이 좋지 않음
프레임워크의 비용, JavaScript의 단점: SPA 사이트(여전히) 성능이 저조합니다.
모바일 장치에 대한 스크립팅 관련 CPU 시간 및 desktopv 장치에 대한 JavaScript 바이트. 일반적으로 React 또는 Angular를 사용하는 사이트는 다른 사이트보다 CPU에서 더 많은 시간을 보냅니다. 그러나 사이트를 구축하는 방법에 따라 다릅니다. 팀 Kadlec의 연구. (큰 미리보기)
  1. 프레임워크 및 종속성을 평가합니다.
    이제 모든 프로젝트에 프레임워크가 필요한 것은 아니며 단일 페이지 애플리케이션의 모든 페이지에서 프레임워크를 로드해야 하는 것도 아닙니다. Netflix의 경우 "클라이언트 측에서 React, 여러 라이브러리 및 해당 앱 코드를 제거하면 JavaScript의 총량이 200KB 이상 감소하여 로그아웃한 홈페이지에 대한 Netflix의 상호 작용 시간이 50% 이상 감소했습니다. ." 그런 다음 팀은 사용자가 방문 페이지에서 보낸 시간을 활용하여 사용자가 방문할 가능성이 높은 후속 페이지에 대해 React를 미리 가져왔습니다(자세한 내용은 참조).

    중요한 페이지에서 기존 프레임워크를 모두 제거하면 어떻게 될까요? Gatsby를 사용하면 정적 HTML 파일에서 Gatsby가 생성한 모든 JavaScript 파일을 제거하는 gatsby-plugin-no-javascript를 확인할 수 있습니다. Vercel에서는 특정 페이지에 대해 프로덕션에서 런타임 JavaScript 비활성화를 허용할 수도 있습니다(실험적).

    일단 프레임워크가 선택되면 우리는 최소 몇 년 동안 그 프레임워크를 유지하게 되므로, 프레임워크를 사용해야 하는 경우 선택 사항이 정보에 입각하여 잘 고려되었는지 확인해야 합니다. 신경써.

    데이터에 따르면 기본적으로 프레임워크는 상당히 비쌉니다. React 페이지의 58.6%는 1MB 이상의 JavaScript를 제공하고 Vue.js 페이지 로드의 36%는 1.5초 미만의 First Contentful Paint를 사용합니다. Ankur Sethi의 연구에 따르면 "당신의 React 애플리케이션 은 아무리 최적화하더라도 인도의 평균 전화에서 약 1.1초보다 빠르게 로드 되지 않습니다. Angular 앱은 부팅하는 데 항상 최소 2.7초가 걸립니다. Vue 앱 사용자는 사용을 시작하기 전에 최소 1초를 기다려야 합니다." 어쨌든 인도를 주요 시장으로 타겟팅하지 않을 수 있지만 최적이 아닌 네트워크 조건으로 사이트에 액세스하는 사용자는 비슷한 경험을 할 것입니다.

    물론 SPA를 빠르게 만드는 것은 가능하지만 즉시 사용 가능한 것은 아니므로 빠르게 만들고 유지 하는 데 필요한 시간과 노력을 고려해야 합니다. 초기에 가벼운 기본 성능 비용을 선택하면 더 쉬울 것입니다.

    그렇다면 프레임워크를 선택하는 방법은 무엇입니까? 옵션을 선택하기 전에 크기 대한 총 비용 + 초기 실행 시간을 고려하는 것이 좋습니다. Preact, Inferno, Vue, Svelte, Alpine 또는 Polymer와 같은 경량 옵션은 작업을 잘 수행할 수 있습니다. 기준선의 크기는 애플리케이션 코드의 제약 조건을 정의합니다.

    Seb Markbage가 언급한 것처럼 프레임워크의 시작 비용을 측정하는 좋은 방법은 먼저 뷰를 렌더링한 다음 뷰를 삭제한 다음 프레임워크가 확장되는 방식을 알려줄 수 있으므로 다시 렌더링 하는 것입니다. 첫 번째 렌더는 지연 컴파일된 코드를 워밍업하는 경향이 있으며, 이는 더 큰 트리가 확장될 때 이점을 얻을 수 있습니다. 두 번째 렌더링은 기본적으로 페이지의 코드 재사용이 페이지의 복잡성이 증가함에 따라 성능 특성에 영향을 미치는 방식에 대한 에뮬레이션입니다.

    기능, 접근성, 안정성, 성능, 패키지 생태계 , 커뮤니티, 학습 곡선, 문서, 도구, 추적 기록을 탐색하여 Sacha Greif의 12점 척도 점수 시스템에서 후보자(또는 일반적으로 모든 JavaScript 라이브러리)를 평가할 수 있습니다. , 팀, 호환성, 보안 등.

    Perf Track은 대규모로 프레임워크 성능을 추적합니다.
    Perf Track은 대규모로 프레임워크 성능을 추적합니다. (큰 미리보기)

    또한 더 오랜 기간 동안 웹에서 수집된 데이터에 의존할 수 있습니다. 예를 들어, Perf Track은 프레임워크 성능을 대규모로 추적하여 Angular, React, Vue, Polymer, Preact, Ember, Svelte 및 AMP로 구축된 웹사이트에 대한 오리진 집계 Core Web Vitals 점수 를 보여줍니다. Gatsby, Next.js 또는 Create React App으로 구축된 웹사이트와 Nuxt.js(Vue) 또는 Sapper(Svelte)로 구축된 웹사이트를 지정하고 비교할 수도 있습니다.

    좋은 출발점은 애플리케이션에 적합한 기본 스택 을 선택하는 것입니다. Gatsby(React), Next.js(React), Vuepress(Vue), Preact CLI 및 PWA 스타터 키트는 평균적인 모바일 하드웨어에서 즉시 로드할 수 있는 합리적인 기본값을 제공합니다. 또한, React 및 Angular에 대한 web.dev 프레임워크별 성능 지침을 살펴보세요( 감사합니다, Phillip! ).

    그리고 아마도 단일 페이지 애플리케이션을 모두 구축하는 데 약간 더 신선한 접근 방식을 취할 수 있습니다. Turbolinks는 JSON 대신 HTML을 사용하여 뷰를 렌더링하는 15KB JavaScript 라이브러리입니다. 따라서 링크를 따라갈 때 Turbolinks는 전체 페이지 로드 비용을 발생시키지 않고 자동으로 페이지를 가져오고 <body> 를 바꾸고 <head> 를 병합합니다. 스택(Hotwire)에 대한 빠른 설명과 전체 문서를 확인할 수 있습니다.

가장 많이 팔린 휴대폰의 컴퓨팅 성능을 보여주는 히스토그램과 같은 그래프
가장 많이 팔린 휴대폰의 CPU 및 컴퓨팅 성능(이미지 제공: Addy Osmani)(큰 미리보기)
  1. 클라이언트 측 렌더링 또는 서버 측 렌더링? 둘 다!
    꽤 열띤 대화입니다. 궁극적인 접근 방식은 일종의 프로그레시브 부팅을 설정하는 것입니다. 서버 측 렌더링을 사용하여 빠른 First Contentful Paint를 얻되, First Contentful Paint에 가깝게 대화식 시간을 유지하는 데 필요한 최소한의 JavaScript도 포함합니다. JavaScript가 FCP 이후에 너무 늦게 오는 경우 브라우저는 늦게 발견된 JavaScript를 구문 분석, 컴파일 및 실행하는 동안 기본 스레드를 잠그므로 사이트 또는 응용 프로그램의 상호 작용을 방해합니다.

    이를 방지하려면 항상 함수 실행 을 별도의 비동기 작업으로 나누고 가능한 경우 requestIdleCallback 을 사용하십시오. WebPack의 동적 import() 지원을 사용하여 UI의 지연 로드 부분을 고려하여 사용자가 실제로 필요할 때까지 로드, 구문 분석 및 컴파일 비용을 피하십시오( Addy에게 감사드립니다! ).

    위에서 언급했듯이 TTI(Time to Interactive)는 탐색과 상호 작용 사이의 시간을 알려줍니다. 구체적으로, 메트릭은 초기 콘텐츠가 렌더링된 후 첫 5초 창을 보고 정의되며, JavaScript 작업은 50ms ( 긴 작업 )보다 오래 걸리지 않습니다. 50ms를 초과하는 작업이 발생하면 5초 창 검색이 다시 시작됩니다. 결과적으로 브라우저는 먼저 Interactive 에 도달했다고 가정하고 Frozen 으로 전환하고 결국에는 Interactive 로 다시 전환합니다.

    Interactive 에 도달하면 필요에 따라 또는 시간이 허락하는 한 앱의 중요하지 않은 부분을 부팅할 수 있습니다. 불행히도 Paul Lewis가 지적했듯이 프레임워크에는 일반적으로 개발자에게 표시될 수 있는 우선 순위에 대한 간단한 개념이 없으므로 점진적 부팅은 대부분의 라이브러리 및 프레임워크에서 구현하기가 쉽지 않습니다.

    그래도 우리는 거기에 도달하고 있습니다. 요즘에는 우리가 탐색할 수 있는 몇 가지 선택 사항이 있으며 Houssein Djirdeh와 Jason Miller는 Rendering on the Web과 Jason과 Addy의 Modern Front-End Architectures에 대한 글에서 이러한 옵션에 대한 훌륭한 개요를 제공합니다. 아래의 개요는 그들의 뛰어난 작업을 기반으로 합니다.

    • 전체 서버 측 렌더링 (SSR)
      WordPress와 같은 클래식 SSR에서는 모든 요청이 전적으로 서버에서 처리됩니다. 요청된 콘텐츠는 완성된 HTML 페이지로 반환되며 브라우저는 즉시 이를 렌더링할 수 있습니다. 따라서 예를 들어 SSR 앱은 실제로 DOM API를 사용할 수 없습니다. First Contentful Paint와 Time to Interactive 사이의 간격은 일반적으로 작으며 HTML이 브라우저로 스트리밍되는 즉시 페이지를 렌더링할 수 있습니다.

      이것은 브라우저가 응답을 받기 전에 처리되기 때문에 클라이언트에서 데이터 가져오기 및 템플릿을 위한 추가 왕복을 방지합니다. 그러나 우리는 더 긴 서버 생각 시간 과 결과적으로 Time To First Byte로 끝나고 최신 응용 프로그램의 반응형 및 풍부한 기능을 사용하지 않습니다.

    • 정적 렌더링
      제품을 단일 페이지 애플리케이션으로 구축하지만 모든 페이지는 구축 단계로 최소한의 JavaScript를 사용하여 정적 HTML로 미리 렌더링됩니다. 이는 정적 렌더링을 사용하여 가능한 모든 URL에 대해 개별 HTML 파일을 미리 생성한다는 것을 의미합니다. 이는 많은 응용 프로그램에서 감당할 수 없는 것입니다. 그러나 페이지의 HTML을 즉석에서 생성할 필요가 없기 때문에 일관되게 빠른 첫 번째 바이트까지의 시간을 달성할 수 있습니다. 따라서 랜딩 페이지를 빠르게 표시한 다음 후속 페이지에 대한 SPA 프레임워크를 미리 가져올 수 있습니다. Netflix는 이 접근 방식을 채택하여 로딩 및 상호 작용 시간을 50%까지 줄였습니다.

    • (Re)Hydration을 사용한 서버 측 렌더링 (범용 렌더링, SSR + CSR)
      우리는 SSR과 CSR 접근 방식의 두 가지 장점을 모두 사용하려고 노력할 수 있습니다. 혼합된 수화와 함께 서버에서 반환된 HTML 페이지에는 완전한 클라이언트 측 애플리케이션을 로드하는 스크립트도 포함됩니다. 이상적으로는 (SSR과 같은) 빠른 First Contentful Paint를 달성한 다음 (재)수화로 렌더링을 계속합니다. 불행히도 그런 경우는 드뭅니다. 더 자주 페이지는 준비된 것처럼 보이지만 사용자의 입력에 응답할 수 없어 분노의 클릭과 이탈이 발생합니다.

      React를 사용하면 Express와 같은 노드 서버에서 ReactDOMServer 모듈을 사용한 다음 renderToString 메서드를 호출하여 최상위 구성 요소를 정적 HTML 문자열로 렌더링할 수 있습니다.

      Vue.js에서는 vue-server-renderer를 사용하여 renderToString 을 사용하여 Vue 인스턴스를 HTML로 렌더링할 수 있습니다. Angular에서는 @nguniversal 을 사용하여 클라이언트 요청을 완전히 서버에서 렌더링된 HTML 페이지로 전환할 수 있습니다. 완전히 서버에서 렌더링된 경험은 Next.js(React) 또는 Nuxt.js(Vue)를 사용하여 즉시 달성할 수도 있습니다.

      접근 방식에는 단점이 있습니다. 결과적으로 더 빠른 서버 측 렌더링을 제공하면서 클라이언트 측 앱의 완전한 유연성을 얻을 수 있지만 First Contentful Paint와 Time To Interactive 사이의 간격이 더 길어 지고 First Input Delay가 증가하게 됩니다. 재수화는 비용이 많이 들고 일반적으로 이 전략만으로는 Time To Interactive를 크게 지연시키기 때문에 충분하지 않습니다.

    • 점진적 수화(SSR + CSR)를 사용한 스트리밍 서버 측 렌더링
      Time To Interactive와 First Contentful Paint 사이의 간격을 최소화하기 위해 한 번에 여러 요청을 렌더링하고 생성되는 대로 콘텐츠를 청크로 보냅니다 . 따라서 콘텐츠를 브라우저로 보내기 전에 전체 HTML 문자열을 기다릴 필요가 없으므로 Time To First Byte가 향상됩니다.

      React에서는 renderToString() 을 사용하여 응답을 파이프하고 HTML을 청크로 보낼 수 있습니다. Vue에서는 파이프 및 스트리밍이 가능한 renderToStream()을 사용할 수 있습니다. React Suspense를 사용하면 그 목적으로도 비동기식 렌더링을 사용할 수 있습니다.

      클라이언트 측에서는 전체 응용 프로그램을 한 번에 부팅하는 대신 구성 요소를 점진적으로 부팅합니다 . 애플리케이션의 섹션은 먼저 코드 분할을 통해 독립 실행형 스크립트로 분할된 다음 점진적으로 수화됩니다(우선 순위에 따라). 사실, 우리는 중요한 구성 요소를 먼저 수화할 수 있고 나머지는 나중에 수화할 수 있습니다. 그런 다음 클라이언트 측 및 서버 측 렌더링의 역할을 구성 요소별로 다르게 정의할 수 있습니다. 그런 다음 일부 구성 요소가 표시되거나 사용자 상호 작용에 필요하거나 브라우저가 유휴 상태일 때까지 일부 구성 요소의 수화를 연기할 수도 있습니다.

      Vue의 경우 Markus Oberlehner는 가시성 또는 특정 사용자 상호 작용 시 구성 요소 수화를 가능하게 하는 초기 단계 플러그인인 vue-lazy-hydration뿐만 아니라 사용자 상호 작용 시 수화를 사용하여 SSR 앱의 대화형 시간을 줄이는 방법에 대한 가이드를 게시했습니다. Angular 팀은 Ivy Universal과 함께 점진적인 수분 공급을 위해 노력합니다. Preact 및 Next.js를 사용하여 부분 수화를 구현할 수도 있습니다.

    • 삼형제 렌더링
      서비스 워커가 있으면 초기/비JS 탐색에 스트리밍 서버 렌더링 을 사용할 수 있으며, 그런 다음 서비스 워커가 설치된 후 탐색을 위해 HTML 렌더링을 수행하도록 할 수 있습니다. 이 경우 서비스 작업자는 콘텐츠를 미리 렌더링하고 동일한 세션에서 새 보기를 렌더링하기 위해 SPA 스타일 탐색을 활성화합니다. 서버, 클라이언트 페이지 및 서비스 작업자 간에 동일한 템플릿 및 라우팅 코드를 공유할 수 있을 때 잘 작동합니다.

    DOM 렌더링, 서비스 작업자 사전 렌더링 및 서버 측 렌더링과 같은 3가지 위치에서 삼중형 렌더링이 작동하는 방식을 보여주는 그림
    서버, DOM 또는 서비스 작업자의 세 위치에서 동일한 코드 렌더링을 사용하는 삼중형 렌더링. (이미지 출처: Google Developers) (큰 미리보기)
    • 사전 렌더링이 포함된 CSR
      사전 렌더링은 서버 측 렌더링과 유사하지만 서버에서 페이지를 동적으로 렌더링하는 대신 빌드 시 애플리케이션을 정적 HTML로 렌더링합니다. 정적 페이지는 클라이언트 측 JavaScript가 많이 없어도 완전히 대화식이지만 사전 렌더링은 다르게 작동합니다 . 기본적으로 클라이언트 측 애플리케이션의 초기 상태를 빌드 시 정적 HTML로 캡처하는 반면 사전 렌더링에서는 페이지가 대화형이 되도록 클라이언트에서 애플리케이션을 부팅해야 합니다.

      Next.js를 사용하면 앱을 정적 HTML로 미리 렌더링하여 정적 HTML 내보내기를 사용할 수 있습니다. React를 사용하는 오픈 소스 정적 사이트 생성기인 Gatsby에서는 기본 JS 청크가 미리 로드되고 향후 경로가 미리 가져오는 빌드 중에 renderToStaticMarkup 메서드 대신 renderToString 메서드를 사용합니다. 간단한 정적 페이지에는 필요하지 않은 DOM 속성이 없습니다.

      Vue의 경우 Vuepress를 사용하여 동일한 목표를 달성할 수 있습니다. Webpack과 함께 prerender-loader를 사용할 수도 있습니다. Navi는 정적 렌더링도 제공합니다.

      결과적으로 Time To First Byte 및 First Contentful Paint가 향상되었으며 Time To Interactive와 First Contentful Paint 사이의 간격이 줄어듭니다. 내용이 많이 변경될 것으로 예상되는 경우 접근 방식을 사용할 수 없습니다. 또한 모든 페이지를 생성하려면 모든 URL을 미리 알아야 합니다. 따라서 일부 구성 요소는 사전 렌더링을 사용하여 렌더링될 수 있지만 동적인 것이 필요한 경우 콘텐츠를 가져오기 위해 앱에 의존해야 합니다.

    • 전체 클라이언트 측 렌더링 (CSR)
      모든 로직, 렌더링 및 부팅은 클라이언트에서 수행됩니다. 결과는 일반적으로 Time To Interactive와 First Contentful Paint 사이에 차이가 있습니다. 결과적으로 모든 것을 렌더링하려면 전체 앱을 클라이언트에서 부팅해야 하므로 애플리케이션 이 느려지는 경우가 많습니다 .

      JavaScript에는 성능 비용이 있으므로 응용 프로그램과 함께 JavaScript의 양이 증가함에 따라 JavaScript의 영향을 길들이기 위해서는 JavaScript의 공격적인 코드 분할 및 지연이 절대적으로 필요합니다. 이러한 경우에는 상호 작용이 많이 필요하지 않은 경우 일반적으로 서버 측 렌더링 이 더 나은 접근 방식입니다. 옵션이 아닌 경우 앱 셸 모델을 사용하는 것이 좋습니다.

      일반적으로 SSR은 CSR보다 빠릅니다. 그러나 여전히 많은 앱에서 매우 자주 구현됩니다.

    그래서, 클라이언트 측 또는 서버 측? 일반적으로 완전한 클라이언트 측 프레임워크의 사용을 절대적으로 필요한 페이지로 제한 하는 것이 좋습니다. 고급 응용 프로그램의 경우 서버 측 렌더링에만 의존하는 것도 좋은 생각이 아닙니다. 서버 렌더링과 클라이언트 렌더링 모두 제대로 수행되지 않으면 재앙이 됩니다.

    CSR이든 SSR이든 상관없이 중요한 픽셀을 가능한 한 빨리 렌더링하고 해당 렌더링과 Time To Interactive 사이의 간격을 최소화해야 합니다. 페이지가 많이 변경되지 않으면 사전 렌더링을 고려하고 가능한 경우 프레임워크 부팅을 연기합니다. 서버 측 렌더링을 사용하여 HTML을 청크로 스트리밍 하고 클라이언트 측 렌더링을 위해 점진적인 수화 를 구현하고 가시성, 상호 작용 또는 유휴 시간에 수화하여 두 가지 장점을 모두 얻을 수 있습니다.

클라이언트 측과 서버 측 렌더링 옵션을 비교하는 표
클라이언트 측과 서버 측 렌더링에 대한 옵션의 스펙트럼. 또한 Google I/O에서 애플리케이션 아키텍처의 성능 영향에 대한 Jason과 Houssein의 대화를 확인하십시오. (이미지 출처: Jason Miller) (큰 미리보기)
AirBnB 웹사이트의 왼쪽은 점진적인 수분 공급이 없고 오른쪽은 점진적 수분 공급이 있는 예
AirBnB는 점진적인 수분 공급을 실험하고 있습니다. 불필요한 구성 요소를 연기하고 사용자 상호 작용(스크롤) 또는 유휴 시간 동안 로드를 수행하고 테스트를 통해 TTI를 개선할 수 있음을 보여줍니다. (큰 미리보기)
  1. 우리는 얼마나 정적으로 봉사할 수 있습니까?
    큰 응용 프로그램에서 작업하든 작은 사이트에서 작업하든 간에, 즉석에서 동적으로 생성되는 것보다 CDN(예: JAM 스택)에서 정적으로 제공 할 수 있는 콘텐츠를 고려하는 것이 좋습니다. 개인화 옵션이 많은 수천 개의 제품과 수백 개의 필터가 있더라도 여전히 중요한 방문 페이지를 정적으로 제공하고 선택한 프레임워크에서 이러한 페이지를 분리하고 싶을 수 있습니다.

    많은 정적 사이트 생성기가 있으며 생성되는 페이지는 종종 매우 빠릅니다. 요청 시 서버나 클라이언트에서 페이지 보기를 생성하는 대신 미리 미리 구축할 수 있는 콘텐츠가 많을수록 더 나은 성능을 달성할 수 있습니다.

    부분적으로 수화되고 점진적으로 향상되는 정적 웹 사이트 구축에서 Markus Oberlehner는 정적 사이트 생성기와 SPA를 사용하여 웹 사이트를 구축하는 동시에 점진적 향상과 최소 JavaScript 번들 크기를 달성하는 방법을 보여줍니다. Markus는 Eleventy와 Preact 를 자신의 도구로 사용하고 도구 설정, 부분 수화, 지연 수화, 클라이언트 항목 파일 추가, Preact용 Babel 구성 및 Preact와 롤업 번들을 처음부터 끝까지 보여줍니다.

    요즘 대규모 사이트에서 JAMStack을 사용하면서 새로운 성능 고려 사항인 빌드 시간 이 나타났습니다. 사실, 새로 배포할 때마다 수천 페이지라도 빌드하는 데 몇 분이 걸릴 수 있으므로 WordPress, Contentful, Drupal, Netlify CMS와 같은 인기 있는 CMS 솔루션에 통합하여 빌드 시간을 60배 까지 개선하는 Gatsby의 증분 빌드를 볼 수 있을 것으로 기대됩니다. 다른 사람.

    증분 상태 재생성 프로세스를 보여주는 왼쪽 상단의 사용자 1과 왼쪽 하단의 사용자 2를 보여주는 순서도
    Next.js를 사용한 증분 정적 재생성. (이미지 크레디트: Prisma.io) (큰 미리보기)

    또한 Next.js는 사전 및 증분 정적 생성을 발표했습니다. 이를 통해 런타임 시 새로운 정적 페이지를 추가하고 트래픽이 들어올 때 백그라운드에서 다시 렌더링하여 이미 구축된 기존 페이지를 업데이트할 수 있습니다. .

    더 가벼운 접근 방식이 필요하십니까? Eleventy, Alpine 및 Tailwind: 가벼운 Jamstack을 향한 그의 강연에서 Nicola Goutay는 CSR, SSR 및 모든 것의 차이점을 설명하고 접근 방식을 보여주는 GitHub 리포지토리와 함께 더 가벼운 접근 방식을 사용하는 방법을 보여줍니다. 실제로.

  2. PRPL 패턴 및 앱 셸 아키텍처 사용을 고려하십시오.
    프레임워크에 따라 성능에 미치는 영향이 다르고 최적화 전략도 달라져야 하므로 의존하게 될 프레임워크의 모든 핵심 사항을 명확하게 이해해야 합니다. 웹 앱을 구축할 때 PRPL 패턴과 애플리케이션 셸 아키텍처를 살펴보세요. 아이디어는 매우 간단합니다. 초기 경로가 빠르게 렌더링되도록 대화식으로 전환하는 데 필요한 최소한의 코드를 푸시한 다음 리소스 캐싱 및 사전 캐싱에 서비스 작업자를 사용하고 필요한 경로를 비동기식으로 지연 로드합니다.
애플리케이션 셸 아키텍처의 PRPL 패턴
PRPL은 중요 리소스 푸시, 초기 경로 렌더링, 나머지 경로 사전 캐싱 및 요청 시 나머지 경로 지연 로드를 나타냅니다.
애플리케이션 셸 아키텍처
애플리케이션 셸은 사용자 인터페이스를 지원하는 최소한의 HTML, CSS 및 JavaScript입니다.
  1. API의 성능을 최적화했습니까?
    API는 애플리케이션이 엔드포인트 를 통해 내부 및 타사 애플리케이션에 데이터를 노출하는 통신 채널입니다. API를 설계하고 구축할 때 서버와 타사 요청 간의 통신을 가능하게 하는 합리적인 프로토콜이 필요합니다. REST (Representational State Transfer)는 잘 정립된 논리적 선택입니다. 이는 개발자가 콘텐츠에 성능이 좋고 안정적이며 확장 가능한 방식으로 액세스할 수 있도록 하기 위해 따라야 하는 일련의 제약 조건을 정의합니다. REST 제약 조건을 준수하는 웹 서비스를 RESTful 웹 서비스 라고 합니다.

    좋은 HTTP 요청과 마찬가지로 API에서 데이터를 검색할 때 서버 응답의 지연이 최종 사용자에게 전파되어 렌더링이 지연 됩니다. 리소스가 API에서 일부 데이터를 검색하려면 해당 엔드포인트에서 데이터를 요청해야 합니다. 주석이 있는 기사 및 각 주석에 작성자 사진과 같은 여러 리소스의 데이터를 렌더링하는 구성 요소는 렌더링되기 전에 모든 데이터를 가져오기 위해 서버로 여러 번 왕복해야 할 수 있습니다. 또한 REST를 통해 반환되는 데이터의 양은 해당 구성 요소를 렌더링하는 데 필요한 것보다 많은 경우가 많습니다.

    많은 리소스에 API의 데이터가 필요한 경우 API가 성능 병목 현상이 될 수 있습니다. GraphQL은 이러한 문제에 대한 고성능 솔루션을 제공합니다. 그 자체로 GraphQL은 API용 쿼리 언어이며 데이터에 대해 정의한 유형 시스템을 사용하여 쿼리를 실행하기 위한 서버 측 런타임입니다. REST와 달리 GraphQL은 단일 요청에서 모든 데이터를 검색할 수 있으며 일반적으로 REST에서 발생하는 데이터를 과도하게 또는 과소 하게 가져오지 않고 응답이 정확히 필요한 것입니다.

    또한 GraphQL은 스키마 (데이터가 구조화되는 방식을 알려주는 메타데이터)를 사용하기 때문에 이미 데이터를 원하는 구조로 구성할 수 있으므로 예를 들어 GraphQL을 사용하면 상태 관리를 처리하는 데 사용되는 JavaScript 코드를 제거할 수 있습니다. 클라이언트에서 더 빠르게 실행되는 더 깨끗한 애플리케이션 코드.

    GraphQL을 시작하거나 성능 문제가 발생하는 경우 다음 문서가 매우 유용할 수 있습니다.

    • GraphQL 입문서: 새로운 종류의 API가 필요한 이유 Eric Baer,
    • GraphQL 입문서: API 디자인의 진화 Eric Baer,
    • Leonardo Losoviz의 최적의 성능을 위한 GraphQL 서버 설계,
    • Wojciech Trocki가 설명하는 GraphQL 성능.
Redux/REST(왼쪽) 및 Apollo/GraphQL(오른쪽)을 사용하는 동안 메시지를 위한 모바일 인터페이스의 두 가지 예
왼쪽의 Redux + REST, 오른쪽의 Apollo + GraphQL 간의 대화를 통해 설명되는 REST와 GraphQL의 차이점. (이미지 출처: Hacker Noon) (큰 미리보기)
  1. AMP 또는 인스턴트 아티클을 사용하시겠습니까?
    조직의 우선 순위와 전략에 따라 Google의 AMP나 Facebook의 Instant Articles 또는 Apple의 Apple News 사용을 고려할 수 있습니다. 그것들 없이도 좋은 성능을 얻을 수 있지만 AMP 무료 CDN(콘텐츠 전달 네트워크)을 통해 견고한 성능 프레임워크를 제공하는 반면 인스턴트 아티클은 Facebook에서 가시성과 성능을 향상시킵니다.

    사용자를 위한 이러한 기술의 겉보기에 명백한 이점은 보장된 성능 이므로 때때로 사용자는 "일반" 및 잠재적으로 부풀려진 페이지보다 AMP-/Apple News/Instant Pages-링크를 선호할 수도 있습니다. 많은 타사 콘텐츠를 처리하는 콘텐츠가 많은 웹 사이트의 경우 이러한 옵션은 잠재적으로 렌더링 시간을 크게 단축하는 데 도움이 될 수 있습니다.

    그들이하지 않는 한. 예를 들어 Tim Kadlec에 따르면 "AMP 문서는 문서보다 빠른 경향이 있지만 반드시 페이지의 성능을 의미하지는 않습니다. AMP가 성능 관점에서 가장 큰 차이를 만드는 것은 아닙니다."

    웹사이트 소유자의 이점은 분명합니다. 해당 플랫폼에서 이러한 형식을 검색할 수 있고 검색 엔진에서 가시성을 높일 수 있다는 것입니다.

    글쎄, 적어도 예전에는 그랬다. AMP는 더 이상 Top Stories 의 요구 사항이 아니므로 게시자는 대신 AMP에서 기존 스택으로 이동할 수 있습니다( 감사합니다, Barry! ).

    그래도 AMP를 PWA의 데이터 소스로 재사용하여 프로그레시브 웹 AMP를 구축할 수도 있습니다. 단점? 분명히 벽으로 둘러싸인 정원에 존재하면 개발자가 콘텐츠의 별도 버전을 생성하고 유지 관리할 수 있는 위치에 놓이게 되며, Instant Articles 및 Apple News의 경우 실제 URL이 없는 경우 (Addy, Jeremy에게 감사드립니다!) .

  2. CDN을 현명하게 선택하십시오.
    위에서 언급했듯이 얼마나 많은 동적 데이터가 있는지에 따라 콘텐츠의 일부를 정적 사이트 생성기로 "아웃소싱"하여 CDN으로 푸시하고 CDN에서 정적 버전을 제공하여 섬기는 사람. 사실, 이러한 생성기 중 일부는 기본적으로 제공되는 많은 자동화된 최적화 기능을 갖춘 실제로 웹사이트 컴파일러입니다. 컴파일러가 시간이 지남에 따라 최적화를 추가함에 따라 컴파일된 출력은 시간이 지남에 따라 더 작아지고 빨라집니다.

    CDN은 동적 콘텐츠도 제공(및 오프로드)할 수 있습니다. 따라서 CDN을 정적 자산으로 제한할 필요가 없습니다. CDN이 압축 및 변환(예: 에지에서 이미지 최적화 및 크기 조정)을 수행하는지 여부, 페이지의 정적 및 동적 부분을 조합하는 에지 측 포함뿐만 아니라 서버 작업자, A/B 테스트에 대한 지원을 제공하는지 여부를 다시 확인하십시오. CDN 에지(즉, 사용자에게 가장 가까운 서버) 및 기타 작업. 또한 CDN이 QUIC(HTTP/3)를 통한 HTTP를 지원하는지 확인하십시오.

    Katie Hempenius는 좋은 CDN을 선택하는 방법 , 미세 조정하는 방법 및 평가할 때 염두에 두어야 할 모든 작은 사항에 대한 통찰력을 제공하는 환상적인 CDN 가이드를 작성했습니다. 일반적으로 콘텐츠를 최대한 적극적으로 캐시하고 Brotli, TLS 1.3, HTTP/2 및 HTTP/3과 같은 CDN 성능 기능을 활성화하는 것이 좋습니다.

    참고 : Patrick Meenan과 Andy Davies의 연구에 따르면 HTTP/2 우선 순위 지정은 많은 CDN에서 효과적으로 손상되었으므로 CDN을 선택할 때 주의하십시오. Patrick은 HTTP/2 Prioritization에 대한 자신의 강연에서 더 자세한 정보를 제공합니다( 감사합니다, Barry! ).

    ms 단위의 CDN 이름 및 쿼리 속도의 CDNPerf 미리 보기
    CDNPerf는 매일 3억 건의 테스트를 수집하고 분석하여 CDN에 대한 쿼리 속도를 측정합니다. (큰 미리보기)

    CDN을 선택할 때 기능에 대한 자세한 개요와 함께 다음 비교 사이트 를 사용할 수 있습니다.

    • Cloudfront, Aazure, KeyCDN, Fastly, Verizon, Stackpach, Akamai 및 기타 여러 업체에 대한 CDN 비교 매트릭스인 CDN 비교.
    • CDN Perf는 매일 3억 건의 테스트를 수집 및 분석하여 CDN에 대한 쿼리 속도를 측정하며 모든 결과는 전 세계 사용자의 RUM 데이터를 기반으로 합니다. 또한 DNS 성능 비교 및 ​​클라우드 성능 비교를 확인하십시오.
    • CDN Planet Guides는 Serve Stale, Purge, Origin Shield, Prefetch 및 Compression과 같은 특정 주제에 대한 CDN 개요를 제공합니다.
    • Web Almanac: CDN 채택 및 사용은 최고의 CDN 제공업체, RTT 및 TLS 관리, TLS 협상 시간, HTTP/2 채택 등에 대한 통찰력을 제공합니다. (안타깝게도 데이터는 2019년의 것입니다.)

목차

  1. 준비하기: 계획 및 측정항목
  2. 현실적인 목표 설정
  3. 환경 정의
  4. 자산 최적화
  5. 빌드 최적화
  6. 배달 최적화
  7. 네트워킹, HTTP/2, HTTP/3
  8. 테스트 및 모니터링
  9. 빠른 승리
  10. 한 페이지에 모든 것
  11. 체크리스트 다운로드(PDF, Apple Pages, MS Word)
  12. 다음 가이드를 놓치지 않으려면 이메일 뉴스레터를 구독하세요.