33일) 사이트 만들고, 기능연결만 되면 그게 개발자야? 찐 프론트엔드는 성능을 높이고 ! 최대한 빨리빨리! 과부하는 없도록! 최적화! Optimistic-UI/ SSR/ SEO CODE CAMP FE 6기

kimareum·2022년 4월 28일
0

코드캠프6기

목록 보기
33/36
post-thumbnail

> 다음주 배포를 앞두고 본 커리큘럼이 끝난지금, 2차 최종 평가를 앞둔지금 동기들도 많이 지쳐가는 모습이 보이고, 나도 예전처럼 마냥 밝거나 으쌰으쌰하는 마음이 떨어지고 지친것은 사실이다.
그럼에도 내가 계속해서 마인드 컨트롤을 하고, 그래, 다시 눈뜨고 집중해보자! 해보자! 할 수 있었던건 무엇보다 나와같은 열정을 가진 동기들이 있었고, 우리보다 더 늦게까지 남아서 많은 부분을 세심하게 케어해주고자 하는 코캠의 멘토님들의 열정이 느껴졌기 때문이다.
처음 코캠의 pf제도를 알게되었을땐, 혼자 공부하는것이 방해되는것이 싫었다. 왜냐면 나보다 못하는 동기 만나면 어쩌지? 내가 배울게 없을텐데? 그럼 나는 시간낭비일텐데 ? 하는 생각이었다 하지만, 나보다 잘하는 pf이건 못하는 pf이건 나는 코딩실력 뿐만 아니라, 그들의 생각하는 생각방식(뛰어난 해결방법을 들으면 그 방법을 듣는게 아니라 어떻게 그렇게 생각의 흐름을 정했는지 묻곤한다)과 열정 체력관리, 코캠 커리큘럼 외의 지식등을 공유하면서 정말 많이 성장해왔다.
저번 달에 조금 힘들어하던 pf와 2주동안 같이 지냈던 적이 있다. 이해하기 힘들어하는 모습을 보면서 어떻게하면 생각의 흐름을 간결하게 잘 전달 할 수 있을까 맵을 그려서 보여주기도 하고 말로 열변을 토하기도 했었다. 그 당시에는 시간이 꽤 오래 지나있기도 하고, 말하는것이 힘들다고 생각했었는데.
지금 와서 커리큘럼을 하나씩 복습하다 보니, 그때 내가 그를 위해 설명해주었던 내용들이 머릿속에 맵이 그려지듯이 뚜렷하게 남아있는 사실에 놀라웠다.
또 한번 편협했던 내 생각을 반성하고 혼자 성장하는것이 아닌, 동기들과 함께 성장하기에 더 커갈수 있는 기회를 만들어주는 코캠에게 감사함을 표하고 pf에게 받았던 힘나는 디코 한번 더 보고 오늘도 힘차게 !!!! 지치지 말고 나태해지지말고 다양한 사람들의 생각을 이해하고 시도해보려하고 그렇게 나아가보자 !

  • 오늘 배울 내용
    오늘은 Optimistic-UI와 SSR에 대해 알아봤습니다!


    Optimistic-UI실제로 성능을 높여주는 것이 아닌, 성능이 높아 빠른 처리를 하는 것 같이 보이도록 눈속임 하는 것이였습니다!
    Optimistic-UI는 이름처럼 낙관적 UI라 했죠? 특정 API요청을 보내기 전 요청 결과가 실패하지 않을것이라 가정하고 화면을 요청 성공이 된 것처럼 그려준 후 API요청을 보내준뒤, 결과가 돌아 온 후 다시 화면을 그려주는것이라 했습니다!


    즉, 비교적 느린 refetchQueries가 아닌 optimisticResponse를 사용해 미리 보여줄 데이터 값을 가지고 update()를 통해, cache state를 직접 수정했고, 요청이 완료되기 전 화면을 처리해줘 빠르게 눈속임 해주었습니다!


    우리는 이를 좀 더 쉽게 이해하기 위해 ‘좋아요’ 기능을 예시로 진행 했습니다!(느린 케이스 확인을 위해 network탭의 fast 3G를 사용해봤죠!?)
    Optimistic-UI를 모든 곳에 사용하면 안되겠죠? 결제와 같이 안정성이 필요한 중요한 부분에는 사용하지 않아야 했습니다!


    SSR(ServerSideRendering)도 알아봤죠!
    SSR을 알아보면서 OG(OpenGraph)를 먼저 이해했죠! OG란 html의 메타 태그 중 하나였습니다!
    특정 링크가 있을때 우리는 그 링크 만으로 해당 사이트가 어떤 사이트인지 알 수 없었죠! 그때 태그로써 미리보기 이미지나 사이트의 설명, 제목을 보여주는 역할을 한다 했습니다.


    즉, html 문서의 메타정보를 더 알아보기 쉽도록 표시하기 위해 사용되는 것입니다.
    이를 위해 우리는 html의 head가 아닌 Next.js의 Head를 import시켜 헤드 태그를 만들어주었습니다! Head안에는 meta태그를 통해 property와 content를 지정해주었습니다!
    이렇게 해주면 카카오,디스코드,슬랙 등 해당 플랫폼의 개발자분들이 미리보기를 구현시켜놓았기때문에 OG태그를 읽고 미리보기를 만들어 줄 수 있었습니다


    실습에서는 모두 하드코딩을 통해 진행했었죠? 하지만 상품상세 페이지라면 어땠나요? 품목마다 Head태그를 여러개 입력할 수 없었죠?
    meta의 content를 useQuery()를 통해 받아온 data의 값들로 채워주면 문제가 생겼죠! data요청이 가기 전 frontend-server에서 화면을 그려주기에 meta의 내용이 비어있게 되어 data를 받아올때까지 기다려야 한다는 점이였습니다!


    이를 SSR은 해결할수있었죠! 사이트에 대한 접근이 요청 되었을경우 SSR이 된 페이지라면 frontend-server에서 Browser를 거치지 않고 바로 Backend로 요청이 보내져 meta에 data들이 들어간 상태로 스크래핑이 가능했습니다!
    SSR을 사용하는 가장 큰 이유는 SEO(SearchEngineOptimization/검색엔진최적화)라고 했습니다!
    사전에 크롤러가 어떤건지 알아봤죠! 이를 시행하는 검색봇이 여러 검색엔진사이트에 존재합니다. 이 검색봇은 24시간 여러 사이트를 돌아다니며, 해당 사이트에 대한 정보를 읽어 해당 사이트가 어떤 사이트인지 판단하게 된다했습니다!


    하지만 사이트 안 내용이 있어야 특정 키워드들에 점수를 올려주게 되는데, 이 검색봇은 사이트에 들어와 내용을 다 받아올때까지 기다려주지 않았죠!
    그렇기 때문에 SSR로 처리를 하여 페이지에 대한 내용을 읽어 사이트 키워드 점수를 올릴 수 있게 해주는 것이 중요 포인트였습니다!

- Optimistic - UI

빠르게 할 수 없다면, 속여보자 ! (낙관적인 ui)

- > 실패해도 큰 영향이 없는 데이터,
실패할 가능성이 많이 없는 데이터에만 사용하자 !
실제로 99% 성공확률일때만 쓰세요! 라고 나와있다
(여러테이블에서 사용하지 않는 데이터일수록 Good)

  • 게시물 좋아요 기능을 생각해 봤을때 , 게시물 좋아요를 누르고
    다시 fetch api를 받아오는것은 너무 데이터가 왔다갔다 많지 않을까?

  • 좋아요 state를 따로 만들어서 데이터 전송을 하고, 브라우저에서만 살짝 바꿔서 보여주자

  • 바꿔서 보여준 그 값이 fetch값이랑 같으면 ㅇㅋ해주자 !
  • 우리가 기존에 했던 방법
  1. 다시 리패치쿼리 불러와서 api재요청
  2. cache(내 컴퓨터에 있는 데이터)만 조작해서 먼저 보여줌

    ^ 쿼리 써주고, variables 써주고 조작할 데이터 써준다음에 likeCount를 10으로 강제로 조정하는 모습 !
    (data에 fetchBoard에 _id와 __typename은 꼭 들어가야 한다 ! 안그러면 바꿀 cache를 못찾아 !)
    근데 우리는 10으로 바꿔줄게 아니라, 우리가 보낸 좋아요 뮤테이션값으로 바꿔줘야지!
    위에서 보내고 받은 데이터의 likeBoard로 바꿔주는 모습 !

    근데 여기 cache조정할때 (cache,{data}) 이 응답받은 {data}를 낙관적으로 받을수 있어!

-> optimisticResponse

안에다가 저렇게 aaa 는 3이라고 써주면
1. 처음에 updata에 data에는 aaa 가 3으로 들어오고
2. 두번째 위에 likeBoard 뮤테이션이 다시 들어가서 data.fetchboard.likeCount가 온다
3. 비교! 맞지 ?
4. 두번째 받아온거로 덮어 씌우게 되는거다 ! (값이 바뀌지 않고 같아야겠지 ?)

^cache 수정해서 받아오는 과정의 흐름인데, 이게 시간이 오래 걸리니까!

^뮤테이션은 아직 가고있는중인데, optimistic으로 화면에만 먼저 바꿔서 보여주자 !
-> 한번은 내가 조정한 optimisticresponse (가짜응답)을 받고, 두번째는 진짜 뮤테이션의 응답을 받아보자 !

  • 다른사이트의 정보 가져오기

    우리가 다른 사이트 들어가서 개발자 도구 켜봤을때,
    저 코드들을 string(싹다 문자열)으로 뽑아올수 있다면...
    소스코드를 가져올수 있지 않을까?

    근데 모든 태그와 문자열을 가져와서 내가 구분할 수 없으니까. 그거 해주는 라이브러리는 있어!
    일단 저 상자안에 있는 코드들은 어떻게 가져오지?


    이해하고자 하는데 필요한 지식 :
    우리 http를 통해 브라우저와 백엔드가 주고 받았는데
    http : text,와 HyperText(html)를 주고받음
    (문자들과 태그로 이루어진걸 http라는 길로 주고받는다 했지)

    그러면 postman 과 axios 로 요청해서 html파일을 받아볼수도 있겠지 ?

    -> 터미널에 curl을 이용해서도 html 파일을 받아올수 있따

    정규표현식으로 꺼낸 다음에 변수에 넣어놓고, state에 넣은다음에 보여준다던지...이런건 너무 많고 복잡하니
    Cheerio, Puppeteer라는 라이브러리를 써보자 !
    -> 두개 뭐가 다른데 ?

- Scraping (한 번 가져오기)- 한번에 긁어버려

- Crawling (꾸준히 가져오기)- 정기적으로 긁어버려

---잠깐지식----

  • 백엔드에서 데이터를 브라우저에 보내줄때...!
    JSON 쓰기전에..
    XML을 썼었다 ( 확장가능한 마크업 랭귀지 , 내가 이름 붙이니까)

    딱봐도 불편해 보이지 ?
    XML -> 여기서 발전한게 JSX(javascriptxml)
    자바스크립트해보면 자바스크립트가 만들어준 태그를 썼었지 , 그래서 onclick onClick 이었던거고
    실행할때는 자바스크립트가 onclick으로 잘 바꿔서 실행한다 !

Open-Graph / SSR

미리보기랑 서버사이드렌더링이 관련있다고?

  • meta 태그는 모지 ?
    내 사이트의 정보를 알릴때 사용한다

  • 저 og는 모지 ?

    아 헉 설마 카톡이나 다른데서 사이트 미리보기 할때 보여주는 태그가 meta인가보다 !

    그럼 우리가 사이트 만들때 이렇게 작성하면, 저절로 보여질까?
    그건아니야!

    각 사이트의 개발자가 어떤식으로 meta태그가 있는 페이지를 긁어와서
    og안에 있는것들을 꺼내서 이렇게 보여줄꺼다 !
    라고 개발을 해놔야 내 meta태그를 보여줄수 있는것이다 !

나는 이렇게 미리보기 보여줄꺼야(meta태그에 작성)!

너 meta태그 이렇게 보여줄꺼야(해당 사이트의 개발자가 작성)!

-> 이 두가지가 짝이 맞아야 저렇게 보여지게 되는것이다
-> 따라서 저 og 는 개발자들간의 약속이라고 할수 있겠지..?
페북에서 먼저 사용한 태그이다 (오픈그래프: 다른페이지에서 있는거 미리 이렇게 보여주자 )
트위터가 따라해서 twitter: title 이렇게 하기도 한다
1. 스크랩핑해오기
2. og 찾기
3. twitter 찾기
-> 이 과정으로 미리보기 그려주면 되겠다

그러면 제공해주는 입장에서 써보고
받아와서 보여주는 입장에서도 실습해보자 !

  • 내가 이해 못했던 흐름 부분(백엔드에서 진행하는 부분이라 했는데 과정이해필요)
    CORS 적용?? 결과를 백엔드 api 에서 받아오기
  1. 이렇게 axios로 요청하면 meta태그 포함 다 스크랩핑 할수 있는거 보이지 ?
  2. 그럼 저 빨간 부분을 떼려와야하니까 <meta 쓰여있는 부분안에 og를 뽑아올까?
    (실제로 이런 과정들을 진행할땐 잘 되는지 콘솔에 찍으면서 해보자)
    split을 meta로 먼저 한모습
  3. 그 뽑은거를 filter해서보여조 ! 뭐를 ? 그 각각의 el들이 includes하고 있니? (og: 얘네를 말이야 ) 있는 애들만 보여조!


4. 그러면 og: title인애만 보여줘봐

이런애들만 배열이니까 필터링 하면 되겠지 ?

-> 그 과정을 쭉 찍어본 코드이다 !
이거는 우리가 직접 meta 태그들의 정보를 뽑아오는 과정인데, 이과정을 쉽게 해결해주는 라이브러리가 있다 !

- SEO

검색엔진최적화도 서버사이드렌더링과 관련있대

  • 상품게시글 들어갈때마다 달라지는 상품과 이미지와 많은데이터들...
    미리보기 각각 다르게 보여주려면 (동적으로 보여주려는데 ) 이렇게 하면 되는거 아닌가요?

    안돼! 왜 안될까?
    맨처음에 axios curl postman 으로 스크랩핑할때(서버사이드렌더링할때)
    처음 접속해서 받아오는 html만 받아오고
    (이때는 큰틀과 껍데기만 받아온다고 했었지) ,


    2차적으로 usequery를 날려야하는데
    스크랩핑 과정에서 usequery를 기다려주진 못한다.
    애초에 html.java.css 받아올때부터 usequery같은 부분이 다 차있어서 data가 차있어야겠지


    yarn dev (프론트엔드의 서버프로그램, 24시간 켜있는) 여기서
    usequery의 데이터를 뽑아와서 html에 끼워서 보내준다음(서버사이드렌더링과정)에
    스크랩핑에서 데이터를 읽을수 있도록 해야한다

    -> 순수 react에서는 쉽지않았다 (html을 다 문자열로 바꿔서..데이터를 미리 불러와서 끼워넣고...다시 ..)
    -> 그걸 해결하기 위해 next.js를 쓴다 (getserverside....)

  • 검색엔진 봇들이 크롤러로 가지고 갈때도 데이터를 줘야한다
    (검색했을때 연관 키워드 저장, 검색엔진 성능 높이기..등 최적화를 위해서는 데이터가 필요하겠지!)
  • seo 서치엔진옵티마이저를 위해선 SSR 서버사이드렌더링이 필요하다 !
  • 그러면 모든페이지를 서버사이드렌더링해?(그거 옛날방식이다)
  • 아니! 필요없는데는 클라이언트 사이트렌더링해주고
    (먼저 받아와서 usequery나중에 채워주는거, 페이지 이동해서 보여주는거)
    - 서버사이드렌더링이 필요한 페이지에서 .getServerSideProps =()=>{}
    얘를 실행시켜주면 된다 !

    (없는페이지는 저절로 클라이언트사이드 렌더링 라우터.push / link태그를 사용해주는것 )
  • 메타가 바뀐다거나, 게시글/상품 상세내용(내용이 다 다르다보니까)등이 있는경우에 서버사이드렌더링 하면 되지 !
  • 캐싱 다시듣기

- 로그인 토큰 관련 이슈해결
우리는 기존에
accesstoken이 로컬 스토리지에 안들어가게 스테이트에 담았다.
새로고침하면 초기화가 되어서 기존 스테이트들이 날아갔다. 그래서 useeffect해서 쿠키에 있는 리프레시 토큰으로 재발급을 해줬다
근데 withauth필요한 페이지는 accesstoken이 로컬스토리지에서 받아오는거 였기때문에 튕긴다
그래서 accesstoken이 없으면 튕기게 해주면 될거같지 ?

근데 이거 안된다 ? 왜냐면 왼쪽아폴로 설정에서 새토큰 받기전에 오른쪽이 페이지에서 먼저 실행이 되거든
권한분기 페이지 설정하는 3가지 방법이 있어
그 해당페이지에서도 컴포넌트로 분리했던 getaccesstoken을 불러와서 다시 리프레시로 재발급하도록
그러면 권한분기먼저 들어갈때는 거기서 받고, 필요없을때는 아폴로에서 받겠지 !

근데 여기서의 문제는 withauth가 적용된 페이지는 accesstoken을 두번 받아오기 때문에,


getaccesstoken을 받아오는 과정에 상태값을 하나 넣어줘서 모든페이지에서
loaded 라는 recoilstate를 하나 만들어 줬다 .
처음에 true 두고 다 받아가지고 오면 false로 받아주고
withauth 페이지에서 loaded의 state가 false일때까지 기다려주는거로 하자
그러면 받아온 다음에 들어가게 되겠지



세번째 방식은
Recoilvalue는 가지고 오는거
변경도 가능하니 가져다 놓을수 있니
loadable은 ㄴ요청중인지 요청이 끝난건지 볼수 있는 부분이다
useRecoilvalueloadable
만들어서 atom 은 특정데이터, selector는 특정 기능을 넣을수 있으니까 이것을 쓰자

여기서 getaccesstoken 해서 받아다 올수 있겠금
get 부분의 함수를 여러 컴포넌트에서 공유를 하는것이다 (글로벌 state가 아니라 글로벌 함수라고 생각하자)
이렇게 글로벌 함수를 만들어서 불러와서 쓰면 되는데
withauth에서도 적어준다 ?
두번 적어도 useeffect 안에 getaccesstoken처럼 두번 실행되는것이 아니라, 글로벌 함수 는 한번 실행되면서 값을 여러번 뿌려주는 형식이기때문에 한번만 실행된다 !

profile
SUNNY SUMMER ! 같이 일하고 싶은 개발자 여름이의 주절주절 TIL 블로그. 기술 블로그 : https://summereum.notion.site/SUNNY-SUMMER-5d8c27f89cf040088999a027e9ddbfdd

0개의 댓글