web.dev 엔지니어링 블로그 #1: 사이트 구축 및 웹 구성요소 사용 방법

이 글은 web.dev 엔지니어링 블로그의 첫 번째 게시물입니다. 앞으로 몇 달 동안 Google에서 얻은 활용 가능한 분석 정보를 공유해 드릴 수 있기를 바랍니다. 엔지니어링 블로그 태그가 포함된 게시물을 기대해 주세요. 여기에서는 정적 사이트의 빌드 프로세스와 (선택사항) 웹 구성요소 뒤에 있는 JavaScript

web.dev는 최신 웹 환경을 빌드하는 방법에 관한 콘텐츠를 제공하고 사이트의 실적을 측정할 수 있도록 지원합니다. 잘 알고 있는 사용자는 측정 페이지가 Chrome의 DevTools에서도 사용할 수 있는 Lighthouse의 인터페이스에 불과하다는 것을 알고 있을 수 있습니다. web.dev에 로그인하면 사이트에서 정기적으로 Lighthouse 감사를 실행하여 시간 경과에 따른 점수 변화를 확인할 수 있습니다. 측정 페이지는 매우 특별한 기능이므로 잠시 후 다시 살펴보겠습니다. 🎊

기본적으로 web.dev는 마크다운 파일 모음에서 생성된 정적 사이트입니다. Eleventy는 마크다운을 HTML로 쉽게 변환할 수 있는 세련되고 확장 가능한 도구이므로 이를 사용하도록 선택했습니다.

또한 asyncawait를 포함하여 type="module"를 지원하는 브라우저에만 제공되는 최신 JavaScript 번들도 사용합니다. 또한 상시 브라우저에서 지원되지만 소수의 이전 버전에서는 지원되지 않는 기능도 기꺼이 사용합니다. 정적 사이트이므로 콘텐츠를 읽는 데 JavaScript가 필요하지 않습니다.

정적 HTML을 생성하고 JavaScript를 롤업과 번들로 묶는 빌드 프로세스가 완료되면 테스트를 위해 간단한 정적 서버로 web.dev를 호스팅할 수 있습니다. 사이트는 거의 완전히 정적이지만 맞춤 Node.js 서버의 이점을 활용할 수 있는 몇 가지 특별한 요구사항이 있습니다. 여기에는 잘못된 도메인의 리디렉션과 향후 국제화 기능을 위한 사용자의 기본 언어를 파싱하는 코드가 포함됩니다.

정적 생성

web.dev의 각 페이지는 마크다운으로 작성됩니다. 모든 페이지에는 각 게시물의 메타데이터를 설명하는 앞부분이 포함됩니다. 이 메타데이터는 각 페이지의 레이아웃으로 수집되어 제목, 태그 등을 생성합니다. 예를 들면 다음과 같습니다.

---
layout: post
title: What is network reliability and how do you measure it?
authors:
  - jeffposnick
date: 2018-11-05
description: |
  The modern web is enjoyed by a wide swath of people…
---

The modern web is enjoyed by a wide swath of [people](https://www.youtube.com/watch?v=dQw4w9WgXcQ), using a range of different devices and types of network connections.

Your creations can reach users all across the world...

이 앞부분을 통해 저자, 게시일, 태그와 같은 임의의 속성을 정의할 수 있습니다. Eleventy는 지능적인 작업을 수행하려는 거의 모든 플러그인, 템플릿 또는 기타 컨텍스트에서 편리하게 앞부분을 데이터로 노출합니다. 데이터 객체에는 Eleventy에서 데이터 캐스케이드라고 설명하는 항목도 포함됩니다. 즉, 각 개별 페이지, 페이지에서 사용하는 레이아웃, 계층적 폴더 구조에 있는 데이터에서 가져온 다양한 데이터입니다.

각 고유한 레이아웃은 서로 다른 유형의 콘텐츠를 설명하며 다른 레이아웃에서 상속할 수 있습니다. web.dev에서 이 기능을 사용하여 다양한 유형의 콘텐츠 (예: 게시물 및 Codelab)를 올바르게 프레이밍하고 하나의 최상위 HTML 레이아웃을 계속 공유합니다.

컬렉션

Eleventy는 임의의 콘텐츠 모음을 프로그래매틱 방식으로 구축할 수 있는 방법을 제공합니다. 이를 통해 페이지로 나누기 지원을 빌드하고 게시물 작성자를 위한 가상 페이지 (디스크에 일치하는 마크다운 파일이 없는 페이지)를 생성할 수 있습니다. 예를 들어 Google에서는 퍼머링크 표현식 (모든 작성자에 대해 템플릿이 다시 렌더링됨)과 지원 컬렉션을 포함하는 템플릿을 사용하여 저자 페이지를 구성합니다.

예를 들어 애디의 모든 게시물이 포함된 간단한 페이지가 생성됩니다.

제한사항

현재 Eleventy의 빌드 프로세스는 명령형이 아닌 선언형이므로 쉽게 연결할 수 없습니다. 즉, 원하는 방식이 아니라 원하는 사항을 설명합니다. Eleventy는 명령줄 인터페이스를 통해서만 호출할 수 있으므로 더 큰 빌드 도구의 일부로 실행하기는 어렵습니다.

템플릿 생성

web.dev는 원래 Mozilla에서 개발한 Nunjucks 템플릿 시스템을 사용합니다. Nunjucks에는 루프 및 조건문과 같은 일반적인 템플릿 기능이 있지만 추가 HTML을 생성하거나 다른 로직을 호출하는 쇼트코드를 정의할 수도 있습니다.

정적 콘텐츠 사이트를 만드는 대부분의 팀과 마찬가지로 Google은 소규모로 시작하여 시간이 지남에 따라 쇼트코드를 추가했으며 지금까지 약 20개를 추가했습니다. 대부분은 맞춤 웹 구성요소를 포함하여 추가 HTML을 생성하기만 합니다. 예를 들면 다음과 같습니다.

{% Aside %}
See how Asides work in the web.dev codebase
{% endAside %}

최종적으로는 다음과 같습니다.

그러나 실제로 다음과 같은 HTML을 만듭니다.

<div class="aside color-state-info-text">
<p>See how Asides work in the web.dev codebase</p>
</div>

이 게시물의 범위에 해당하지 않지만 web.dev에서는 메타프로그래밍 언어의 한 유형으로 쇼트코드도 사용합니다. 단축 코드는 인수를 허용하며 인수 중 하나가 포함된 콘텐츠입니다. 쇼트코드는 아무것도 반환할 필요가 없으므로 상태를 빌드하거나 다른 동작을 트리거하는 데 사용할 수 있습니다. 🤔💭

스크립트 작성

앞서 언급한 바와 같이 web.dev는 정적 사이트이므로 JavaScript 없이 제공 및 사용할 수 있으며 type="module" 또는 다른 최신 코드를 지원하지 않는 이전 브라우저에서도 사용할 수 있습니다. 이는 모든 사용자가 web.dev에 액세스할 수 있도록 하기 위한 Google의 접근 방식에서 매우 중요한 부분입니다.

하지만 최신 브라우저용 코드는 두 가지 주요 부분으로 구성됩니다.

  1. 전역 상태, 애널리틱스, SPA 라우팅 코드가 포함된 부트스트랩 코드
  2. 사이트를 점진적으로 개선하는 웹 구성요소용 코드 및 CSS

부트스트랩 코드는 매우 간단합니다. web.dev는 새 페이지를 싱글페이지 애플리케이션 (SPA)으로 로드할 수 있으므로 로컬 <a href="..."> 요소의 클릭을 수신 대기하는 전역 리스너를 설치합니다. SPA 모델을 사용하면 사용자의 현재 세션에 관한 전역 상태를 유지할 수 있습니다. 그렇지 않으면 매번 새 페이지를 로드할 때마다 Firebase를 호출하여 사용자의 로그인 상태에 액세스해야 합니다.

또한 방문한 URL에 따라 사이트에 몇 가지 진입점을 지정하고 동적 import()를 사용하여 올바른 진입점을 로드합니다. 이렇게 하면 사이트가 코드로 개선되기 전에 사용자에게 필요한 바이트 수가 줄어듭니다.

웹 구성요소

웹 구성요소는 JavaScript에 제공된 런타임 기능을 캡슐화하는 맞춤 요소이며 <web-codelab>와 같은 맞춤 이름으로 식별됩니다. 이 디자인은 web.dev와 같이 대체로 정적 사이트에 적합합니다. 사이트의 HTML이 업데이트될 때 브라우저가 요소의 수명 주기를 관리하여 요소가 페이지에 연결되거나 연결 해제될 때 이를 요소에 올바르게 알립니다. 오래된 브라우저는 웹 구성요소를 완전히 무시하고 DOM에 남아 있는 모든 항목을 렌더링합니다.

각 웹 구성요소는 connectedCallback(), disconnectedCallback(), attributeChangedCallback()를 비롯한 메서드가 있는 클래스입니다. web.dev의 맞춤 요소는 대부분 복잡한 구성요소를 위한 간단한 기반을 제공하는 LitElement에서 상속됩니다.

web.dev는 많은 페이지에서 웹 구성요소를 사용하지만 측정 페이지보다 웹 구성요소가 더 필요한 곳은 없습니다. 다음 두 요소는 이 페이지에 표시되는 기능의 대부분을 제공합니다.

<web-url-chooser-container></web-url-chooser-container>
<web-lighthouse-scores-container></web-lighthouse-scores-container>

이러한 요소는 더 많은 기능을 제공하는 추가 요소를 만듭니다. 이러한 요소는 일반 마크다운 소스 코드의 일부일 뿐이며, Google 콘텐츠팀은 측정 노드뿐만 아니라 모든 페이지에 확장 기능을 추가할 수 있습니다.

웹 구성요소는 주로 React에서 인기를 얻은 컨테이너 구성요소 모델을 사용하지만, 이 모델은 이제 약간 시대에 뒤떨어졌습니다. 각 -container 요소는 글로벌 상태 (unistore에서 제공)에 연결된 후 시각적 요소를 렌더링하고, 이 요소는 스타일 또는 기타 내장 기능이 있는 실제 DOM 노드를 렌더링합니다.

전역 상태와 이를 사용하는 HTML 요소 간의 관계를 보여주는 다이어그램
전역 상태 및 웹 구성요소

가장 복잡한 웹 구성요소는 전역 작업 및 상태를 시각화하기 위해 존재합니다. 예를 들어 web.dev를 사용하면 즐겨찾는 사이트를 감사한 다음 측정 페이지에서 벗어날 수 있습니다. 돌아오면 작업이 아직 진행 중임을 알 수 있습니다.

간단한 구성요소는 전역 상태와 관계가 없는 정적인 콘텐츠를 순전히 개선하거나 놀라운 시각화를 만듭니다 (예: 각 선 그래프는 고유한 <web-sparkline-chart>임).

상담을 받아보시겠어요?

web.dev 엔지니어링팀 (Rob, Ewa, 마이클, )은 곧 더 많은 기술적 심층 분석을 진행할 예정입니다.

Google의 운영 방식을 들어보면 프로젝트에 대한 아이디어를 얻는 데 도움이 되기를 바랍니다. 이 블로그에 관해 궁금한 점이 있거나 주제 요청이 있으면 트위터로 문의해 주세요.