Programming/React

[React] 성능최적화 1. 웹 성능 결정 요소 - 로딩 성능/ 렌더링 성능

RosyPark 2022. 2. 20. 10:14

 

사용자가 떠나지 않도록 하기위해  = 수익증대

프론트 엔드 개발자로서 경쟁력 갖추기위해 

 

[핵심] 

브라우저의 렌더링 원리

Performance 패널을 이용한 분석

Lighthouse 패널을 이용한 분석

Network 패널을 이용한 분석

webpack-bundle-analyzer를 이용한 분석

텍스트 압축

이미지 사이즈 최적화

적절한 사이즈로 변환

이미지 CDN을 통한 최적화

리소스 캐싱

이미지 preload

컴포넌트 preload

Component Lazy Load

React Code Splitting

Image Lazy Load

병목 코드 제거

repaint, flow 줄이기 

 

 

웹 성능 결정 요소

화면을 부르고 최적화시 로딩, 렌더링할것인지 중요, 브라우저가 서버가 어떻게 통신하는지 알 필요가 있음 

1. 로딩 성능 - 각 리소스를 불러오는 성능 

= Javascript 엔진으로 Javascript code를 읽어내, 기능을 작동시키는 역할을 함 

=> (React) 이미지 사이즈 최적화 / Code Split / 텍스트 압축 

 

2. 렌더링 성능 - 불러온 이 리소스들을 화면에 보여주는 성능

= 사용자가 볼 화면을 그려내는 역할 

=> Bottleneck 코드 최적화

 

 

 

웹 성능 최적화 for React 

1. 이미지 사이즈 최적화 

- 웹 서비스에서 다양한 이미지 사용, 이미지 사이즈가 너무 크면 서비스가 굉장히 무거워짐 

- 어떠한 이미지가 적절한 사이즈인지 판단하는것이 필요 

 

2. Code split

- 코드를 분할 

 

3. 텍스트 압축

 

4. Bottleneck 코드 최적화 

- 특정 js 코드때문에 로딩이 늦게 되는경우? 한참을 해메는 경우 존재 

- 병목 현상을 일으키는 코드를 어떻게 찾을 것인가? 

 

 

 

 

 

웹팩이란? 모듈 본들러, 주된 목적은 자바스크립트 파일들을 묶어서 사용하기위함, 자원이나 자산등을 구축, 패키징이 가능하게 만듦. 모듈화가 무조건 좋은것은 아님. 변수의 문제, 네트워크문제 등이 있기 떄문에 웹팩의 번틀링문제도 존재

번들링 = 어떤것을 묶는다. 가장 사용많이 되고 있는데 webpack , 서로 의존성 있는 여러 파일들을 번들 파일로 묶어줌

 

 

 

분석툴

1. 크롬 Network 탭 

2. 크롬 Performanc 탭 - 웹 페이지가 실행될때 작동하는 모든 작업들을 알려줌 

3. 크롬 Audit 탭(Light House) - 서비스가 어느정도 수준인지 파악할 수 있음 

4. webpack-bundle- analyzer  - bundling된 파일들이 어떤 코드를 담고 있는지 파악해주는 툴 

 

 

사이트의 성능최적화 부분을 전체 다 알면 좋지만 무리가 있음

-> audit를 사용하면 성능 최적화 부분을 알 수 있음 (2020년 3월에 나온 크롬 83버전부터 탭 이름이 Audits에서 LightHouse로 바뀜 )

 

Audit이란? 웹 품질개선을 위해 성능을 검사해주고, 성능향상을 위해 가이드라인을 주는 것

체크를 할때 Performance위주로 할꺼면 그것에 대한 CHECK 를 해주면 됨 

 

가장 먼저 보이는 숫자 

- 페이지의 성능을 알려주는 것 

- Performance는 전체의 100점 만점 중 몇점인지 알려주는 것? 

- 페이지가 로드되는 화면을 알려주는 것 

 

항목 웹페이지의 문제점과 문제점을 해결하기 위한 가이드를 제공 

1) Opportunities : Resources 관점에서 전달

2) Diagnostics :  페이지의 실행관점에서 전달 ( = 렌더링성능최적화와 관련) 

3) Past Audit : 이미 잘 적용하고 있는 항목 

4) Runtime Setting : 검사하고 있는 환경을 요약해서 보여주는 것 

 

1) Opportunities 

- Proper set images  자세한 사항을 볼 수 있음 

 

(1) " " 

이미지 최적화 방법은 크게 두가지가 있음 

- 이미지를 화면에 표시된 사이즈로 표시해도 되지만 요즘 많이 사용하는 retina display는 같은 공간에 더 많은 pixel을 사용하기 떄문에 너비 기준으로 2배 큰 기준으로 이미지를 사용하는 것이 적절하다

- 최적 사이즈가 120x120를 권장한다면 실제 코딩시 넣는 이미지는 240x240를 넣는것이 적합 

이미지를 줄이는 방법은 2가지가 있음

1) 이미지가 자체 server에 있는 static source면? 자체적으로 줄이면 됨 

2) Image CDN? 

- 기존 CDN(Contents Delivery Network)란? 

- 물리적 거리의 한계를 극복하기 위해 소비자(사용자)와 가까운 곳에 컨텐츠 서버를 두는 기술 

- 한국에 있는 사용자가 미국 서버에 있는 이미지파일을 받기 위해서 다운로드 하지만 인터넷이 빨라졌다고 해도 속도가 느릴수도 있음, 미국에 있는 서버를 한국에 복사해두고 한국에 있는 서버에 바로 복사? 

- 하지만 CDN과 Image CDN은 다름  Image CND? 사용자에게 전달하기 위해서  이미지를 사용자에게 보내기 위해서 특정 가공하기 전에 이미지 포맷 처리과정을 거쳐서 사용자에게 전달해줌 

- 이미지 CDN의 예시? http://cdn.image.com?src=[img src] & width = 200 & height = 100 

- 이미지 CDN의 경우 직접 구축하지 않고 imgix라는 홈페이지를 사용해서 사용함 

 

(2) Minifiy JavaScript 

 

 

2) Diagnostics

- Javascript때문에 생긴 코드 

- 주로 Performance Tab을 사용하여 타임라인과 관련시켜본다 

- Performance Tab? 페이지가 로딩되면서 실행되는 것을 타임라인과 차트 형태로 보여줌 

- 새로고침 버튼을 사용하면 페이지의 작업들을 다시 표시해줌 

 

0.chunk.js..? 파일이 어떤건지? 사이즈가 995KB정도가 됨 

- 시간이 되게 오래 걸림 

- 굉장히 많은 js파일을 사용하여 시행 

- 서비스의 component 실행을 하고 있음 

 

bottleneck 코드 탐색? 

- remove 캐릭터가 여러번 실행한게 아니라 한번에 선택했는데 가비지 컨텍터에 의해 끊김

- Minor QC 메모리에 여유가 없을떄 메모리에서 적용 

 

bottleneck 코드 최적화   1-7) 코드 다시 보기 

 1. 특수 문자를 효율적으로 제거하기 

 -> replace 함수와 정규식 사용 

 -> 마크 다운의 특수문자를 지워주는 라이브러리 사용

2. 작업하는 양 줄이기 

 

bundle 파일 분석(bundle - analyzer) 

- 파일은 유독 다운로드 시간이 오래 걸림, 자바스크립트가 다운로드 된 이후로부터 시간이 오래 걸림 

- 구글에 webpack bundle analyzer 검색 

https://www.npmjs.com/package/webpack-bundle-analyzer

 

webpack-bundle-analyzer

Webpack plugin and CLI utility that represents bundle content as convenient interactive zoomable treemap

www.npmjs.com

- 문제가 있음 , 직접 webpack을 사용해서 구성하는것이 아니라 CRA에서 제공되고 있는 webpack을 사용하고 있음 

- 직접 플러그인에 넣으려면 CRA를 reject하거나 webpack을 커스텀할 수 있는 라이브러리를 설치해야함

다행이도 최근에 webpack 커스텀 라이브러리를 사용하지않아도 bundle analyzer를 사용할 수 있는 것 발행됨 

- 리소스가 다운로드 되는 시간이 오래걸리다 보면 이후부터 코드가 실행되기 때문에 다운로드가 걸리는 시간만큼 화면이 뜨는 시간만큼 오래 걸림, 어떤식으로 해야지 서비스의 로드 타임을 줄어들것인가?

 

많은 양의 코드들? package-lock.json파일에서 찾을 수 있음 

package-lock.json 사용하고 잇는 모듈들의 dependencies를 찾을 수 있음

babel-core 라는 모듈을 사용하고 잇는데 babel-core 하위 dependency 모듈들을 같이 설치해라 . 

refractor도 명시되어 있음 

코드 블럭은 여기에서만 쓰이니깐 해당 모듈들도 이 페이지에서만 필요한건가? 

view 페이지에서만 코드블럭 라이브러리가 필요 

- 코드블럭 모듈은 사이즈를 많이 차지하는 모듈은 뷰 페이지에서만 사용하고 있기 떄문에 list 페이지에서는 불필요하게 로드할 필요가 없음 --> 페이지를 분리시키고 필요할떄마다 로드하는것이 좋음 

- refractor은 큰 사이즈를 차지하고 있음 --> 코드 스플릿팅을 통해서 불필요한 페이지 상승을 할 수 있음 

 

코드 스플리팅이란? 

- JS로 개발시 기본적으로 하나의 파일에 모든 로직들이 들어가기 때문에 분할시켜 로딩속도를 빠르게 하는 것이 중요함 . 코드를 분할하는 것 덩치가 큰 번들 파일을 쪼개서 작은 사이즈의 파일을 만들어 내는 것

- 하나의 파일을  Bundle.js  -> 파일이 하나로 통짜로 들어가고 있기 때문에 다운로드가 오래 걸리고 페이지 로딩속도도 오래걸림 

- 모듈을 쪼개는 code splitting이 필요

- 하나의 chunk 파일을 ListPage.Chunk.js 와 ViewPAge.Chunk.js 파일로 나눌 수 있음

- chunk란? 코드를 비동기적으로 불러오면 웹팩에서 처리를 하면서 코드를 분리시킴 

 

출처 ) https://velog.io/@velopert/react-code-splitting

 

리액트 프로젝트 코드 스플리팅 정복하기

코드 스플리팅, 뭐 별거있나요? 그냥 웹팩에서 하라는대로 하면 되는걸요. 하지만! 리액트에서 코드 스플리팅이랑 서버사이드 렌더링을 함께 해보신 경험이 있으시다면, 이 두가지 작업을 함께

velog.io

 

코드 스플리팅의 여러가지 패턴

(1) 페이지별로 코드 분할

(2) 모듈별로 코드 분할 

코드 스플리팅의 목적? 불필요한 코드 또는 중복되는 코드가 없이 적절한 사이즈의 코드가 적절한 타이밍에 로드될 수 있도록 하는 것 , 당장 필요한 코드가 아니라면 따로 분리시켜서 나중에 필요할떄 불러와서 사용가능 

 

코드 분할에 대한 리액트 공식 문서 존재 

https://ko.reactjs.org/docs/code-splitting.html

 

코드 분할 – React

A JavaScript library for building user interfaces

ko.reactjs.org

 

lazy? 동적으로 우리가 필요할때 Home이라는 component를 import 하겟다? 실제로 로드가 되었을때 정해진 주소가 되었을때 컴포넌트 로드 

suspense? 어느정도 수준에는 

 

코드 스플리팅을 실제로 실행하는것은 리액트가 아니라 webpack임 

 

Q. main함수안에서 놀면 어떻게 하나? 

 

CRA환경과 PRoduction 환경은 다르다

- Production 환경은 minify가 추가

- 성능도 다름 , 실제 성능이 다른 production build 최종적인 서비스의 환경? 

- Production 빌드?

- 기존에 했던 npm run start가 아닌 npm run build -> 실서비스 환경 

- 미리 만들어져 있는 npm serve라는 script를 사용해서 실 서비스 환경을 사용 

Q. 배포시 npm run build? 

 

개발환경과 실제 배포 환경? 

- lighthouse를 사용할시 개발환경과 실제 배포환경이 다름

텍스트 압축(Text Comporession) 

- css, js , HTML 파일들의 사이즈가 클수록 로딩 속도는 더 오래걸림 

- 이러한 문서의 사이즈를 줄이기 위해서는 여러가지 방법이 있는데 코드 스플리팅도 하나의 방법이고 Text COmpression도 하나의 방법임

- Text Compression? 다운로드 하는 리소스들의 사이즈가 작아지기 때문에 더 빠르게 서비스 할 수 있음

- 실제로 서비스가 압축되어 있는지 확인 가능! --> 네트워크 탭으로 가서 새로고침을 하면 다운로드 되는 리소스들을 확인할 수 있음 

   Text Compression 압축 알고리즘 

   - content-encoding 항목에서 확인할 수 있음 

   (1) GZIP  - 블럭화, 체크썸, 휴리스틱 필터링 Delfate를 사용하는 파일 포맷 , GZIP과 Deflate를 두가지 정도 사용 

   (2)  Deflate?  - LZ77

  압축은 클라이언트가 아닌 번들파일을 사용하는 서버에서 사용 

기본적으로 서버에서 압축을 하면 client에서는 압축을 해제해야함 , 압축하는데도 시간이 걸리지만 해제하는데에서도 시간이 걸림, 모든 파일들을 압축하려고 하면 성능이 굉장히 떨어짐, file의 크기가 2kb이상이 되면 인코딩을 해서 전달하는것이 좋고 2kb 이하면 인코딩을 하지 않는 것이 좋음 

 

정리

1. Audits 툴을 이용한 페이지 감사

 

2. 이미지 사이즈 최적화

 

3. Bottleneck 코드 최적화

 

4. Code Splitting

-

5. 텍스트 압축 

 

 

 

 

출처

1.  https://mingule.tistory.com/66?category=1021235

2.  https://www.seonest.net/posts/%EC%9B%B9-%EC%82%AC%EC%9D%B4%ED%8A%B8-%EC%84%B1%EB%8A%A51-%EC%A7%80%ED%91%9C

3. 

 


1. 렌더링 성능 최적화 

- 애니메이션 최적화(Reflow, Repaint) 

2. 로딩성능 최적화 

컴포넌트 Lazy Loading(Code Splitting) -> 한 페이지 안에서의 코드를 분할하고 레이지 로딩할 예정

컴포넌트 Preloading 분할한 코드를 분할

이미지 Preloading 

 

분석툴 

1. 크롬 Network 탭

2. 크롬 Performance 탭

3. webpack-bundle-analyzer 

 

 

실습코드 - https://github.com/performance-lecture/lecture-2 

 

GitHub - performance-lecture/lecture-2: lecture-2

lecture-2. Contribute to performance-lecture/lecture-2 development by creating an account on GitHub.

github.com

 

참고) 

npm start

npm run server