이전 모듈에서는 주요 렌더링 경로에 관한 몇 가지 이론에서 렌더링 차단 리소스와 파서 차단 리소스가 리소스 충돌로 인해 렌더링되어야 합니다. 이제 이면의 이론을 이해했으니 이제 중요한 스킬을 최적화하는 기법을 배울 준비가 되었습니다. 지정할 수도 있습니다.
페이지가 로드될 때 HTML 내에서 많은 리소스가 참조되어 CSS를 통한 모양과 레이아웃뿐만 아니라 상호작용성까지 갖춘 페이지 JavaScript를 통해 할 수 있습니다. 이 모듈에서는 이러한 리소스와 이러한 리소스가 페이지 로드 시간에 미치는 영향을 다룹니다.
렌더링 차단
이전 모듈에서 설명했듯이, CSS는 render-blocking 리소스입니다. 웹 브라우저가 콘텐츠를 렌더링하는 것을 차단하므로 CSS 객체 모델이 요청될 때까지 (CSSOM)이 구성됩니다. 브라우저가 렌더링을 차단하여 플래시가 잘못되는 것을 방지합니다. 스타일이 지정되지 않은 콘텐츠 (FOUC): 사용자 환경 관점에서 바람직하지 않음
이전 동영상에는 설명 없이 페이지를 볼 수 있는 간단한 FOUC가 사용할 수 있습니다. 이후에 페이지의 CSS가 완료되면 모든 스타일이 적용됩니다. 네트워크에서 로드가 완료되고, 페이지의 스타일이 지정되지 않은 버전이 스타일이 지정된 버전으로 즉시 대체됩니다.
일반적으로 말하자면, FOUC는 일반적으로 볼 수 없는 것이지만 개념은 브라우저가 렌더링을 차단하는 이유를 알고 있어야 합니다. CSS가 다운로드되어 페이지에 적용될 때까지 그대로 유지됩니다. 렌더링 차단 반드시 바람직하다고 할 수는 없지만, 최대 6초까지는 최대 64분까지 지속되는 것을 CSS를 최적화 상태로 유지하세요
파서 차단
파서 차단 리소스는 <script>
과 같은 HTML 파서를 중단합니다.
요소(async
또는 defer
속성이 없는 요소)를 사용합니다. 파서가
<script>
요소의 경우 브라우저에서 스크립트를 평가하고 실행해야 합니다.
계속해서 파싱하고 있습니다. 이는 의도적으로 설계된 것으로, 스크립트가
DOM이 생성 중인 동안 DOM을 수정하거나 액세스할 수 없습니다.
<!-- This is a parser-blocking script: -->
<script src="/script.js"></script>
외부 JavaScript 파일 (async
또는 defer
없음)을 사용할 때 파서는 다음과 같습니다.
파일이 검색된 시점부터 다운로드, 파싱 및 분석될 때까지
실행됩니다 인라인 JavaScript를 사용할 때 파서는 마찬가지로
인라인 스크립트가 파싱되고 실행됩니다.
미리 로드 스캐너
미리 로드 스캐너는 보조 HTML 형식의 브라우저 최적화입니다.
원시 HTML 응답을 스캔하여 찾아 추측에 따라 가져오는 파서
리소스를 발견하기 전에 기본 HTML 파서가 리소스를 발견하지 못할 수 있습니다. 대상
예를 들어 미리 로드 스캐너를 사용하면 브라우저에서
HTML 파서가 차단된 경우에도 <img>
요소에 지정된 리소스
CSS와 JavaScript 같은 리소스를 가져오고 처리할 수 있습니다.
미리 로드 스캐너를 활용하려면 중요한 리소스를 포함해야 합니다. 가 포함됩니다. 다음 리소스 로드 패턴은 미리 로드 스캐너에서 찾을 수 없는 경우
background-image
속성을 사용하여 CSS에 의해 로드된 이미지 이 이미지 참조는 CSS에 있으며 미리 로드 스캐너로 검색될 수 없습니다.- 삽입된
<script>
요소 마크업 형식으로 동적으로 로드된 스크립트 또는 동적import()
를 사용하여 로드된 모듈을 사용하여 DOM에 삽입할 수 있습니다. - 자바스크립트를 사용하여 클라이언트에서 렌더링된 HTML입니다. 이러한 마크업은 문자열이 있고 미리 로드로 검색할 수 없음 있습니다.
- CSS
@import
선언
이러한 리소스 로드 패턴은 모두 늦게 검색된 리소스이므로
미리 로드 스캐너의 이점을 누리지 못합니다 가능하면 항상 사용하지 마세요. 만약
이러한 패턴을 방지하는 것은 불가능하지만
리소스 검색 지연을 방지하는 preload
힌트
CSS
CSS는 페이지의 표시와 레이아웃을 결정합니다. 앞에서 설명한 것처럼 CSS는 렌더링 차단 리소스이므로 CSS를 최적화하면 전체 페이지 로드 시간에 미치는 영향
축소
CSS 파일을 축소하면 CSS 리소스의 파일 크기가 줄어들어 더 빨리 다운로드할 수 있습니다. 이는 주로 캠페인에서 콘텐츠를 삭제하는 방식으로 이루어집니다. 소스 CSS 파일(예: 공백 및 기타 보이지 않는 문자)을 만들고 다음과 같이 새로 최적화된 파일에 추가합니다.
/* Unminified CSS: */
/* Heading 1 */
h1 {
font-size: 2em;
color: #000000;
}
/* Heading 2 */
h2 {
font-size: 1.5em;
color: #000000;
}
/* Minified CSS: */
h1,h2{color:#000}h1{font-size:2em}h2{font-size:1.5em}
가장 기본적인 형태의 CSS 축소는 웹사이트의 FCP, 심지어는 LCP를 개선할 수 있습니다. 다음과 같은 도구 번들러는 프로덕션에서 이 최적화를 자동으로 수행할 수 있습니다. 살펴보겠습니다
사용하지 않는 CSS 삭제
브라우저는 콘텐츠를 렌더링하기 전에 할 수 있습니다. 파싱을 완료하는 데 필요한 시간에는 현재 페이지에서 사용되지 않습니다. 모든 CSS를 결합하는 번들러를 사용하는 경우 파일을 한 파일로 압축할 경우, 사용자가 다운로드하는 것보다 CSS를 더 많이 다운로드하는 것은 렌더링해야 할 수 있습니다.
현재 페이지에서 사용되지 않는 CSS를 찾으려면 Chrome의 노출 범위 도구를 사용하세요. DevTools를 사용할 수 있습니다.
<ph type="x-smartling-placeholder">![Chrome DevTools의 적용 범위 도구 스크린샷 하단 창에서 선택된 CSS 파일에 현재 페이지 레이아웃에서 사용하지 않는 상당한 양의 CSS가 표시됩니다.](https://web.developers.google.cn/static/learn/performance/optimize-resource-loading/image/fig-1.png?authuser=9&hl=ko)
사용하지 않는 CSS를 삭제하면 두 가지 효과가 발생합니다. 즉, 다운로드 수를 줄이는 것 외에도 브라우저가 렌더링되어야 하므로 렌더링 트리 구성을 최적화하게 됩니다. 더 적은 수의 CSS 규칙이 처리됩니다.
<ph type="x-smartling-placeholder">CSS @import
선언 피하기
편리해 보일 수 있지만 CSS에서는 @import
선언을 피해야 합니다.
/* Don't do this: */
@import url('style.css');
HTML에서 <link>
요소가 작동하는 방식과 마찬가지로 @import
선언은
를 사용하면 스타일 시트 내에서 외부 CSS 리소스를 가져올 수 있습니다. 이
이 두 가지 방법의 주요 차이점은 HTML <link>
요소가
HTML 응답에 포함되므로 CSS보다 훨씬 빨리 발견됨
@import
선언에서 다운로드한 파일을 찾습니다.
그 이유는 @import
선언이
태그가 포함된 CSS 파일을 먼저 다운로드해야 합니다. 이
그 결과로 요청 체인(CSS의 경우)이 지연됩니다.
시간이 얼마나 걸릴지를
예로 들 수 있습니다 또 다른 단점은
@import
선언을 사용하여 로드된 스타일 시트는
미리 로드되어 있어 렌더링 차단 리소스가 늦게 발견되는 리소스가 될 수 있습니다.
<!-- Do this instead: -->
<link rel="stylesheet" href="style.css">
대부분의 경우@import
<link rel="stylesheet">
요소 <link>
요소를 사용하면 스타일 시트가 다음과 같이 작동합니다.
@import
와 달리 동시에 다운로드되어 전체 로드 시간이 줄어듭니다.
선언을 사용하여 스타일시트를 연속으로 다운로드합니다.
중요한 인라인 CSS
CSS 파일을 다운로드하는 데 걸리는 시간으로 인해 페이지의 FCP가 증가할 수 있습니다. 인라이닝
<head>
문서의 중요한 스타일은
CSS 리소스를 제공하며, 올바르게 수행되면
사용자의 브라우저 캐시가 준비되지 않았습니다. 나머지 CSS를 로드할 수 있습니다.
비동기식으로 처리되거나 <body>
요소의 끝에 추가됩니다.
<head>
<title>Page Title</title>
<!-- ... -->
<style>h1,h2{color:#000}h1{font-size:2em}h2{font-size:1.5em}</style>
</head>
<body>
<!-- Other page markup... -->
<link rel="stylesheet" href="non-critical.css">
</body>
단점은 많은 양의 CSS를 인라인 처리하면 초기 HTML 응답입니다. HTML 리소스는 오랫동안 캐시될 수 없거나 이는 인라인된 CSS가 외부 스타일 시트에서 동일한 CSS를 사용합니다. 페이지 품질 테스트 및 측정 그만한 가치가 있는지 확인하기 위한 것입니다.
CSS 데모
자바스크립트
JavaScript는 웹에서 대부분의 상호작용을 유도하지만 대가가 따릅니다. JavaScript를 너무 많이 제공하면 페이지의 응답 속도가 느려질 수 있습니다. 상호작용을 늦추는 응답성 문제를 야기할 수도 있습니다. 사용자에게 좌절감을 줄 수 있습니다.
렌더링 차단 JavaScript
defer
또는 async
속성 없이 <script>
요소를 로드하면
스크립트가 다운로드되고 파싱되고
실행됩니다 마찬가지로 인라인 스크립트는 스크립트가 파싱될 때까지 파서를 차단합니다.
실행할 수 있습니다
async
및 defer
비교
async
및 defer
는 HTML을 차단하지 않고 외부 스크립트를 로드하도록 허용합니다.
반면에 type="module"
가 있는 스크립트 (인라인 스크립트 포함)는
자동으로 연기됩니다 그러나 async
와 defer
에는 다음과 같은 몇 가지 차이점이 있습니다.
이해하는 것이 중요합니다.
async
로 로드된 스크립트는 다운로드되는 즉시 파싱되고 실행됩니다.
defer
로 로드된 스크립트는 HTML 문서 파싱이
완료됨 - 브라우저의 DOMContentLoaded
이벤트와 동시에 발생합니다.
또한 async
스크립트는 비순차적으로 실행될 수 있지만 defer
스크립트는
마크업에 표시된 순서대로 실행됩니다.
클라이언트 측 렌더링
일반적으로 JavaScript를 사용하여 중요한 콘텐츠를 렌더링하거나 페이지의 LCP 요소를 참조하세요. 이를 클라이언트 측 렌더링이라고 하며 단일 페이지 애플리케이션 (SPA)에서 광범위하게 사용됩니다.
JavaScript로 렌더링된 마크업은 미리 로드 스캐너를 사용하지 않습니다. 클라이언트가 렌더링한 마크업 내에 포함된 마크업으로는 검색할 수 없습니다. 이 LCP 이미지와 같은 중요한 리소스의 다운로드가 지체될 수 있습니다. 브라우저 스크립트가 실행된 후에만 LCP 이미지 다운로드를 시작하고 요소를 DOM에 추가합니다. 결국 스크립트는 검색, 다운로드 및 파싱이 이루어집니다. 이를 중요한 요청이라고 하며 체인에 있으므로 피해야 합니다.
또한 JavaScript를 사용하여 마크업을 렌더링하면 탐색에 대한 응답으로 서버에서 다운로드한 마크업보다 긴 작업 합니다. 클라이언트 측 HTML 렌더링의 광범위한 사용은 상호작용 지연 시간 페이지의 DOM이 매우 큼: JavaScript가 HTML 문서를 수정할 때 상당한 렌더링 작업이 있습니다.
축소
CSS와 마찬가지로 JavaScript를 축소하면 스크립트 리소스의 파일 크기가 줄어듭니다. 이렇게 하면 다운로드가 더 빨라져 브라우저가 더 빠르게 파싱하고 컴파일하는 프로세스를 다루었습니다.
또한 자바스크립트를 축소하면 축소하는 것보다 한 단계 더 발전되어 기타 애셋(예: CSS)을 사용합니다. JavaScript가 축소되면 그러나 기호는 공백, 탭, 주석과 같은 것들이 아니라, 기호는 JavaScript가 짧아집니다. 이 과정을 삭제라고도 합니다. 받는사람 다음 자바스크립트 소스 코드를 살펴보겠습니다.
// Unuglified JavaScript source code:
export function injectScript () {
const scriptElement = document.createElement('script');
scriptElement.src = '/js/scripts.js';
scriptElement.type = 'module';
document.body.appendChild(scriptElement);
}
앞의 JavaScript 소스 코드를 ugl링하게 하면 결과가 예를 들면 다음과 같습니다.
// Uglified JavaScript production code:
export function injectScript(){const t=document.createElement("script");t.src="/js/scripts.js",t.type="module",document.body.appendChild(t)}
앞의 스니펫에서 사람이 읽을 수 있는 변수인
소스의 scriptElement
는 t
로 단축됩니다. 여러 영역에 적용했을 때
스크립트 컬렉션을 사용하면 비용 절감에 영향을 주지 않으면서도 상당한 비용을 절약할 수 있습니다.
웹 사이트의 프로덕션 JavaScript 기능이 제공하는 기능을 구현합니다.
번들러를 사용하여 웹사이트의 소스 코드를 처리하는 경우 프로덕션 빌드에서 자동으로 수행되는 경우가 많습니다 Uglifier(예: Terser, 또한 고도로 구성할 수 있어 고도화 알고리즘의 공격성으로 전환하여 비용을 절감해야 합니다. 그러나 일반적으로 모든 통합 도구의 기본값만으로도 출력 크기와 기능 보존 사이의 적절한 균형을 맞추는 것입니다.
JavaScript 데모
학습한 내용 테스트
브라우저에서 여러 CSS 파일을 로드하는 가장 좋은 방법은 무엇인가요?
@import
선언<link>
요소브라우저 미리 로드 스캐너는 어떤 역할을 하나요?
<link rel="preload">
요소 감지:
할 수 있습니다.
브라우저가 HTML 파싱을 일시적으로 차단하는 이유는 무엇인가요? 다운로드합니까?
다음 단계: 리소스 힌트로 브라우저 지원
이제 <head>
요소에 로드된 리소스가
다양한 측정항목에 영향을 미치므로 다음 문제로 넘어가겠습니다. 다음
리소스 힌트를 살펴보고 이러한 힌트를 통해
브라우저에서 리소스 로드 및 교차 출처 연결 열기
더 빠른 서버에서 실행되어야 합니다.