Skip to content

Latest commit

 

History

History
222 lines (136 loc) · 11.1 KB

기본적인 렌더링 최적화 방법.md

File metadata and controls

222 lines (136 loc) · 11.1 KB

기본적인 렌더링 최적화 방법

렌더링 최적화와 관련해서는 무수한 내용이 있으며 하나의 파일에 담아내는 데 한계가 있다고 판단하여 (기존의 내용 + Front-End-Performance-Checklist 레포지토리)를 정리하여 작성하였습니다.

이외에도 많은 최적화 내용이 있으니 찾아보시는 걸 추천해 드립니다.

프론트엔드 분야가 관심을 받게 되면서, 성능 향상을 도와주는 기술과 도구들이 많이 생겼다. 지금, 이 순간에도 만들어지고 있다.

분야별로 많은 최적화 방법이 있지만, 프론트엔드에서 가장 많이 보면서 사용하는 5가지에 대해서만 알아보려고 한다.


html5_img HTML

  • HTML 코드를 압축하며, 최종적으로 나오는 번들된 파일에서 주석, 공백, 줄바꿈을 제거한다.

프로트엔드 개발을 하는 데 있어서 Webpack 같은 번들링 도구를 사용하면서 플러그인을 적용해주면 HTML 파일도 Compress 작업을 거치기 때문에 크게 고려하지 않아도 된다. 실제로 크기를 줄이고 측정 시 로딩 속도를 높여주며, 다운로드 시간을 줄여주는 것을 확인했다.

간단하게 Big Size의 파일을 가지고 확인을 해보자

🔗 Online html-minifier

  • CSS 태그를 자바스크립트 태그 앞에 두어 자바스크립트 코드보다 먼저 로드가 되도록 한다.

자바스크립트 전에 CSS 태그를 두면 브라우저의 렌더링 속도를 높이는 병렬 다운로드가 가능해진다.

  • 다른 기술적 가능성이 없을 때 iframe을 사용하고, 최대한 iframe을 사용하지 말아야 한다.

iframe을 기본적으로 Main 페이지와 리소스를 공유하지 않아서 iframe 내부적으로 리소스를 다시 호출한다. 이렇게 되면 한 화면의 2개의 렌더링 페이지를 보게 되는 것과 동일하게 된다.


css_img CSS

  • CSS 파일을 압축하고, 최종적으로 나오는 번들된 파일에서 주석, 공백, 줄바꿈을 제거한다.

프로트엔드 개발을 하는 데 있어서 Webpack 같은 번들링 도구를 사용하면서 플러그인을 적용해주면 CSS 파일도 Compress 작업을 거치기 때문에 크게 고려하지 않아도 된다. 실제로 크기를 줄이고 측정 시 로딩 속도를 높여주며, 다운로드 시간을 줄여주는 것을 확인했다.

  • DOM이 로드되는 데 시간이 오래 걸리지 않도록 CSS 파일은 Non-Blocking이 되어야 한다.

CSS 파일은 페이지 로드와 렌더링을 지연시킬 수 있다. 이에 방안으로 preload를 통해 브라우저가 페이지의 콘텐츠를 보여주기 전에 CSS 파일을 미리 로드할 수 있다.

<link rel="preload" href="style.min.css" as="style" onload="this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="style.min.css"></noscript>

위와 같이 link tag에 rel="preload"as="style" 를 넣어주면 된다.

이와 관련된 아래의 글을 읽어보는 것을 추천한다.

🔗 preload & preconnect & prefetch

  • CSS 크리티컬(또는 '스크롤 없이 볼 수 있는 부분')은 페이지의 보이는 부분을 렌더링하는데 사용되는 모든 CSS를 수집한다. 주요 CSS 호출 전, <style></style> 사이에 한 줄로 추가하게 된다.

화면에 필요한 부분만 모아서 inline으로 삽입하면서, 초기 렌더링 속도를 높이면서 inline으로 삽입하여 request를 줄이게 된다.

  • 외부 또는 인라인 CSS를 <body> 안에 작성해서는 안된다. (HTTP/2에서는 다르게 평가될 수 있다.)

먼저 디자인에서 콘텐츠를 분리하는 것이 좋다. 또한 코드 유지보수를 쉽게 만들고 사이트 접근성을 높인다.

HTML 페이지의 파일 크기와 로딩 시간을 줄여준다.

결론적으로 항상 외부 스타일을 사용하거나 CSS를 <head>에 작성한다.

  • 스타일 시트를 분석하여 불필요한 중복 CSS 선택자를 찾는다.

중복, 또는 유효성 처리가 CSS 코드에서 발생한다. CSS 파일을 분석하고 복잡성을 해결하게 되면 파일을 읽는 속도를 높일 수 있다.

  • CSS 스프라이트 기법을 사용하여 많은 아이콘을 사용하는 곳에서 request의 수를 줄인다.

CSS 스프라이트 기법은 이미지 여러 개를 하나로 만들고 background-position 속성을 사용하여 필요한 부분의 이미지만 보여주는 기법이다.

다수의 이미지가 포함된 웹 사이트의 경우, 이미지의 수 만큼 HTTP 요청을 했던 방식을 한 번의 요청으로 줄일 수 있어 초기 Rendering에 걸리는 시간을 줄인다.

<style>
    .up,
    .down,
    .right,
    .left {
        background: url("./img_css_image_sprites.png") no-repeat;
    }

    .up {
        width: 21px;
        height: 20px;
        background-position: 0 0;
    }

    .down {
        width: 21px;
        height: 20px;
        background-position: -21px 0;
    }

    .right {
        width: 22px;
        height: 20px;
        background-position: -42px 0;
    }

    .left {
        width: 22px;
        height: 20px;
        background-position: -65px 0;
    }
</style>

<body>
    <div class="up"></div>
    <div class="down"></div>
    <div class="right"></div>
    <div class="left"></div>
</body>

fonts_img Fonts

  • 웹 또는 어플리케이션에서 WOFF(Web Open Font Format) 2 포맷 을 사용하는 것이 좋다.

WOFF 이후 WOFF2 형식이 개발되었는데, WOFF에 비해 30%~50% 정도 더 압축되어 훨씬 가벼워졌다. 2018년 기준으로는 IE를 제외한 거의 모든 브라우저의 최신 버전에서 지원하고 있다.

🔗 Can I use... - woff2

구글의 자료에 따르면 WOFF 2.0 폰트 압축 포맷은 WOFF 1.0보다 평균 30% 더 많이 쓰인다고 한다.

  • 폰트를 더 빨리 로드하기 위해 preconnect 를 사용한다.
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>

웹 사이트에 접속하면, 브라우저는 DNS 서버를 찾고, 리소스(폰트, CSS...) 수집이 끝나기 전, 조회가 완료될 때까지 대기한다.

이 경우 prefetch와 preconnect를 사용하게 되면 브라우저가 DNS 정보를 찾고 폰트 파일을 호스팅하는 서버에 대한 TCP 연결을 허용받는다.

브라우저가 폰트 정보와 서버에 요청해야 하는 폰트 파일이 담긴 CSS 파일을 파싱할 때 DNS 정보를 확인하고, 커넥션 풀에 있는 서버에 대한 개방형 연결을 준비하게 되어 성능을 높일 수 있다.

🔗 preload & preconnect & prefetch


images_img Images

  • 이미지는 최적화되어야 한다. 최종 사용자에게 영향을 미치지 않는 선에서 압축되어야 한다.

당연히 압축된 이미지는 용량이 작아지기 때문에 브라우저에서 더 빨리 로드되고, 적은 데이터를 소비한다.

  • 적절한 이미지 형식.

적절한 이미지 형식이란 웹 사이트를 느리게 만들지 않을 형식을 사용하자는 것이다. 요즘은 차세대 포맷인 JPEG 2000m, JPEG XR 또는 WebP를 사용하는 것이 좋다.

대부분의 브라우저에서 현재 WebP 포맷이 지원되고 있다. (사파리 제외)

🔗 Can I use - webP

  • Image Lazy Loading

이미지 레이지 로딩에 관련된 많은 글이 존재한다.

레이지 로딩에 따른 여러 방법이 존재하지만, 기본적인 방법인

  1. facebook과 같이 skeleton UI 를 사용하는 방법,
  2. Medium과 같은 progressive image loading,
  3. 무한스크롤시 IntersectionObserver를 사용하여 클래스로 background-image를 주는 방법

등등이 있다.

위와 관련된 글은 아래의 참조 글을 읽어보는 것이 좋다.

🔗 (Developers Google)[https://developers.google.com/web/fundamentals/performance/lazy-loading-guidance/images-and-video/]


javascript_img JavaScript

  • JS 파일을 압축하고, 최종적으로 나오는 번들된 파일에서 주석, 공백, 줄바꿈을 제거한다.

프로트엔드 개발을 하는 데 있어서 Webpack 같은 번들링 도구를 사용하면서 플러그인을 적용해주면 JS 파일도 Compress 작업을 거치기 때문에 크게 고려하지 않아도 된다. 실제로 크기를 줄이고 측정 시 로딩 속도를 높여주며, 다운로드 시간을 줄여주는 것을 확인했다.

  • 자바스크립트 코드를 <body> 중간에 두어서는 안 된다.

코드를 그룹화를 하여 외부 파일로 만들거나 페이지의 마지막(</body> 이후)에 작성하는 것이 좋다.

자바스크립트 코드를 <body> 중간에 넣게 되면 DOM이 구성되는 과정에서 코드가 로드되기 때문에 페이지 속도를 떨어뜨리게 된다.

가장 좋은 옵션은 외부 파일을 async 또는 defer 속성과 함께 사용하여 DOM 로딩을 막지 않도록 하는 것이다.

  • 자바스크립트 파일을 비동기적으로 로드하기 위해 async를 사용하거나 지연시키기 위해 defer 속성을 사용해야 한다.
<!-- Defer Attribute -->
<script defer src="foo.js">
<!-- Async Attribute -->
<script async src="foo.js">

자바스크립트는 HTML 문서의 파싱을 차단하기 때문에, 파서는 <script> 태그에 도달할 때 (특히 <head> 안에 있을 때) 파싱을 멈추고 스크립트를 실행한다. 스크립트를 페이지의 상단에 두는 경우 async 또는 defer를 사용하는 것이 권장되지만 언제나 이 속성을 사용하여 성능 이슈를 피하는 것은 좋은 습관이다.

🔗 ES6-module-in-Browser

  • 외부 라이브러리를 잘 보고 선택해서 사용하자. 대부분의 경우, 똑같은 기능을 하지만 더 가벼운 라이브러리가 있다.

  • 자바스크립트 파일의 성능 문제를 확인해야 한다.

자바스크립트의 복잡도는 런타임 성능을 떨어뜨릴 수 있다. 크롬 개발자 도구의 타임라인 툴을 이용하여 스크립트 이벤트를 테스트하고 너무 오랜 시간이 걸리는 이벤트를 찾아서 수정하여야 한다.


Reference