웹페이지 첫 화면 로딩 성능과 최적화 전략에 대한 심층 논의
AI 기반 코드 생성이 붐을 이루면서 React 코드 작성의 중요성이 줄어들고 있습니다. 이제 누구든지 무엇이든 React로 애플리케이션을 작성할 수 있습니다. 하지만 코드 작성은 언제나 퍼즐의 일부일 뿐입니다. 우리는 여전히 애플리케이션을 어딘가에 배포하고, 사용자에게 공개하고, 강력하게 만들고, 빠르게 만드는 등 수많은 작업을 수행해야 합니다. 어떤 AI도 이를 대신할 수 없습니다. 적어도 아직은 아닙니다.
오늘은 지원서를 빠르게 작성하는 방법에 집중해 보겠습니다. 그러기 위해서는 잠시 React에서 벗어나야 합니다. 왜냐하면 무언가를 빠르게 만들기 전에 먼저 "빠름"이 무엇인지, 이를 측정하는 방법, "빠름"에 영향을 줄 수 있는 것이 무엇인지 알아야 하기 때문입니다.
스포일러 경고: React는 학습 프로젝트를 제외하고 이 글에 등장하지 않습니다. 오늘은 성능 도구 사용 방법, Core Web Vitals 소개, Chrome 성능 패널, 초기 로드 성능이 무엇인지, 이를 측정할 수 있는 측정항목, 캐시 제어 및 다양한 네트워크 조건이 이에 미치는 영향 등 기본 사항에 대해 다룹니다.
브라우저를 열고 즐겨찾는 웹사이트로 이동하려고 하면 어떻게 되나요? GET 요청을 하기 위해 주소 표시줄에 "https://www.php.cn/link/63ea3fef646010a7255aec506626ea32를 입력하고 그 대가로 HTML 페이지를 받습니다.
이 작업을 수행하는 데 걸리는 시간을 '첫 번째 바이트까지의 시간'(TTFB)이라고 합니다. 즉, 요청이 전송된 시점과 결과가 도착하기 시작하는 시점 사이의 시간입니다. HTML을 수신한 후 브라우저는 이제 가능한 한 빨리 이 HTML을 사용 가능한 웹 사이트로 변환해야 합니다.
먼저 사용자에게 표시할 수 있는 가장 작고 가장 중요한 콘텐츠인 '주요 경로'를 화면에 렌더링합니다.
정확히 크리티컬 경로에 무엇이 포함되어야 하는지는 복잡한 질문입니다. 이상적으로는 모든 것이 사용자가 전체 경험을 즉시 볼 수 있도록 설계되었습니다. 그러나 다시 말하지만, "중요한" 경로이기 때문에 가능한 한 빨라야 하기 때문에 아무것도 아닙니다. 두 가지를 동시에 하는 것은 불가능하므로 절충이 필요합니다.
절충안은 이것이다. 브라우저는 "주요 경로"를 구축하려면 최소한 다음 유형의 리소스가 절대적으로 필요하다고 가정합니다.
브라우저는 서버에 대한 초기 요청에서 첫 번째 HTML(HTML)을 가져옵니다. 구문 분석을 시작하고 이를 통해 "중요 경로"를 완료하는 데 필요한 CSS 및 JS 파일에 대한 링크를 추출합니다. 그런 다음 서버에서 가져오기 요청을 보내고, 다운로드될 때까지 기다리고, 처리하고, 모두 합친 다음, 특정 순간이 끝나면 화면에 "중요 경로" 픽셀을 그립니다.
이러한 중요한 리소스가 없으면 브라우저는 초기 렌더링을 완료할 수 없기 때문에 이를 "렌더링 차단 리소스"라고 합니다. 물론 모든 CSS 및 JS 리소스가 렌더링을 차단하는 것은 아닙니다. 일반적으로만:
"주요 경로"를 렌더링하는 전체 프로세스는 대략 다음과 같습니다.
이 시점을 첫 번째 추첨(FP)이라고 부릅니다. 사용자가 화면에서 무언가를 볼 수 있는 기회는 이번이 처음입니다. 이런 일이 발생하는지 여부는 서버에서 보낸 HTML에 따라 다릅니다. 거기에 텍스트나 이미지 등 의미 있는 내용이 있는 경우 첫 번째 콘텐츠 페인트(FCP)가 발생하는 시점이기도 합니다. HTML이 빈 div인 경우 FCP는 나중에 발생합니다.
FCP(첫 번째 콘텐츠 페인트)는 인식된 초기 로드를 측정하므로 가장 중요한 성능 지표 중 하나입니다. 기본적으로 이는 사이트 속도에 대한 사용자의 초기 인상입니다.
이 순간까지, 사용자는 손톱을 물기 위해 빈 화면을 쳐다보고있었습니다. Google에 따르면, 좋은 FCP 번호는 1.8 초 미만입니다. 그 후, 사용자는 웹 사이트가 제공 할 수 있고 떠나기 시작할 수있는 콘텐츠에 대한 관심을 잃기 시작합니다.
로딩 성능
.
프로젝트 설정
<code>npm install</code>
빌드 프로젝트:
<code>npm run build</code>
서버 시작:
<code>npm run start</code>
"https://www.php.cn/link/66e8d052ec2230c66bd11ee6b5a0e3c8으로 이동하세요.
Chrome에서 분석하려는 웹사이트를 열고 Chrome DevTools를 엽니다. 거기에서 Performance 및 Lighthouse 패널을 찾아서 함께 배치합니다. 우리는 둘 다 필요합니다.
또한 이 문서에서 다른 작업을 수행하기 전에 '캐시 비활성화' 확인란이 활성화되어 있는지 확인하세요. 이는 최상위 네트워크 패널에 있어야 합니다.
이렇게 하면 처음 방문자, 즉 웹사이트를 방문한 적이 없고 아직 리소스를 캐시하지 않은 사람들을 시뮬레이션할 수 있습니다.
이제 Lighthouse 패널을 엽니다. 여기에는 몇 가지 설정과 "페이지 로드 분석" 버튼이 표시됩니다.
이 섹션에서는 페이지의 초기 로드에 대한 자세한 분석을 제공하는 "탐색" 패턴에 관심이 있습니다. 보고서는 다음과 같은 점수를 제공합니다.
로컬 성능은 완벽합니다. 놀랄 일도 아닙니다. 모든 것이 "내 컴퓨터에서 실행"됩니다.
다음 지표도 있습니다.
이 기사에 필요한 FCP 및 LCP 값이 바로 상단에 있습니다.
아래에서 점수를 높이는 데 도움이 될 수 있는 제안 목록을 확인할 수 있습니다.
각 제안을 확장하여 더 자세한 정보를 찾을 수 있으며 특정 주제를 설명하는 링크도 찾을 수 있습니다. 이 모든 것이 실행 가능한 것은 아니지만 성능에 대해 배우고 이를 개선할 수 있는 다양한 사항을 이해하기 시작하는 데 훌륭한 도구입니다. 이 보고서와 관련 링크를 읽는 것만으로도 몇 시간을 보낼 수 있습니다.
그러나 Lighthouse는 표면 정보만 제공하며 느린 네트워크 또는 낮은 CPU와 같은 다양한 시나리오를 시뮬레이션하는 것을 허용하지 않습니다. 이는 시간 경과에 따른 성과를 추적하기 위한 훌륭한 진입점이자 훌륭한 도구입니다. 무슨 일이 일어나고 있는지 더 깊이 이해하려면 성능 패널이 필요합니다.
처음 로드하면 성능 패널이 다음과 같이 표시됩니다.
태그가 있습니다. 우리가 알다시피, 레이블의 CSS 리소스는 장애물로 렌더링되므로 확인할 수 있습니다.
'네트워크' 섹션에서 '프레임' 및 '타이밍' 섹션을 찾을 수 있습니다.
정말 멋지네요. "타이밍" 섹션에서는 이전에 논의한 모든 지표(FP, FCP, LCP)와 아직 논의하지 않은 일부 지표를 볼 수 있습니다. 측정항목 위에 마우스를 올리면 소요된 정확한 시간을 확인할 수 있습니다. 이를 클릭하면 맨 아래에 있는 "요약" 탭이 업데이트되며, 여기서 이 측정항목에 대한 정보와 자세한 내용을 확인할 수 있는 링크를 찾을 수 있습니다. DevTools는 이제 사람들을 교육하는 데 중점을 두고 있습니다.
마지막으로 메인 부분입니다. 이는 기록된 타임라인 동안 메인 스레드에서 일어나는 일입니다.
여기서 'HTML 구문 분석' 또는 '레이아웃'과 같은 항목과 소요 시간을 확인할 수 있습니다. 노란색 부분은 JavaScript와 관련된 부분으로, 축소된 JavaScript가 포함된 프로덕션 버전을 사용하고 있기 때문에 약간 쓸모가 없습니다. 하지만 이 상태에서도 예를 들어 HTML 구문 분석 및 그리기 레이아웃과 비교하여 JavaScript 실행에 걸리는 시간을 대략적으로 알 수 있습니다.
네트워크와 메인을 모두 열어서 전체 화면을 차지할 때 성능 분석에 특히 유용합니다.
여기서 보면 내 서버가 매우 빠르고 번들이 매우 빠르고 작다는 것을 알 수 있습니다. 어떤 네트워크 작업도 병목 현상이 발생하지 않습니다. 상당한 시간이 필요하지 않으며 그 사이에 브라우저는 그냥 대기하고 자체 작업을 수행합니다. 따라서 여기에서 초기 로드 속도를 높이려면 "HTML 구문 분석"이 왜 그렇게 느린지 조사해야 합니다. 이는 그래프에서 가장 긴 작업입니다.
또는 절대적인 숫자를 보면 성능 측면에서 여기서는 아무것도 하면 안 됩니다. 전체 초기 로드 시간은 200ms 미만으로 Google이 권장하는 임계값보다 훨씬 낮습니다. 하지만 이 테스트를 매우 빠른 노트북에서 로컬로 실행하고(따라서 실제 네트워크 비용이 없음) 매우 기본적인 서버를 사용하기 때문에 이런 현상이 발생합니다.
실제 생활을 시뮬레이션할 시간입니다.
이 상황은 성능 최적화를 수행하기 전에 글로벌을 확인하고 병목 현상을 식별하는 것의 중요성을 강조합니다. LCP 값은 약 650 밀리 초이며, 그 중 약 560 밀리 초가 초기 HTML을 기다리는 데 사용됩니다. 반응 부분은 약 50 밀리 초입니다. 그것을 줄이고 25 밀리 초로 줄이려면 전체 상황에서는 4%에 불과합니다. 그것의 감소는 많은 노력이 필요합니다. 보다 효과적인 전략은 서버에 집중하고 왜 그렇게 느린 지 알아내는 것입니다.
어쨌든. 이 불쾌한 호주 인터넷을 시뮬레이션하고 성능 지표에서 어떤 일이 발생하는지 살펴 보겠습니다. 이를 위해 성능 탭에서 기존 레코드를 지우십시오 (재 장전 및 레코드 버튼 근처 버튼). 네트워크 설정 패널을 표시해야합니다
Chrome 버전에 표시되지 않으면 "네트워크"탭에서 동일한 설정을 사용할 수 있어야합니다.
이제 드롭다운 메뉴에서 프로필을 선택하고 공연 녹화를 다시 실행하세요. 무엇을 보셨나요? 나에게는 이렇게 보입니다. LCP 값은 거의 변경되지 않았습니다. 640ms에서 700ms로 약간 증가했습니다. 설명할 수 있는 초기 파란색 "서버" 섹션에는 변경 사항이 없습니다. 가장 기본적인 HTML만 전송하므로 다운로드하는 데 시간이 오래 걸리지 않습니다. 그러나 다운로드 가능한 리소스와 메인 스레드 간의 관계는 극적으로 변했습니다. 이제 렌더링 차단 CSS 파일의 영향을 확실히 볼 수 있습니다. "HTML 구문 분석" 작업이 완료되었지만 브라우저는 유휴 상태이며 CSS를 기다리고 있습니다. 다운로드될 때까지 아무것도 그릴 수 없습니다. 브라우저가 HTML을 구문 분석하는 동안 리소스가 거의 즉시 다운로드되었던 이전 이미지와 비교해 보세요. 이후에는 기술적으로 브라우저가 뭔가를 그릴 수도 있었지만 아무 것도 없고 HTML 파일에 빈 div만 전송되었습니다. 따라서 브라우저는 자바스크립트 파일이 다운로드되어 실행될 때까지 계속 대기합니다. 이 ~60ms의 대기 간격은 바로 LCP의 증가로 보이는 것입니다. 속도를 더 줄여서 어떻게 진행되는지 확인하세요. 새 네트워크 프로필을 만들고 이름을 "낮은 인터넷 대역폭"으로 지정한 다음 "낮은 인터넷 대역폭" 프로필에서 다운로드/업로드 번호를 복사하고 지연 시간을 40밀리초로 설정합니다. 그리고 다시 테스트를 실행해 보세요. LCP 값이 이제 거의 500ms로 증가했습니다. JavaScript 다운로드에는 약 300밀리초가 소요됩니다. 상대적으로 말하면 "HTML 구문 분석" 작업과 JavaScript 실행 작업의 중요성이 줄어들고 있습니다. 자신만의 프로젝트가 있다면 이 테스트를 실행해 보세요. 숫자를 촉진 할 것입니다.
: 100 mbps
지연 : 300 밀리 초
보장"이라고합니다. CDN 제공업체는 다양한 지리적 위치에 여러 서버를 보유합니다. 이러한 서버는 정적 리소스의 복사본을 저장하고 브라우저가 요청할 때 이를 사용자에게 보낼 수 있습니다. CDN은 기본적으로 원본 서버 주변의 소프트 레이어로, 외부 영향으로부터 서버를 보호하고 외부 세계와의 상호 작용을 최소화합니다. 실제 사람을 참여시키지 않고도 일반적인 대화를 처리할 수 있는 내성적인 사람들을 위한 AI 비서와 같습니다. 위의 예에서 서버는 노르웨이에 있고 클라이언트는 호주에 있으며 다음과 같은 이미지가 있습니다. CDN을 중간에 두고 이미지가 달라집니다. CDN은 예를 들어 호주 어딘가에 사용자와 더 가까운 서버를 보유하게 됩니다. 어느 시점에서 CDN은 원본 서버로부터 정적 리소스의 복사본을 받게 됩니다. 호주 또는 인근 지역의 사용자는 노르웨이 서버의 원본 대신 이러한 복사본을 받게 됩니다. 두 가지 중요한 목표를 달성합니다. 첫째, 사용자가 더 이상 직접 접속할 필요가 없기 때문에 원본 서버의 부하가 줄어듭니다. 둘째, 이제 사용자는 일부 JavaScript 파일을 다운로드하기 위해 바다를 건너지 않아도 되므로 이러한 리소스를 더 빠르게 얻을 수 있습니다. 그리고 위 시뮬레이션의 LCP 값은 960ms에서 640ms로 떨어졌습니다. 지금까지는 최초 방문 성능, 즉 사이트를 방문한 적이 없는 사람들을 위한 성능에 대해서만 논의했습니다. 하지만 사이트가 너무 좋아서 대부분의 처음 방문자가 일반 방문자가 되기를 바랍니다. 아니면 최소한 첫 번째 로드 후에 떠나지 않고 몇 페이지를 탐색하고 무언가를 구매할 수도 있습니다. 이 경우 일반적으로 브라우저는 정적 리소스(CSS 및 JS 등)를 캐시할 것으로 예상합니다. 즉, 리소스를 항상 다운로드하는 대신 로컬에 복사본을 저장합니다. 이 경우 성능 그래프와 수치가 어떻게 변하는지 살펴보겠습니다. 학습 프로젝트를 다시 엽니다. 개발 도구에서 네트워크를 이전에 생성한 "평균 3G"로 설정합니다. 대기 시간은 길고 대역폭은 낮으므로 차이를 즉시 확인할 수 있습니다. 그리고 "네트워크 캐시 비활성화" 확인란이 선택 해제되어 있는지 확인하세요. 먼저 브라우저를 새로 고쳐 최초 방문자를 제거하세요. 그런 다음 성능을 새로 고치고 측정합니다. 학습 프로젝트를 사용하는 경우 최종 결과는 다음과 같으므로 다소 놀랄 수 있습니다. CSS 및 JavaScript 파일은 여전히 네트워크 탭에서 매우 눈에 띄며 "요청 보내기 및 대기"("평균 3G" 프로필에서 설정한 대기 시간 설정)에서 약 300ms로 표시됩니다. 결과적으로 LCP는 가능한 한 낮지 않으며 브라우저가 CSS 차단을 기다리는 동안 300ms의 간격이 있습니다. 무슨 일이 일어났나요? 브라우저가 이 항목을 캐시하면 안 되나요? 이제 무슨 일이 일어나고 있는지 이해하기 위해 네트워크 패널을 사용해야 합니다. 그것을 열고 거기에서 CSS 파일을 찾으십시오. 다음과 같아야 합니다. 여기서 가장 흥미로운 점은 '상태' 열과 '크기'입니다. "크기"에서는 전체 CSS 파일의 크기가 아닙니다. 너무 작습니다. "상태"에서는 일반적인 200 "모든 것이 괜찮습니다" 상태가 아니라 뭔가 다른 304 상태입니다. 여기서 두 가지 질문이 있습니다. 200이 아닌 304인 이유와 요청이 전송된 이유는 무엇입니까? 캐싱이 작동하지 않는 이유는 무엇입니까? 먼저 304 응답입니다. 이는 잘 구성된 서버가 조건부 요청에 대해 보내는 응답입니다. 여기서 응답은 다양한 규칙에 따라 변경됩니다. 이러한 요청은 브라우저 캐시를 제어하는 데 자주 사용됩니다. 예를 들어 서버가 CSS 파일에 대한 요청을 받으면 파일이 마지막으로 수정된 시간을 확인할 수 있습니다. 이 날짜가 브라우저 측 캐시 파일의 날짜와 동일한 경우 본문이 비어 있는 304를 반환합니다(그래서 223B만 반환됩니다). 이는 브라우저가 이미 소유한 파일을 안전하게 재사용할 수 있음을 의미합니다. 대역폭을 낭비하고 다시 다운로드할 필요가 없습니다. 이것이 성능 사진에서 큰 "요청 보내기 및 대기" 숫자를 보는 이유입니다. 브라우저는 CSS 파일이 여전히 최신인지 확인하기 위해 서버에 요청하고 있습니다. 이것이 "콘텐츠 다운로드"가 0.33ms인 이유입니다. 서버는 "304 Unmodified"를 반환하고 브라우저는 이전에 다운로드한 파일을 재사용합니다. 이제 두 번째 질문 - 이 요청이 전송된 이유는 무엇인가요? 이 동작은 서버가 응답으로 설정하는 Cache-Control 헤더에 의해 제어됩니다. 요청/응답 세부 정보를 보려면 네트워크 패널에서 CSS 파일을 클릭하세요. "헤더" 탭의 "응답 헤더" 블록에서 "Cache-Control" 값을 찾습니다.
이 헤더에서는 다른 조합이있는 쉼표로 분리 할 수 있습니다. 이 예에는 두 가지가 있습니다
위 정보는 캐싱이 성능 만병통치약이며 모든 것을 최대한 적극적으로 캐시해야 한다는 것을 의미합니까? 절대 그렇지 않습니다! 무엇보다도, "기술에 정통하지 않은 고객"과 "브라우저 캐시를 지우는 방법을 전화로 설명해야 하는" 조합을 만들 가능성은 최고 수준의 개발자라도 공황 발작을 일으킬 수 있습니다. 캐싱을 최적화하는 방법은 수백만 가지가 있으며, 캐시 기간에 영향을 줄 수도 있고 그렇지 않을 수도 있는 다른 헤더와 함께 Cache-Control 헤더의 지시어 조합이 서버 구현에 따라 달라질 수도 있고 그렇지 않을 수도 있는 수백만 가지가 있습니다. 아마도 이 주제에 대해서만 여러 권의 책을 쓸 수 있을 것입니다. 캐싱 전문가가 되고 싶다면 https://web.dev/ 및 MDN 리소스의 기사부터 시작하여 탐색경로를 따르십시오. 안타깝게도 "여기에 모든 것에 대한 5가지 최고의 캐싱 전략이 있습니다."라고 말할 수 있는 사람은 없습니다. 기껏해야 대답은 다음과 같습니다. "이것, 이것, 이것과 결합된 이 사용 사례가 있다면 이 캐시 설정 조합은 좋은 선택이지만 이러한 문제에 유의하십시오." 모든 것은 리소스, 빌드 시스템, 리소스가 얼마나 자주 변경되는지, 캐시가 얼마나 안전한지, 잘못된 작업의 결과를 이해하는 것으로 귀결됩니다. 단, 한 가지 예외가 있습니다. 명확한 "모범 사례"가 있는 한 가지 예외는 최신 도구를 사용하여 구축된 웹 사이트용 JavaScript 및 CSS 파일입니다. Vite, Rollup, Webpack 등과 같은 최신 패키징 도구는 "불변" JS 및 CSS 파일을 생성할 수 있습니다. 물론 그것들은 실제로 "불변"하지는 않습니다. 그러나 이러한 도구는 파일 내용에 따라 달라지는 해시 문자열을 사용하여 파일 이름을 생성합니다. 파일 내용이 변경되면 해시도 변경되고 파일 이름도 변경됩니다. 결과적으로 웹 사이트가 배포되면 브라우저는 캐시 설정에 관계없이 파일의 새로운 복사본을 다시 가져옵니다. 이전에 CSS 파일의 이름을 수동으로 바꿨을 때와 마찬가지로 캐시가 "삭제"됩니다. 예를 들어 학습 프로젝트의 dist/assets 폴더를 살펴보세요. JS 및 CSS 파일에는 index-[hash] 파일 이름이 있습니다. 이 이름을 기억하고 npm run build를 몇 번 실행하세요. 이러한 파일의 내용은 변경되지 않았으므로 이름은 동일하게 유지됩니다. 이제 src/App.tsx 파일로 이동하여 console.log('bla') 같은 항목을 어딘가에 추가하세요. npm run build를 다시 실행하고 생성된 파일을 확인하세요. CSS 파일 이름은 동일하게 유지되지만 JS 파일 이름은 변경된 것을 볼 수 있습니다. 이 웹 사이트가 배포되면 다음에 반복 사용자가 이 웹 사이트를 방문할 때 브라우저는 캐시에 전혀 나타나지 않는 완전히 다른 JS 파일을 요청합니다. 캐시가 지워졌습니다.
추가 연습
다시 실행하십시오. 모든 네트워크 리소스의 "요청 및 대기"는 약 300 밀리 초로 늘려야합니다. 이것은 또한 이것은 아직 달성하지 않은 경우 모든 사람이 달성 해야하는 첫 번째 성능 개선을 상기시켜줍니다. "CDN을 통해 서비스를 제공하기 위해 정적 자원 반복 접속 성능
Cache-Control 헤더를 사용하여 브라우저 캐시 제어
추가 연습
추가 연습
캐시 제어 및 최신 번들링 도구
추가 운동
위 내용은 React 개발자의 초기 부하 성능 : 조사 깊은 다이빙의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!