31Days

김하은·2023년 2월 28일
0
post-custom-banner

이미지 업로드 -> 파일선택후 스토리지로 --> 이 다운로드한 주소를 벡엔드로 보내고 이 주소를 다시 받아서 미리보기로 나타나게함. ===> 미리보기 느림.

가장 중요한 문제는.. 이미지 업로드를 하려고 사진을 선택했는데, 글 등록을 취소했다. => 그렇지만 이 업로드시도를통해 이미 스토리지로 날라가 저장되었다. ===> 이미지 찌꺼기가 남았다.

해결방법 2가지.

  1. 브라우저자체에서 사진에 접근할 수 있는 임시 url을 만들기. => 미리보기 빠름.
  2. 브라우저 자체에서 임시 url만들어 저장해놨기에 이미지 찌꺼기 남는것 해결됨.

CreateBoard하기전에 uploadFile먼저하면서 임시 url만들고,
이후 등록하기 버튼 누르고나서야 스토리지에 저장되며 => 등록하기 하면서 업로드가 일어나고, 그후에 이 두개를 합쳐 CreateBoard가 요청된다.

=> 각각 장단점이 있으나 이 방법이 더 낫다.


  • 일단 업로드를 하지않는다.
const onChangeFile = async (
    event?: ChangeEvent<HTMLInputElement>
  ): Promise<void> => {
    const file = event?.target.files?.[0]; // 배열로 들어오는 이유 :<input type="file" multiple/>일때 여러개 드래그 가능

    if (file === undefined) return;

    console.log(file); // 선택한 파일을 콘솔로 찍어본다
  // 1. 임시 URL생성 => 가짜 URL 생성 -> 내 브라우저에서만 접속가능
    const result = URL.createObjectURL(file);
    console.log(result);
  }

  • 임시 URL이지만 =>진짜 Url생성

    const onChangeFile = async (
      event?: ChangeEvent<HTMLInputElement>
    ): Promise<void> => {
      const file = event?.target.files?.[0]; // 배열로 들어오는 이유 :<input type="file" multiple/>일때 여러개 드래그 가능
    
      if (file === undefined) return;
    
      console.log(file); // 선택한 파일을 콘솔로 찍어본다
    // 2. 임시 URL생성 => 진짜 URL 생성 -> 다른브라우저에서도 접근가능 (사진 자체를 텍스트 형태로 바꾼것이기에)
    
      const fileReader = new FileReader(); // 파일을 읽어줘
      fileReader.readAsDataURL(file); // 이것을 읽어줘
      fileReader.onload = (event) => {
        // 다 로드가 되면(로드되어 들어온 event의 target
        console.log(event.target?.result);
      };

    코드줄은 처음방법이 더 짧아보이지만,(어차피 벡엔드로 보낼것이 아니라 두 방법다 상관없음)
    안되는 브라우저가 있을수도 있어서 두번째 방법이 더 좋다.

    두번째 방법을 사용하여 코드를 마저 작성하였다.

    사진을 바로 받아옴을 볼 수 있었다.
    (업로드 해서 가져오는것이 아니라 브라우저 자체에서 사진을 주소로 바꾸어 만들어주어 만들어준 url을 state에 넣으면 이미지 미리보기가 가능하게된다.)


정리하자면!!

  • **일단 미리보기를 먼저해주어 좀더 빠르게 어떤 사진을 업로드 하는지 볼 수 있게하며 스토리지로 보내는것이 아니라 브라우저 자체에서 url을 만들어 보여주는겻이기에 스토리지에 이미지 찌꺼기가 남지 않는다. 그다음!
    DB에는따로 저장해야하는데, 등록시에 uploadFile뮤테이션을 실행해 스토리지로 보내고, 그때 구글클라우드에서의 사진이 저장된 url을 받아오고 CreateBoard시에 image부분에 이 url을 넣고 createBoard뮤테이션을 실행한다.
    **

    이렇게되면 빠르게 미리보기가 가능하다.(등록시에 두가지 api요청이 일어나 느리긴하지만...)


    업로드 하고 등록하는 방식으로 바뀌었음.

    Promise.all실습

    이미지 하나하나를 동시에 올리기 외부에 요청하는 부분은 거의 Promise로 이루어져있다.
    업로드 file이 5개라고한다면 promise가 5번 일어난다는것이고,,, await나 .then으로 받을 수 있다. 문제점:

    Promise가 3개 있을때...

    => 각기 받아오는 시간이 다름=> for문을 사용해 간단히 리펙토링 되지만, 다만... await들어가는 것은 같기에 코드상만 리펙토링된것이고, 성능은 변화없음.

    const startPromise = async () => {
            console.time("=============개별 Promise각각================");
            const result1 = await new Promise((resolve, reject) => {
              setTimeout(() => {
                resolve("성공1"); // 요청성공시 실행될 함수
              }, 2000);
            });
            const result2 = await new Promise((resolve, reject) => {
              setTimeout(() => {
                resolve("성공2"); // 요청성공시 실행될 함수
              }, 3000);
            });
            const result3 = await new Promise((resolve, reject) => {
              setTimeout(() => {
                resolve("성공3"); // 요청성공시 실행될 함수
              }, 1000);
            });
            const results = [result1, result2, result3];
            console.log(results);
            console.timeEnd("=============개별 Promise각각================"); // 전부 합친시간을 볼 수 있음. 서로동시에 요청하는것이 아니라 하나끝나면 다음것 요청되는식.
          };
    ``


Lazy-load(이미지 처음부터 다 다운받아오지 말자)

라이브러리 사용.

react-lazyload

사이트 성능 측정해주는 사이트

  • PageSpeed Insights

    Webp포멧 -> 사진의 용량을 줄이는 방법중에 하나인데 화질을 최소한으로 떨어뜨리기에 유용.

    -react-dropzone => 드래그해서 파일끌어다놓는식으로 업로드하는법 => 드래그해서 놓으면 onChange가 실행되는형식

    • react-beautiful-dnd => 끌어놓으며 스케줄등 정리할 수 있는 라이브러리


      이미지 프리로드.

      이전에 필요한곳에서 import했던 방식과 유사.

      useEffect사용으로 다이나믹 import를 했었음.

      useEffect를 사용해 페이지 접속했을때 미리 받음. = 프리로드

      그런데, 사용하지 않는것들을 넣는다면 메모리 누수가 생김. 따라서 꼭필요한 부분에만 적용하기(다음 페이지에서 보여줄 배너부분이고, 누구나 다음페이지로 넘어갈것같다 하면 이럴경우에 적용하면 훨씬 빠르게 적용할 수 있다.)


      프리패치 (다음페이지에서 사용될 html코드를 미리받아옴.)

      Data-prefetch

      다음페이지에서 보여줄 data를 미리 받아온다.

      접속하면 이미 다 나와있음.

      => 원래 data가 undefined였다가 후에 생기면서 화면에 그려짐.(랜더링 두번일어남.)
      지금은 목록에 마우스를 올리면 (onMouseOver)하면 해당 id의 것이 미리 받아지고, 있으면 벡엔드로 바로 갈것이니 빠르게 상세페이지를 보여줄것이다.

post-custom-banner

0개의 댓글