티스토리 뷰

Web

Lazy Loading과 기타 이야기

Pewww 2018. 11. 15. 00:06

우리는 흔히 웹 페이지의 성능을 향상시키고자 할 때 3R을 얘기합니다.


1. Request 개수 줄이기

2. Resource 사이즈 줄이기

3. Rendering 시간 단축


Webpack을 통한 모듈 번들링, 이번에 얘기해 볼 Lazy Loading이 1번,

Webpack-Minify, Obfuscation, Tree-Shaking, Code-Splitting, 이미지 최적화가 2번,

CRP 최적화, Reflow의 최소화, 부드러운 애니메이션 등이 3번 예시에 속한다고 볼 수 있습니다.


이번 포스트에서는 1번 예시 중 Lazy Loading과 기타 내용에 관해 이야기를 해볼까 합니다.

Image result for lazy loading

이미지와 같이 사이즈가 큰 데이터를 로딩할 때, 사용자의 브라우저 화면에 나타나지 않은 이미지까지 로딩을 하면 페이지의 로딩이 느려질 수 있습니다.

이런 상황에서 유용하게 쓰일 수 있는 것이 바로 Lazy Loading이며, 예시 그림과 같이 사용자 브라우저에 보이는 이미지만 로딩을 하고 다른 이미지들은 사용자가 스크롤 하면서 이미지에 가까워지면 로딩을 합니다.

전체 이미지를 한 번에 로딩하지 않고, 사용자가 필요한 부분만 보여줄 수 있기 때문에 로딩에 대한 비용을 줄일 수 있다는 장점이 있습니다.

꼭 이미지만 해당 하는 것이 아닌, 웹에서 특정 위치나 컴포넌트에 도달하였을 때 API를 호출하는 것, 데이터베이스에서 기본적으로 PK가 되는 값만 전달해주고, 추가 요청이 생길 경우에만 DB에서 상세 내용을 불러오는 것 등 모두 Lazy Loading의 예시라고 할 수 있습니다.


정리를 해보자면, Lazy Loading은 웹 페이지의 성능을 향상시키기는 하지만 정확히 Request의 개수(총량)를 줄이는 것은 아니며, 그냥 간단히 브라우저의 초기 렌더링 최적화를 위한 작업이라고 생각하시면 좋을 것 같습니다.


그럼 좀 더 나아가서, 우리가 Request의 개수를 줄여야 하는 이유는 무엇일까요?

바로, 네트워크 통신 비용으로 인한 렌더링 블록(Rendering Blocking) 문제를 방지하기 위함입니다.


브라우저 마다 특정 개수의 호스트를 가지고 있고, 그 호스트를 가지고 서버에 리소스를 요청합니다.

그리고, 각 요청이 끝나면 다시 호스트는 서버와 새롭게 커넥션하여 통신합니다.

이는 Chrome Devtools의 Network Debugger를 통해서도 쉽게 확인할 수 있는데, 아래 사진과 같이 데이터를 내려 받는 속도보다 서버와 커넥션, SSL 적용 등의 작업이 훨씬 오래걸린다는 사실을 알 수 있습니다.



* 실제 작업이 완료되기 까지 걸린 시간은 각각 97.90ms, 186.20ms에 비해, 실제 콘텐츠가 다운로드 되는데 걸린 시간은 4.44ms와 1.62ms로 작업 시간에 대한 확연한 차이를 알 수 있습니다.


따라서, 요청이 잦아질 경우 리소스를 요청하는데에 걸리는 시간은 기하급수적으로 늘어나며, 그렇기 때문에 최적화를 위해서는 처음 말했던 것처럼 요청의 개수를 줄이고, 리소스를 합치는 것이 필요합니다.


말을 좀 거창하게 한 것 같지만, 사실 그다지 어렵진 않습니다.

바로, 스프라이트 기법(CSS Sprites)Webpack과 같은 모듈 번들러(Module Bundler)를 사용하여 여러 파일을 하나의 파일로 통합하는 것입니다.


그 중 스프라이트 기법은 조각난 이미지 파일들을 하나로 병합한 후, 이를 배경으로 처리하는 것을 말합니다.

다시 말해, 여러 이미지 파일을 일일히 불러오는 것이 아니라, 한 이미지 파일로 통합한 후 Background-Position을 이용하여 사용자에게 실제로 보여지는 위치를 다르게 하는 것이죠.

현재, 국내 유명 포털엔진 및 SNS에서도 이를 적극 활용하고 있는데요. 아래 사진을 통해 확인해 볼 수 있습니다!


1. 네이버 (Naver)


2. 다음 (Daum)


3. 페이스북 (Facebook)



자바스크립트의 경우를 좀 더 예로 들자면, 흔히 개발할 때  style 파일은 <head /> 부분에, script 파일은 <body />의 최하단 부분에 위치 시켜야 한다는 말을 자주 들어 보셨을 겁니다.

javascript-execution

기본적으로, 브라우저가 페이지를 렌더링하려면 먼저 HTML 마크업을 파싱하여 DOM을 빌드해야 합니다.

하지만 다음 그림과 같이, 브라우저가 파싱을 하다가 스크립트 파일을 만날 경우, 스크립트 파일을 요청하고 다 불러와지는 동안 구문에 대한 분석을 중단하게 되는데, 이것이 우리가 흔히 말하는 렌더링 블록킹(Rendering Blocking) 현상입니다. 당연히 렌더링이 계속해서 블록될 시 페이지의 첫 렌더링 시간은 지연될 수 밖에 없으며, 이는 곧 좋지 않은 사용자 경험으로 이어지게 됩니다.

이와 같은 이유 때문에, style과 script 파일을 지정된 곳에 위치시켜야 한다는 것이고, 좀 더 나은 페이지의 성능을 위해 간단하지만 필수적이라고 할 수 있습니다.



말이 계속 딴 길로 새는 것 같은데... 어쨌든 정리를 해보자면, Request에 가장 큰 영향을 끼치는 것은

네트워크의 커넥션 리소스이며, Request의 호스트 개수에는 제한이 있기 때문에 Request의 개수가 많아질 경우, 콘텐츠를 다운로드 하는 시간보다 전체 리소스를 불러오는 시간이 훨씬 더 길다는 것입니다.

물론 이 부분은 커넥션을 유지한 채로 통신하는 HTTP 2.0에서는 신경을 쓰지 않아도 되며, HTTP 1.1에서만 해당되는 내용이기 때문에 그냥 가볍게 읽어보시면 좋을 듯 합니다~



글 읽어주셔서 감사하고, 피드백은 언제나 환영입니다!




+ 이미지 Lazy Loading에 관한 이해를 돕기 위해 깃허브 레포를 생성하였습니다.

한 번 확인해보시면 좋을 듯 합니다 :D

https://github.com/Pewww/progressive-image-lazy-loading

'Web' 카테고리의 다른 글

미처 알지 못했던 package-lock.json  (6) 2018.12.29
댓글