TDD
·
프론트엔드/테스트
TDD란? Test Driven Development 테스트 코드 작성 후 그 테스트 코드를 Pass 할 수 있는 실제 코드를 작성 장점 많은 기능 테스트하기에 소스 코드에 안정감 디버깅 시간 줄어들고 실제 개발 시간 줄어듬 깨끗한 코드 방법 기능 하나에 대한 테스트 코드 작성 해당 테스트 코드 통과하도록 코드 작성 1~2 반복 예시 기능 하나에 대한 테스트 코드 작성 it('counter starts at 0', () => { render() const counter = screen.getByTestId('counter') // 임시로 testid 사용, getByRole을 되도록이면 쓰자 expect(counter).toHaveTextContent('0') }) 해당 테스트 코드 통과하도록 코드 작성..
React 테스트 기초 (사용 툴, 환경 설정)
·
프론트엔드/테스트
인프런의 "따라하며 배우는 리액트 테스트"를 듣고 정리해 봤다. 테스트를 하는 이유 더 안정적인 어플리케이션을 만들기 위해 디버깅 시간 단축 - 테스팅 환경이 구축되어 있다면 자동화된 유닛 테스팅으로 특정 버그를 쉽게 찾아 낼 수 있다. 재설계 시간 단축, 추가 구현 용이 사용 툴 React Testing Library React 컴포넌트 테스트용 라이브러리 - 사용자 입장의 테스트, 행위 주도 테스트 (click, type 등) DOM Testing Library 위에 구축 주요 API render DOM에 컴포넌트 렌더링, 인자로 렌더링할 컴포넌트 리턴 값으로 RTL에서 제공하는 쿼리 함수, 기타 유틸 함수를 담고 있는 개체를 리턴 해당 쿼리, 유틸 함수는 소스 코드가 복잡할 경우 비추천, 대신 sc..
렌더링 성능 최적화 - Redux
·
프론트엔드/성능 최적화
Redux의 useSelector 렌더링 문제 해결 문제점 Redux의 useSelector로 특정 데이터를 구독하는 컴포넌트는, 리덕스 스토어에서 특정 데이터(구독하지 않은 것일 수도 있음)가 변경되는 경우 알림을 받는다. 새로운 상태와 현 상태를 비교해 값이 다르면 리렌더링한다. 보통 useSelector(state => ({a: state.a, b: state.b})) 이 selector에 전달한 콜백의 리턴 값을 기준으로 비교한다. 위의 예시는 매번 새로운 객체가 생성되기 때문에 값이 다른 것으로 판단하고 리렌더링한다. (구독하는 데이터가 변경되지 않았음에도 불필요한 리렌더링) 해결 Object를 새로 만들지 않도록 State 쪼개기 // 변경 전 const { modalVisible, bgCol..
렌더링 성능 최적화 - Layout Shift 피하기
·
프론트엔드/성능 최적화
Layout Shift 피하기 Layout Shift: 화면 레이아웃이 계속 변경되는 것 -> 리플로우 발생, 사용성에 많이 안 좋은 영향 (ex: 원래 클릭하려던 애가 밀리면서 다른 애 클릭) 원인 사이즈가 정해져 있지 않은 이미지 사이즈가 정해져 있지 않은 광고 동적으로 삽입된 콘텐츠 Web font (FOIT, FOUT) 해결 이미지, 광고의 사이즈를 예측해서 width, height을 준다 동적으로 삽입될 콘텐츠의 크기를 예측하고 다른 화면요소들이 밀리지 않게 설계한다. 폰트 최적화 이미지 사이즈 비율 맞추기 이미지의 width, height을 고정된 값으로 주면 Layout Shift는 발생하지 않지만 이미지의 비율이 깨지게 된다. (반응형으로 이미지 크기가 변하는 경우) 이런 경우 Wrappe..
렌더링 성능 최적화 - 애니메이션
·
프론트엔드/성능 최적화
애니메이션 최적화 (Reflow, Repaint) 쟁크 현상 브라우저는 보통 초당 60프레임으로 렌더링 초당 프레임이 떨어지면 ex) 30,20 -> 쟁크(애니메이션 버벅이는 현상) 발생 브라우저 렌더링 과정 1) DOM + CSSOM Render Tree Layout Paint - 3,4를 통해 여러개의 레이어가 만들어짐 Composite - 각 레이어 합성 1초에 60프레임이기 때문에 약 16.7ms에 한 프레임을 그려내야 함. 재렌더링이 해당 시간안에 완료되지 않으면, 특정 프레임 누락 -> 이전 프레임 보여줌 리플로우 width, height 변경시 레이아웃을 다시 하며 렌더링 과정 실행 리페인트 color 등 변경시 레이아웃 제외하고 렌더링 과정 실행 리플로우, 리페인트 피하기 GPU 도움받기 ..
렌더링 성능 최적화 - Bottleneck code
·
프론트엔드/성능 최적화
Bottleneck 코드 최적화 1 - 작업양 줄이기 Bottleneck 코드 찾기 크롬 Performance를 활용해서 페이지가 렌더링될 때 각 컴포넌트 등의 실행시간을 체크해볼 수 있다. 이를 활용해 실행이 오래 걸리는 함수, 컴포넌트 등 Bottleneck 코드를 찾을 수 있다. 여기서 보면, Article 컴포넌트 mount 작업이 오래걸리는데, 아래에서 상세한 수행내역을 보면 removeSpecialCharacter 함수가 실행시간을 다 차지하고 있는 것을 확인할 수 있다. 이런식으로 Bottleneck코드를 찾을 수 있다. Bottleneck 코드 분석 /* * 파라미터로 넘어온 문자열에서 일부 특수문자를 제거하는 함수 * (Markdown으로 된 문자열의 특수문자를 제거하기 위함) * */ ..
로딩 성능 최적화 - 텍스트 압축, 불필요한 CSS 제거
·
프론트엔드/성능 최적화
텍스트 압축 개요 서버에서 보내는 리소스들(CSS, JS, HTML)의 텍스트를 압축해서 보내고 받고 압축을 해제한다. 크기가 작기 때문에 더 빨리 다운로드할 수 있다. -> 로딩 속도를 개선할 수 있다. lighthouse의 opportunities에서 확인할 수 있다. 종류 텍스트 압축에는 크게 2가지가 있다. GZIP Deflate GZIP이 Defalte보다 더 좋은 압축율을 제공한다. 적용 번들은 기본적으로 압축이 안된 상태로 전달이 된다. 이를 compression-webpack-plugin을 활용해 빌드 시 압축하거나, 서버 코드에서 텍스트 압축을 적용한 후 전달하도록 하면 된다. 압축 시 모든 파일을 압축하는 것이 아닌 크기가 특정 크기 이상(ex: 10KB)인 파일들만 압축을 해서 전달한..
로딩 성능 최적화 - 캐시
·
프론트엔드/성능 최적화
캐시 최적화 캐시 활용 위해서 Cache-Control 설정 필요 -> 빌드된 파일을 서비스하는 서버에서 설정 no-cache: 캐시를 사용하기 전에 서버에 검사 후, 사용 결정 no-store: 캐시 사용 안 함 public: 모든 환경에서 캐시 사용 가능 private: 브라우저 환경에서만 캐시 사용, 외부 캐시 서버에서는 사용 불가 max-age: 캐시의 유효시간 , max-age = 0 해도 캐시 된 리소스를 버리지 않고 가지고 있는다. 추후 요청시 수정 여부 확인 후 활용 사용 예시 cache-control: private, max-age=60 Express를 활용한 간단한 구현 예시 1) 캐시를 전혀 사용하지 않을 때 no-store만 주지 않은 이유는 브라우저 중 no-store으로만 캐시 ..