Chrome 102에서는 DevTools에 새로운 실험용 패널인 성능 통계가 표시됩니다. 이 게시물에서는 새 패널로 작업하게 된 이유뿐만 아니라 Google이 당면한 기술적 어려움과 그 과정에서 내린 결정에 대해서도 다룹니다.
다른 패널을 빌드해야 하는 이유
실적 통계 패널을 빌드하는 이유와 이를 통해 웹사이트 실적에 관한 실행 가능한 통계를 얻는 방법을 설명하는 동영상을 아직 보지 못하신 경우 확인해 보세요.
기존 실적 패널은 웹사이트의 모든 데이터를 한곳에서 확인하고 싶을 때 유용한 리소스이지만 다소 부담스러울 수 있습니다. 공연 전문가가 아니라면 무엇을 찾아야 하고 녹음 파일의 어떤 부분이 관련이 있는지 정확히 알기 어렵습니다.
인사이트 패널로 이동하면 트레이스의 타임라인을 계속 보고 데이터를 검사할 수 있을 뿐만 아니라 DevTools에서 자세히 살펴볼 만한 주요 '인사이트'로 간주하는 항목의 유용한 목록을 확인할 수 있습니다. 통계는 렌더링 차단 요청, 레이아웃 변경, 장기 작업 등 웹사이트의 페이지 로드 성능, 특히 사이트의 코어 웹 바이탈 (CWV) 점수에 부정적인 영향을 미칠 수 있는 문제를 식별합니다. 성능 통계는 문제 신고와 함께 CWV 점수를 개선하기 위한 실행 가능한 제안을 제공하고 추가 리소스 및 문서 링크를 제공합니다.
이 패널은 실험 단계에 있으며 여러분의 의견을 기다립니다. 버그가 있거나 사이트의 실적을 개선하는 데 도움이 될 만한 기능 요청이 있으면 알려주세요.
실적 통계 제작 방법
나머지 DevTools와 마찬가지로 Performance Insights는 TypeScript로 빌드되었으며 lit-html의 지원을 받는 웹 구성요소를 사용하여 사용자 인터페이스를 빌드했습니다. 실적 통계의 차이점은 기본 UI 인터페이스가 HTML canvas
요소이고 타임라인이 이 캔버스에 그려진다는 점입니다. 이 캔버스를 관리하면 많은 복잡성이 발생합니다. 즉, 올바른 위치에 올바른 세부정보를 그리는 것뿐만 아니라 마우스 이벤트 (예: 사용자가 캔버스를 클릭한 위치)를 관리하는 것입니다. 사용자가 그린 이벤트를 클릭했나요?)를 확인하고 캔버스를 효과적으로 다시 렌더링합니다.
단일 캔버스에 여러 트랙
특정 웹사이트에 대해 렌더링하려는 여러 '트랙'이 있으며, 트랙은 각각 다른 데이터 카테고리를 나타냅니다. 예를 들어 통계 패널에는 기본적으로 다음과 같은 세 가지 트랙이 표시됩니다.
패널에 기능이 계속 추가됨에 따라 더 많은 트랙이 추가될 예정입니다.
처음에는 이러한 각 트랙이 자체 <canvas>
를 렌더링하여 기본 뷰가 세로로 쌓인 여러 개의 캔버스 요소가 되도록 할 계획이었습니다. 이렇게 하면 각 트랙을 개별적으로 렌더링할 수 있고 트랙이 경계를 벗어나 렌더링될 위험이 없으므로 트랙 수준에서 렌더링이 간소화되지만 안타깝게도 이 접근 방식에는 두 가지 주요 문제가 있습니다.
canvas
요소는 (다시) 렌더링하는 데 비용이 많이 듭니다. 캔버스가 더 크더라도 여러 개의 캔버스를 사용하는 것이 하나의 캔버스를 사용하는 것보다 비용이 더 많이 듭니다.
여러 트랙에 걸쳐 있는 오버레이 (예: FCP 시간과 같은 이벤트를 표시하는 세로선)를 렌더링하는 것이 복잡해집니다. 여러 캔버스에 렌더링하고 모두 함께 렌더링되고 올바르게 정렬되는지 확인해야 합니다.
전체 UI에 하나의 canvas
를 사용하기 위해서는 각 트랙이 올바른 좌표에서 렌더링되고 다른 트랙으로 오버플로되지 않도록 하는 방법을 찾아야 했습니다. 예를 들어 특정 트랙의 높이가 100픽셀인 경우 120픽셀 높이의 항목을 렌더링하여 아래 트랙으로 블러드되도록 허용할 수 없습니다. 이 문제를 해결하려면 clip
를 사용하면 됩니다. 각 트랙을 렌더링하기 전에 표시되는 트랙 창을 나타내는 직사각형을 그립니다. 이렇게 하면 이 경계 밖에 그려진 모든 경로가 캔버스에 의해 잘립니다.
canvasContext.beginPath();
canvasContext.rect(
trackVisibleWindow.x, trackVisibleWindow.y, trackVisibleWindow.width, trackVisibleWindow.height);
canvasContext.clip();
또한 각 트랙이 세로 위치를 알아야 하는 것도 원치 않았습니다. 각 트랙은 (0, 0)에서 렌더링하는 것처럼 자체적으로 렌더링해야 하며, 전체 트랙 위치를 관리하는 상위 수준 구성요소 (TrackManager
라고 함)가 있습니다. 캔버스를 주어진 (x, y) 위치로 변환하는 translate
를 사용하면 됩니다. 예를 들면 다음과 같습니다.
canvasContext.translate(0, 10); // Translate by 10px in the y direction
canvasContext.rect(0, 0, 10, 10); // draw a rectangle at (0, 0) that’s 10px high and wide
rect
코드에서 0, 0
를 위치로 설정하더라도 전체 변환이 적용되면 직사각형이 0, 10
에서 렌더링됩니다. 이렇게 하면 (0, 0)에서 렌더링하는 것처럼 트랙 기준으로 작업할 수 있으며 각 트랙을 렌더링할 때 트랙 관리자가 변환하여 각 트랙이 이전 트랙 아래에 올바르게 렌더링되도록 할 수 있습니다.
트랙 및 하이라이트의 오프스크린 캔버스
캔버스 렌더링은 상대적으로 비용이 많이 들며, Google에서는 사용자가 통계 패널을 사용할 때 원활하고 반응이 빠르게 유지되도록 하기 위해 노력하고 있습니다. 전체 캔버스를 다시 렌더링해야 하는 경우도 있습니다. 예를 들어 확대/축소 수준을 변경하면 다시 시작하여 모든 항목을 다시 렌더링해야 합니다. 캔버스 재렌더링은 특히 비용이 많이 듭니다. 캔버스의 일부만 재렌더링할 수 없기 때문입니다. 전체 캔버스를 지우고 다시 그려야 합니다. 이는 도구가 필요한 최소 작업을 계산하고 모든 항목을 삭제하지 않고 다시 시작할 수 있는 DOM 렌더링과는 다릅니다.
시각적 문제가 발생한 영역 중 하나는 강조 표시였습니다. 창에서 측정항목 위로 마우스를 가져가면 타임라인에서 해당 측정항목이 강조표시되고, 마찬가지로 특정 이벤트에 대한 통계 위로 마우스를 가져가면 해당 이벤트 주위에 파란색 테두리가 그려집니다.
이 기능은 처음에는 강조 표시를 트리거하는 요소 위로 마우스를 움직일 때 이를 감지한 다음 강조 표시를 기본 캔버스에 직접 그려서 구현되었습니다. 하이라이트를 삭제해야 할 때 문제가 발생합니다. 유일한 방법은 모든 내용을 다시 그리는 것입니다. 강조 표시된 영역을 다시 그리는 것은 불가능합니다 (큰 구조 변경 없이는 불가능). 하지만 하나의 항목 주위의 파란색 테두리를 삭제하기 위해 전체 캔버스를 다시 그리는 것은 과도한 작업으로 느껴졌습니다. 또한 여러 항목 위로 마우스를 빠르게 이동하여 여러 하이라이트가 빠르게 연속으로 트리거되는 경우 시각적으로 지연되기도 합니다.
이 문제를 해결하기 위해 UI를 두 개의 화면 밖 캔버스, 즉 트랙이 렌더링되는 '기본' 캔버스와 하이라이트가 그려지는 '하이라이트' 캔버스로 분할했습니다. 그런 다음 이러한 캔버스를 사용자에게 화면에 표시되는 단일 캔버스에 복사하여 렌더링합니다. 다른 캔버스를 소스로 사용할 수 있는 캔버스 컨텍스트에서 drawImage
메서드를 사용할 수 있습니다.
이렇게 하면 강조 표시를 삭제해도 기본 캔버스가 다시 그려지지 않습니다. 대신 화면 캔버스를 지운 다음 기본 캔버스를 표시된 캔버스에 복사할 수 있습니다. 캔버스를 복사하는 작업은 비용이 적게 들지만 그리기는 비용이 많이 듭니다. 따라서 강조 표시를 별도의 캔버스로 이동하면 강조 표시를 켜거나 끌 때 발생하는 비용을 방지할 수 있습니다.
포괄적으로 테스트된 트레이스 파싱
새 기능을 처음부터 빌드하는 이점 중 하나는 이전에 선택한 기술을 반영하고 개선할 수 있다는 것입니다. 개선하고자 했던 사항 중 하나는 코드를 거의 완전히 구분된 두 부분으로 명시적으로 분할하는 것이었습니다.
트레이스 파일을 파싱하고 필요한 데이터를 가져옵니다. 트랙 세트를 렌더링합니다.
파싱 (1부)을 UI 작업 (2부)과 별개로 유지하여 견고한 파싱 시스템을 구축할 수 있었습니다. 각 트레이스는 다양한 문제를 담당하는 일련의 핸들러를 통해 실행됩니다. LayoutShiftHandler
는 레이아웃 전환에 필요한 모든 정보를 계산하고 NetworkRequestsHandler
는 네트워크 요청 가져오기만 처리합니다. 트레이스의 여러 부분을 담당하는 여러 핸들러가 있는 명시적 파싱 단계를 사용하는 것도 유용했습니다. 트레이스 파싱은 매우 복잡해질 수 있으며 한 번에 하나의 문제에 집중하는 데 도움이 됩니다.
또한 DevTools에서 녹화한 후 저장하고 테스트 모음의 일부로 로드하여 트레이스 파싱을 포괄적으로 테스트할 수 있었습니다. 실제 트레이스로 테스트할 수 있고 쓸모가 없어질 수 있는 엄청난 양의 가짜 트레이스 데이터를 축적할 수 없기 때문에 유용합니다.
캔버스 UI의 스크린샷 테스트
테스트 주제에 관해 말하자면, 일반적으로 프런트엔드 구성요소를 브라우저에 렌더링하고 예상대로 작동하는지 확인하여 테스트합니다. 클릭 이벤트를 전달하여 업데이트를 트리거하고 구성요소가 생성하는 DOM이 올바른지 어설션할 수 있습니다. 이 접근 방식은 괜찮지만 캔버스에 렌더링하는 경우에는 문제가 됩니다. 캔버스를 검사하고 그려진 내용을 확인할 방법이 없기 때문입니다. 따라서 렌더링 후 쿼리하는 일반적인 접근 방식은 적절하지 않습니다.
테스트 범위를 넓히기 위해 스크린샷 테스트로 전환했습니다. 각 테스트는 캔버스를 실행하고 테스트할 트랙을 렌더링한 후 캔버스 요소의 스크린샷을 찍습니다. 그런 다음 이 스크린샷은 코드베이스에 저장되고, 향후 테스트 실행에서는 저장된 스크린샷을 생성된 스크린샷과 비교합니다. 스크린샷이 다르면 테스트가 실패합니다. 또한 렌더링을 의도적으로 변경하여 테스트를 업데이트해야 하는 경우 테스트를 실행하고 스크린샷 업데이트를 강제하는 플래그도 제공합니다.
스크린샷 테스트는 완벽하지 않으며 약간 무방합니다. 좀 더 구체적인 어설션이 아닌 전체 구성요소가 예상대로 렌더링되는지만 테스트할 수 있습니다. 초기에는 모든 구성요소 (HTML 또는 캔버스)가 올바르게 렌더링되도록 하기 위해 이 테스트를 과도하게 사용한 탓에 유죄입니다. 이로 인해 테스트 모음이 급격히 느려졌고, 거의 관련이 없는 사소한 UI 변경 (예: 미세한 색상 변경 또는 항목 간 여백 추가)으로 인해 여러 스크린샷이 실패하고 업데이트가 필요한 문제가 발생했습니다. 이제 스크린샷 사용을 축소하고 캔버스 기반 구성요소에만 사용하고 있으며, 지금까지는 이 균형이 잘 맞았습니다.
결론
새로운 실적 통계 패널을 만드는 것은 팀에 있어 매우 즐겁고 유익한 경험이었습니다. 트레이스 파일, 캔버스 작업 등에 대해 알아봤습니다. 새 패널을 유용하게 활용하시기 바라며, 여러분의 의견을 기다리겠습니다.
실적 통계 패널에 대해 자세히 알아보려면 실적 통계: 웹사이트 실적에 관한 실행 가능한 통계 확인하기를 참고하세요.
미리보기 채널 다운로드
Chrome Canary, Dev 또는 베타를 기본 개발 브라우저로 사용하는 것이 좋습니다. 이러한 미리보기 채널을 사용하면 최신 DevTools 기능에 액세스하고, 최신 웹 플랫폼 API를 테스트하고, 사용자가 발견하기 전에 사이트에서 문제를 찾을 수 있습니다.
Chrome DevTools팀에 문의하기
다음 옵션을 사용하여 새로운 기능, 업데이트 또는 DevTools와 관련된 다른 내용을 논의하세요.
- crbug.com에서 의견 및 기능 요청을 제출하세요.
- DevTools에서 옵션 더보기 > 도움말 > DevTools 문제 신고를 사용하여 DevTools 문제를 신고합니다.
- @ChromeDevTools에 트윗하세요.
- DevTools의 새로운 기능 YouTube 동영상 또는 DevTools 도움말 YouTube 동영상에 댓글을 남겨주세요.