[TIL] 22.12.14 - 이미지 미리보기(FileReader), PreLoad, Prefetch

nana·2022년 12월 14일
0

TIL

목록 보기
48/50
post-thumbnail

useMemo

페이지네이션에서 lastPage 계산 부분 -> useMemo
useEffect에서 setState 부분이 있으면 useMemo로 변경해보기


이미지

FileReader - 이미지 불러오기


기존 이미지 업로드 방식을 효율적으로 개선하기


기존 이미지 업로드 방식의 문제점

브라우저에서 파일을 업로드 하고 백엔드에 전송 -> 백엔드에서 스토리지를 통해 다운로드 URL을 다시 전달 -> 제목, 내용, 작성자, 다운로드URL을 통해 게시글 등록 API요청

  1. 이미지 찌꺼기가 남는다.
    사진 파일을 업로드하고 뒤로가기 버튼을 눌렸을 경우, 사용하지 않는 사진파일이 스토리지에 저장된다.

  2. 이미지 미리보기가 느리다.


개선 방법

  1. 브라우저에서 파일 업로드 후, 확인을 누르면 해당 컴퓨터에서만 사용 가능한 가짜 URL을 생성, 바로 이미지 미리보기를 가능하게한다.
    => 미리보기 성능 극대화

  2. 게시글 등록 버튼을 누를 때 업로드파일 + 게시글 등록 API 요청
    -> 스토리지에 파일 저장, 다운로드 URL을 받아옴, createBoard할때 result에 담긴 다운로드 URL을 넣어준다.
    => 업로드 타이밍 변경


  • URL.createObjectURL -> 내 브라우저에서만 접근 가능
  • new FileReader() -> 다른 브라우저에서도 사용 가능
    => 둘 다 미리보기 용으로 실제로 백엔드에 전달하지 않는다.

new FileReader()를 사용해서 진짜 URL을 생성하고, 다른 브라우저에서도 접근이 가능하도록 만들어준다.

readAsDataURL()을 사용하면 Data URL을 얻을 수 있다. ()안에 파일을 넣어준다.

onload() 에서는 파일을 읽고 생성된 Data URL이 target.result에 담긴다.

해당 결과를 img태그의 src에 값으로 넣어주면 된다.


사진을 여러개 올릴 경우 어떻게 처리할까??

파일을 모두 받을때까지 await로 기다렸다가 uploadFile를 실행하고 싶은경우, Promise.all을 사용한다.


Promise.all


Async-await를 for문에서 사용하면 안된다.
-> 0, 1, 2 등 순서가 있기 때문이다.
-> 대신 map을 사용해준다.

Promise.all()을 사용하면 Promise.all()에 포함되어 있는 함수들을 동시에 실행한다.

따라서 onClickPromiseAll 함수의 경우 약 3초의 시간이 소요된다.
(Promise.all을 사용하지 않으면 약 6초의 시간이 소요됨)


Promise.all을 이용한 다중 이미지 업로드


Promise.all을 사용해서 uploadFile API를 여러번 받아올 때, map을 사용해준다.


LazyLoad / PreLoad


이미지 페이지 성능 개선 방법


1. LazyLoad


페이지를 읽어주는 시점에 중요하지 않은 리소스 로딩을 추 후에 하는 기술

첫 페이지 접속시 보여지는 부분만 이미지를 다운로드 받고, 스크롤을 내리면 나오는 부분은 스크롤시 추가적으로 다운로드 받아 필요한 때가 되면 로드해서 데이터의 낭비를 막아줄 수 있다.

react-lazy-load 설치
https://www.npmjs.com/package/react-lazy-load


2. webp 확장자

webp 확장자는 구글에서 만든 이미지 확장자이다.(웹피라고 부름)

이미지 서버의 부담을 줄이고, 서버비를 아낄 수 있는 방안으로 Webp라는 확장자를 만들었다.

Webp의 장점

  • GIF, PNG, JPEG 확장자 모두 대체 가능한 확장자이며, 이미지를 파일을 압축했을 때 기존 PNG, JPEG보다 약 30%정도 용량을 줄일 수 있다.

  • GIF는 256색만 표현할 수 있지만, Webp은 파일 크기도 작고 , 색상 수에 제한이 없으므로 GIF보다 훨씬 성능이 좋다.

  • PNG 처럼 알파 채널(배경이 투명한 것)을 지원한다.

Webp 확장자 변환 사이트
https://cloudconvert.com


3. Google page-speed-insights

실제 배포를 진행하고 나서, 내가 배포한 페이지의 개선할 점을 찾을때 유용한 사이트


4. preload

페이지를 읽어줄 때 미리 리소스를 받아놓는 기술

다음페이지 이동이 필요할 경우, 현재 페이지에서 다음 페이지에서 사용할 이미지를 미리 다운로드 받아 저장하고, 페이지 이동시 저장된 이미지를 바로 화면으로 보여준다.

예를 들어 이미지가 10장이 넘는 페이지가 있을 때, LazyLoad의 경우에는 필요할 때마다 데이터를 로드하는 방법이라면, PreLoad의 경우에는 모든 데이터들을 미리 로드해놓고 대기하는 방식이다.

preloadimage 함수를 libraries 폴더에 생성

preload한 이미지들을 글로벌 변수(PRELOAD_IMAGES)에 저장한다.

ussEffect를 사용해서 preloadImage 함수를 사용해줌

버튼을 클릭해서 페이지를 이동했을때, 이미지 주소를 미리 다운로드 받아놓았기 때문에 이동시 이미지를 보여주는 속도가 빠르다.


5. prefetch


게시물 제목을 클릭하면 다음 페이지에 적용된 useQuery를 미리 fetch하기

useEffect 보다 onMouseOver

마우스를 올리면 prefetchBoard 함수 안에 있는 query가 실행된다.
-> client.query로 apollo client 캐시에 저장
-> fetchboard시 캐시에 있는지 확인 후 그 데이터를 그대로 가져오기 때문에 api 요청이 없고, 속도가 빠르다.

디바운싱으로 마우스 오버 시간을 확인하고 캐시에 저장하도록 해주면 더 좋다.



react 이미지 관련 라이브러리


참고할만한 사이트

wappalyzer : 홈페이지 만드는데 사용된 기술 확인 가능
codenary : 사이트별 기술 스택 확인

profile
프론트엔드 개발자 도전기

0개의 댓글