
알아두면 좋은 프론트엔드 성능에 대해
원제 : 12 Front End Performance Patterns You Need to Know
1초가 걸리던 로딩 시간이 5초로 늘어나게 되면, 사용자 이탈률이 90%까지 증가하게 됩니다. - 2017년, 구글 조사 결과
이번 장에서 다루는 내용이 꽤나 많기 때문에, 제가 시간을 들여 제작한 프론트엔드 성능 최적화 패턴 및 최적화 방법이 담긴 요약 자료를 별도로 준비했습니다. (역주 : 메일링에 동의하면 곧바로 제공되는 자료인데, 꽤나 퀄리티가 뛰어나 받아보실 가치가 있다고 생각합니다!)
이번 장은 파트 1, 2에 대한 지식이 없어도 읽을 수 있지만 파트 1, 2를 먼저 읽고 오신다면 더 강한 시너지를 발휘할 수 있는데요, 이제 이번 장에서 무엇을 배울지 알았으니 바로 시작해 보도록 하겠습니다!
1. SWR을 사용한 SSG - 가장 빠르고 최적화된 렌더링 패턴
역주 : SSG는 서버 사이드 렌더링과 관련된 용어로, 페이지를 클라이언트에서 동적으로 렌더링하는 SPA와달리 서버에서 페이지를 생성해 클라이언트로 전송하는 방식을 의미합니다.
어플리케이션의 렌더링 방법은 다른 중요한 요소들처럼 여러분의 프론트엔드 성능에 매우 중요한 영향을 미치는데요, 따라서 이를 첫 번째로 다루기로 했습니다.
어플리케이션의 목적과 상황에 맞는 가장 최적화된 렌더링 방법을 선택하는 것은 중요한 과제입니다.
여러분의 어플리케이션을 렌더링하는 방법은 클라이언트 사이드 렌더링, 서버 사이드 렌더링, 정적 사이트 생성의 3가지가 있으며, 각 방법별 장단점과 가장 적합한 상황이 존재합니다.
이번 글에서는 세 방법을 짧게 설명하겠지만, 가장 최적화된 렌더링 방법에 대한 설명을 주로 해보려 합니다. 이 방법은 보통의 클라이언트 사이드 렌더링처럼 직관적이지는 않지만, 만약 이게 그렇게 간단한 문제였다면 느린 어플리케이션 로딩속도로 고민할 일이 없었을 것입니다.
2019년 전후로 정적 페이지 생성방식(SSG)은 주류가 되었고, 가능한 방법 중 렌더링 속도가 제일 빠른 방법이었기 때문에 가능한 모든 곳에 이를 적용해야만 했습니다. 어플리케이션이 매우 거대하거나 유저 검증 등의 작업을 필요로 하더라도 SSG 렌더링 방식을 사용할 수 있었습니다.
정적 페이지 생성방식의 전제는 사전에 생성된 페이지에 빌드 시 페칭한 데이터를 포함해 클라이언트로 전송하는 것인데요, 그렇다고 해서 정적 페이지 생성방식이 인증이나 자주 업데이트되는 데이터를 사용하는 어플리케이션에 부적합하다는 것은 아닙니다. 어플리케이션의 동적인 부분을 빌드 시점에 제어할 수는 없지만, 이는 클라이언트에서 동작하는 자바스크립트(자바스크립트를 통해 인증 및 변화하는 데이터를 관리할 수 있습니다.)를 통해 해결할 수 있습니다.

이는 위 사진처럼 페이지의 뼈대가 되는 부분을 정적으로 제공하고, 유저 인증을 포함한 사용자 고유의 데이터나 자주 변경되는 데이터의 처리는 자바스크립트를 통해 관리할 수 있음을 의미합니다.
게다가 여기에 stale-while-revalidate(SWR) 패턴을 적용하면 스켈레톤 페이지를 캐싱된 데이터(stale)로 업데이트하고, 새로운 요청을 보내(revalidate), 필요한 부분에만 UI 업데이트를 진행할 수도 있습니다.
이를 적용하면 초기 스켈레톤 페이지가 거의 즉시 렌더링되는 것처럼 보임과 동시에 빠르고 반응적인 UI를 구성할 수 있게 됩니다. 결과적으로 클라이언트 사이드 렌더링 방식을 사용할 때 빈 페이지에 로딩 스피너를 보여주거나, 서버 사이드 렌더링 방식에서 오랜 지연을 거쳐 완성된 페이지를 제공하는 것보다 훨씬 나은 사용자 경험을 제공할 수 있게 됩니다.
다만 이 패턴은 일반적인 클라이언트 사이드 렌더링 방식이나 서버 사이드 렌더링 방식에 비해 구현하기 어렵습니다. 그러나 여러분이나 여러분의 개발 조직이 새로운 방식을 적용해볼 준비만 되어 있다면 이는 가장 빠른 렌더링 방법일 뿐만 아니라 사용자에게도 가장 나은 사용자 경험을 제공하는 렌더링 방법인데요, Next.js는 여러분의 어플리케이션에 해당 패턴을 가장 쉽게 제공해줄 방법을 제공합니다.
역주 : 정적 페이지 생성 방식 + SWR 방식은 next.js의 ISR 이라는 렌더링 방식으로 구현할 수 있습니다!

2. CSR vs SSR vs SSG
클라이언트 사이드 렌더링은 모든 페이지를 자바스크립트로 렌더링해 모든 작업 부하를 브라우저에게 맡기게 됩니다. 이는 개발자들이 구현하기 쉽고, 어플리케이션의 규모가 작을 때는 빠른 렌더링 속도를 제공합니다. 그러나 어플리케이션 규모가 커질수록 브라우저가 내려받게 되는 자바스크립트 번들 용량은 점차 커지게 되며, 브라우저는 추가로 페이지를 구성하기 위한 데이터를 불러와야만(fetch) 합니다. 따라서 첫 페이지를 불러오는데 걸리는 시간의 비율이 커지게 되며, 어플리케이션의 규모가 커질수록 자바스크립트 번들을 내려받고 실행하는 긴 시간동안 사용자는 하얗게 빈 화면을 봐야만 합니다.
서버 사이드 렌더링은 두 가지 렌더링 과정을 포함하는데요, 먼저 서버에서 데이터 페칭을 수행하고 완전히 렌더링이 끝난 페이지를 브라우저에 전달합니다. 브라우저는 HTML 파일을 렌더링하고 자바스크립트 파일을 내려받습니다. 이후 브라우저가 자바스크립트 파일을 실행함으로써 페이지를 상호작용이 가능한 상태로 만듭니다. 서버 사이드 렌더링은 대부분의 작업을 서버에서 수행하는 만큼 느린 인터넷을 사용하는 사용자에게 더 빠른 렌더링을 제공할 수 있으며, 클라이언트 사이드 렌더링이 서버에서 빈 페이지를 받아왔던 것과는 달리 완전히 렌더링이 끝난 결과물을 서버에서 받아와 검색 엔진이 쉽게 인덱싱과 컨텐츠 크롤링을 수행할 수 있게 함으로써 SEO(검색 엔진 최적화)에도 효과적입니다.
정적 사이트 생성은 서버 사이드 렌더링이나 클라이언트 사이드 렌더링보다 훨씬 빠릅니다. 정적 사이트 렌더링은 빌드 시점에 데이터 페칭과 HTML 생성을 모두 수행합니다. 사전에 생성된 HTML 페이지가 웹 서버에 배포되고, 브라우저가 서버에 요청을 보내면 수 밀리초 안에 렌더링이 가능한 경량화된 HTML을 내려받게 됩니다. 이는 매우 빠를 뿐만 아니라 SEO에도 효과적입니다.
정적 사이트 생성 방식이 모든 곳에서 쓰이지 않는 이유는 바로 이전 장에서 살펴봤습니다. 많은 수의 어플리케이션이 수시로 업데이트되는 데이터와 인증 관련 로직을 포함하고 있어, 많은 개발자들은 정적 사이트 생성 방식이 이와는 맞지 않다고 생각했겠지만 실제로는 동적인 부분에서만 자바스크립트를 활용하고 나머지 부분(스켈레톤 페이지)은 정적으로 구성할 수 있습니다.
이제 여러분은 서버 사이드 렌더링과 클라이언트 사이드 렌더링의 장점만을 챙길 수 있게 되었고, 바로 이 점이 정적 페이지 생성 방식과 stale-while-revalidate 방식이 가장 빠르고 최적화된 렌더링 패턴인 이유입니다.

3. 클라이언트 성능 분석하기
다른 프론트엔드 성능 최적화 패턴을 알아보기 전에, 클라이언트 성능 분석 방법을 조금은 알아두는 것이 중요합니다. 이번 글에서 이에 대해 깊게 다루지는 않겠지만, 최적화된 프론트엔드 성능을 제공하기 위해 효과적으로 클라이언트 성능을 분석할 수 있어야 한다는 것은 언급할 가치가 있습니다. 브라우저의 개발자 도구에 대한 최소한의 대략적인 이해가 없으면(특히 네트워크 탭에서) 느리게 동작하는 어플리케이션의 원인을 파악하기도 어려워지고, 구현하고자 하는 동작이 제대로 동작하는지도 디버깅하기 어려워집니다.
4. 정적인 에셋(요소) 사용하기
정적인 요소를 최적화하고 이를 제공하는 방법을 최적화하는 것은 어플리케이션이나 사이트에서 가장 먼저 시도할 수 있는 부분입니다. 정적인 요소는 크게 코드(HTML, CSS, 자바스크립트 파일)와 이미지, 비디오 등의 정적 컨텐츠로 구분할 수 있습니다. 이미지와 비디오는 대용량의 파일로, 제대로 최적화되지 않은 정적 컨텐츠들은 느린 성능의 가장 큰 원인이 되곤 합니다. 따라서 만약 여러분이 최적화 문제를 확실히 해결하고 싶었다면, 여기 그 방법을 소개합니다!
5. CDN을 통해 제공되는 압축된 & 반응적인 WebP 포맷 이미지를 사용하세요.
이미지를 압축하는 것은 이미지 품질을 만족할 만한 수준으로 유지하면서 파일 용량만을 줄이는 데에 초점을 맞춥니다. 그 다음 적용할 수 있는 방법은 이미지의 포맷을 WebP로 바꾸는 것으로, WebP 이미지는 PNG 이미지와 비교하면 약 25%, JPEG 이미지와 비교했을 때 약 35%정도 용량을 줄일 수 있습니다. 파일 크기가 최적화되었다면 불필요하게 큰 용량의 이미지를 띄우지 않도록 해야 할 텐데요, 이를 위해서는
<img>
태그의 srcset
과 sizes
속성을 활용하거나 <picture>
태그를 활용할 수 있습니다. 이를 통해, 사용하고자 하는 기기 화면 사이즈에 따라 다른 크기의 이미지를 제공할 수 있게 됩니다.반응형 이미지를 제공하기 위해 AWS Serverless Image Handler와 같은 클라우드 기반 이미지 처리 기법을 사용할 수도 있습니다. SIH는 응답 과정에서 조정된 이미지를 전송할 수 있습니다. 따라서 크기에 따라 가공한 이미지를 만들고 로컬에서 불러와 사용하는 대신, SIH로 하나의 이미지를 가공해 요청한 크기의 이미지를 얻을 수 있게 됩니다. 서버리스 이미지 핸들러는 강력한 툴로, 제가 아는 최고의 이미지 제공 방법입니다.

SIH를 사용한다면 이미지를 CDN으로부터 제공받게 되는데요, 만약 SIH같은 서비스를 활용하지 않는다면 지연률과 성능 향상을 위해 CDN을 통해 제공받을 수 있도록 해야 합니다. 몇몇 더 발전된 CDN의 경우 이미지 압축과 점진적 렌더링 기능까지도 제공하곤 합니다.
6. 압축 및 최소화된 정적 코드 파일을 CDN을 통해 제공하세요
정적 코드 파일을 최적화하는 방법은 어렵지 않습니다. 개발자는 파일 크기를 최대한 줄이고 싶어할테고, 사용자는 CDN을 통해 지리상 가장 가까운 서버에서 파일을 내려받게 됩니다. 따라서 코드를 최소화하거나 번들링, Gzip(압축)으로 처리해 CDN을 통해 제공하면 됩니다. 일반적으로는 여러분이 사용하는 기술들의 백엔드 영역에서 번들러를 통해 코드 최소화와 압축을 수행하는데요, 몇몇 CDN조차도 이를 수행할 수 있습니다.
7. 프리페칭(Prefetching)
프리페칭은 리소스를 사용하기 전에 리소스를 불러오는데요, 이는 리소스를 실제로 필요로 할 때 대기시간을 줄이는 용도로 사용합니다. 어플리케이션을 브라우저보다 개발자들이 더 잘 알고 있으므로, 개발자들은 브라우저가 페이지를 불러오기 시작하면 리소스의 실제 사용 시점에 앞서 어떤 리소스를 프리페칭할지 알려줄 수 있습니다.
링크 프리페칭은 가장 널리 알려진 프리페칭의 형태입니다. 링크가 DOM에 로드되고 나면, 브라우저는 이미지나 자바스크립트와 같은 캐싱이 가능한 리소스들을 불러옵니다. 만약 사용자가 링크를 클릭하면, 브라우저는 이미 필요로 하는 리소스를 갖고 있기 때문에 훨씬 빠른 페이지 전환이 이루어지게 됩니다.
8. 지연 로딩(Lazy Loading)
페이지에서 현재 필요한 부분만을 불러오고 나머지 부분은 기다리는 지연 로딩 기법은 웹사이트와 어플리케이션의 강력한 프론트엔드 성능 최적화 패턴입니다.
인스타그램을 예로 들어보면, 탐색 페이지는 본질적으로 무한한 양의 컨텐츠를 갖고 있습니다. 만약 모든 컨텐츠를 한번에 불러오게 된다면 어마어마하게 긴 로딩 시간과 리소스가 낭비되게 되어, 사용자는 얼마 스크롤을 내리지 못하고 앱을 닫게 될 것입니다. 이럴 때 지연 로딩 기법을 사용한다면, 특히 무한 스크롤 지연 로딩을 사용한다면 사용자가 스크롤을 내릴 때 컨텐츠를 불러오게 됩니다.

Summary
Well done — with the knowledge you’ve just equipped yourself with you are now the front end performance guru on your team 🚀 You now have insight into the most powerful and important front end performance patterns and insight into when and where each pattern is appropriate to use. If you want a high-quality cheatsheet to easily refer to, you can download the one I created for free here.
Thanks for reading, I hope there were gems in this article for you 💎What are your thoughts on front end performance optimization patterns? 🤔Always happy to have a healthy discussion and/or receive feedback 🙂
If you enjoy reading articles like this, consider signing up to become a Medium member. It’s only $5 a month, giving you unlimited access to articles on Medium. If you sign up using my link below, I’ll earn a small commission.