31일차) 언제까지 사진 한 장씩 올리는거 기다릴거야! FileReader/readAsDataURL/Promise.all/ 실무 위주 !성능 높여 ! 끌어올려! Code Camp FE 6기

김아름·2022년 4월 26일
1

코드캠프6기

목록 보기
31/36
post-thumbnail

교훈 : 데이터가 어떠한 형태로 오는지 정확히 파악후 ! JSON.parse 잊지말자 ㅎㅎ

오늘 배울 내용

오늘은 이미지에 대해 크게 4가지 정도 중요한 내용을 배웠죠!


기존의 방식은 Browser에서 이미지를 등록하면 백엔드에서 storage에 이미지를 올려 url을 받아 그 url을 Browser에게 반환해주는 방식이였습니다! 이 방식은 Storage 용량 낭비 문제가 있었죠!


이를 해결할 수 있는 방법이 있었습니다! 미리보기 성능을 올리기 위해서 FileReader()를 활용해 아직 파일을 업로드(uploadFile)하지는 않은 상태로 임시주소를 만들어서 이미지를 보여주는것! .readAsDataURL()을 사용하면 그 컴퓨터에서만 사용 가능한 가짜 URL을 만들어 낼 수 있었습니다! 이 방식을 사용하면 Storage에 찌꺼기도 남지 않아 낭비도 막을 수 있어 효율적이였습니다! 하지만 실제로 게시물을 등록할때는 가짜 URL을 등록하면 안되겠죠!


게시물 등록 버튼을 클릭하면, 파일을 먼저 모두 업로드(uploadFile)한 후, 결과로 받아온 url을 배열로 묶어 게시물 등록(createBoard)을 요청해봤죠!


즉, 기존에는 파일이 변경됐을 때 마다 자동으로 uploadFile이 실행되도록 했는데, 이 때, 업로드를 하나씩 하게되면 시간이 비교적 오래 걸렸죠! 따라서, 시간 단축을 위해 동시에 보내는 방법으로 Promise.all()을 사용하여 효율성을 높였습니다! Promise안에 배열 형태로 집어넣은 Promise들을 각각 보내는 것이 아닌 한번에 보내 기다려줬죠!


게시물 등록버튼을 눌렀을 때 한번에 모든 파일을 uploadFile을 통해 업로드하고, createBoard 도 함께 요청 하도록 했습니다!


또 다른 성능 관점에서 LazyLoadPreLoad가 있었습니다!


LazyLoad는 아래 위로 긴 페이지에서 이미지를 포함하여 모든 내용을 한 번에 받아 오는 것이 아닌, 스크롤을 내리면서 보여질 필요가 있는 부분만 추가적으로 받아오는 식으로 불필요한 서버와의 통신을 줄일 수 있었습니다.


PreLoad는 이미지를 사전에 미리 로드해 놓고, 필요할 때 이미 다운로드된 이미지를 보여줌으로써 렌더링 시간을 단축시켰습니다.


이미지 다운로드 성능을 높이기 위한 .webp 확장자에 대해서도 배웠습니다!


png 또는 jpeg보다 압축률이 높아 더욱 좋은 성능을 보여줄 수 있었죠!


PageSpeedInsights 를 활용한 사이트 속도 검증도 알아봤죠! 이 사이트를 활용하면 사이트 속도 개선을 올릴 수 있고 검색엔진(봇)의 점수를 더 높게 받을 수 있는 장점이 있었습니다!


마지막으로, 이미지 관련 라이브러리에 대해서 배웠습니다.


사진을 끌어다 놓는 방식(drag and drop)으로 업로드하는 react-dropzonereact-beautiful-dnd, 사진을 동그라미형태로 변경, 확대, 축소 등이 가능하도록 도와주는 react-avatar-editor`,또한, ant-design에도 많은 이미지 관련 라이브러리들이 있었습니다!


오늘 배운 fileReader와 URL.createObjectURL은 둘 다 이미지 업로드 시 이미지를 불러와 미리보기 할 수 있습니다.
createObjectURL을 사용하게 되면 소스코드가 짧아져서 작성하기 쉽고 좋겠지만, fileReader와는 다르게 createObjectURL은 blob 객체로 이미지를 생성하기 떄문에 해당 데이터를 서버와 통신할 때 사용할 수 없습니다.
또한 createObjectURL보다는 fileReader가 브라우저 호환성이 좋기 떄문에 사용자 편의를 생각하신다면 fileReader를 사용하시는 것이 좋겠습니다.


fileReader와 createObjectURL의 MDN🙂
https://developer.mozilla.org/ko/docs/Web/API/FileReader
https://developer.mozilla.org/ko/docs/Web/API/URL/createObjectURL

- 기존 이미지 업로드 방식은 비 효율적이야 ? FileReader

  • 우리가 기존에 쓰던 이미지 업로드 방식
    백엔드의 uploadFile api요청을 통해서 storage에 사진을 저장하고,
    url을 받아와서 브라우저에 url을 넘겨주었었다.
    그 다음에 그 url을 첨부해서 createBoard api요청을 해서
    게시글에 이미지를 올리는 과정.

  • 받은 url을 통해 img태그를 써서 미리보기를 했었다
    (문제1 - url받아오기까지 시간이 걸림)
    (문제2 - 찌꺼기 이미지 파일들이 쌓이게 된다
    -> 파일 업로드만 해서 url만 받아놓고 create요청 안때리면..몬데? 찌꺼기!)

    이러한 문제들 때문에...

  • 자바스크립트로 브라우저에서 url을 만들어서 바로 보여주면 어떨까?
    (그러면 일단 스토리지에 저장 안하고도 미리보기로 보여줄수 있으니까)
    (근데 자바스크립트로 만든 url은 다른 사람들이 보려면 db에 저장을 하긴 해야해 ! ) -> 그건 최종 등록 뮤테이션 날릴때 uploadfile하고, 등록하면 된다!


    -> 미리보여주기는 자바스크립트 내에서 해결하고,
    최종 등록 뮤테이션 날릴때, 스토리지에 저장해서 url 받아오는 과정을 묶는다 !

  • input type file로 url 만들어서 img태그로 보여주자
  • 자바스크립트로 미리보기 주소를 만들자
  • 이미지태그로 미리보기 주소를 보여주자
    자바스크립트 내장기능인 filereader를 쓰는모습..!
    괄호 안에 blob형태로 넣어주라고 하네!

    -자바스크립트가 만들어준 url을 찍어보면 엄청 긴..문자열이 나오는데!
    이 문자열은 스토리지에 저장하는거니 안심해
    (우리db에 이렇게 긴 내용이 쌓이진 않음)
    저 긴 문자열로 스토리지에서 받아오는 간단한 url을 우리는 저장할거다
    그럼 이제 게시글을 등록하러가자! (그때 스토리지에 같이 올리러가자)
    여기 최종 등록하기 부분에서 두가지 함수 같이 한다는것 알겠지?

    빠르게 미리보기가 되는것과, 등록하기를 했을때 uploadlink state를 통해서 비로소 스토리지에 저장해서 올리는것을 볼 수 있다

- Async-await 를 for문에서 쓰면 안된다고 ? Promise.all


사진 여러개 올릴꺼면 이렇게 반복문 하면 될거 같은데,,, 아닌가?
for문 한번씩 도는동안 계속 await 기다릴순 없잖아 !

  • 일반적으로 promise는 오래 걸리는 작업이야 그러니까 큐로 빠져서 실행되겠지? (이벤트루프 기억하자)
    resolve는 실행완료
    rejects는 에러
    resolve가 실행이 될때까지 실행되는 애가 promise이다

    이건 프로미스를 쓰는 의미가 없겠지 ? 시간이 걸리는 작업을 할거니까
    이렇게 가짜고 url 올리는 시간은 3,1,2,초라고 하고 하나하나
    업로드 파일 함수인것처럼 해보자!

    전체가 6초 걸리는걸 볼수 있다

-> promise.all은 promise들을 배열안에 나열해서 써서, promise들을 한번에 실행시켜줄 수 있다 !

  • async await를 쓰면 안에있는 promise들이 다 받기를 기다렸다가 아래로 내려간다 !

    이러면 모든걸 한번에 받아올때까지 기다렸다가 보여줄테니까 3초밖에 안걸리겠지?
    그러면 담아온 result 에는 배열로 resolve 값들이 담겨서 오는걸 볼 수 있다.

    근데, promise들
    똑같은거 3개쓰기 귀찮으니까!
    리팩토링해보자 !
    배열안에 원하는 값들을 넣어놓고 map으로 돌려주면,, 밑에처럼 결과가 나오겠지?

    이걸 사진 올리는데 적용을 해보자
    저기 variables가 files가 되어야겠지 !

- 이미지를 내가 원할 때 불러올 수 있대 !

- LazyLoad vs PreLoad

특정 페이지에 들어와서 내려가면서 화면이 보일때,,
원할때만 받는거 LazyLoad라고 한다
처음 사이트에 들어가서 다 받는것이 아니라,
스크롤을 내리면 그때그때 필요한 이미지를 다운받는것을 네트워크에서 볼 수 있다 .

->자주사용하는 라이브러리사용

  • react-lazy-load


    특정 페이지에 들어가기전에 사전에 미리 받아놓는것 PreLoad
    -> 간단한 코드작성 몇줄이면 된다. 진짜?
    useEffect를 통해서 처음에 페이지에 들어왔을때 다 다운받아준다

    라이브러리 소개!
    react-dropzone(이미지 끌어다 놓았을때 로드되도록 하는!)
    react-avatar-editor(사진을 확대 축소 조정 편집기기능 )
    react-breautiful-dnd(드로그앤 드롭하는 부분)
    google-page-speed-insights(모바일속도, 웹속도를 측정할수 있는 사이트)
    jpg to webp - 파일변환
  • 포트폴리오 해쉬태그 적용방법
  1. state에 해쉬태그 하나의 값, 태그들이 들어갈 배열이 필요하다
  2. 태그를 배열에 담아줄거고, array로 가져와서 뿌려주게 된다




  3. 키보드 이벤트 중에 하나인 , onKeyUp={} 함수를 input태그에 만든다
  4. 이 함수에서는 event가 발생한다. 조건문으로 판별해주자
    if(event.keyCode === 32 && event.target.value !==" "){
    여기는 스페이스바 그리고 빈값이라면? 이라는 조건 ?
profile
SUNNY SUMMER ! 같이 일하고 싶은 개발자 여름이의 초심을 잃지 않기 위한 주절주절 부트캠프 시절 블로그.

2개의 댓글

comment-user-thumbnail
2022년 4월 27일

안녕하세요~ 갑자기 실례해서 정말죄송합니다 ...개발자로 전향하려는참에 코트캠프에관하여 몇가지 질문이 있는데 이메일 같은걸로 혹시 질문좀드려도될까요?!ㅜㅜㅜㅜ

1개의 답글