Skip to content

✍ 주간 리뷰 및 회고

Mina Seo edited this page Dec 13, 2023 · 14 revisions

1주차

회고

서민아

개인의 성장 목표

  • reactts 잘 사용해보기!

기술적 고민거리

트러블 슈팅 경험

김찬우

개인의 성장 목표

  • React 의 동작원리 Deep-Dive
  • Three.js 로 3D 모델 렌더링 익숙해지기
  • FE 인프라 설계
  • 클라이언트 성능 개선 경험
  • 타입스크립트 익숙해지기

기술적 고민거리

  • 상태 관리 라이브러리의 사용은 언제 해볼까 ?
  • Socket.io 말고 추가로 CRDT 를 적용해볼 수 있을까? 아니면 우리 서비스에 Socket.io 로 실시간 채팅 말고 다른 기능을 적용해볼 수 는 없을까?

트러블 슈팅 경험

  • 모델링 클릭 이벤트시 여러번 이벤트 발생 → 모델링의 문제
  • 시야에서 3D 모델링이 보이지 않아도 onClick 이벤트 적용되는 문제 → Raycaster.params.DepthTest 보는 시야에서 광선을 쏘아 해당 모델이 보이는지 판단

오승엽

개인의 성장 목표

  • React랑 TS사용에 익숙해지기
  • Threejs, WebGL에 대해 학습하기
  • SPAs, CSR 학습

기술적 고민거리

  • 이번주는 기획이나 디자인 위주로 고민해서 많이 없긴 함
  • 프로토타입을 만들어보면서 성능적으로 고민을 많이 함
    • 여러 환경(성능)에서 테스트 해보는 방법 알아보기
    • 3d object 몇개까지 될지도 테스트 해봐야할거같음
    • raycaster 학습 필요
      • 장식 클릭 시 메시지 열려야 함
  • useFrame 사용시 컴포넌트가 unmount되기 전까지 계속 돌아감
    • 이 부분이 성능에 영향을 얼마나 줄지 알 수 없음
    • 성능상 문제 발생 시 R3F대신 Threejs직접 사용하거나 커스텀훅을 이용해야 할 것 같음

트러블 슈팅 경험

  • git branch 꼬여서 힘들었는데 찬우쿤이 도와줬다..

최진수

개인의 성장 목표

  • Nest.js 딥다이브 한번 날잡고 달려야 할 것 같다
  • 도커 공부를 하고
  • 페이스를 좀 더 높여야겠다

기술적 고민거리

  • 배포는 어떻게 할것인지
  • 트래픽이 몰리면 어떻게 해결 할 것인지
  • 서버에 대한 공격에는 어떻게 대응을 해야할지
  • 어느부분을 프론트가 하고 백이 하는지

트러블 슈팅 경험

  • 아직 까지는 없다

송현우

개인의 성장 목표

  • 서버, 배포, 도커, db에 대해 제대로 학습하기
  • 다수의 사용자를 관리해본 경험 갖기 (로드테스팅이라도 꼭 해보기)
  • 서버 부하를 줄이는 개인적인 기술적 도전 해보기

기술적 고민거리

  • 서버..도커.. 그게 뭔데..
  • 트래픽에 대한 고민
  • security를 어떻게 촘촘히 짤지

트러블 슈팅 경험

  • 아직 없다 !

2주차

회고

서민아

개인의 성장 목표

  • 쉽게 이해할 수 있는 코드 작성하기❗

기술적 고민거리

  • 링크 전송 시 미리보기 구현 어떻게 하지❓ meta tag
  • 공통으로 사용되는 부분 component
  • 라우터 처리
  • 애니메이션 구현
    • forwards 사용하면 애니메이션 마지막 상태 유지
      @keyframes fadeInUp { // 위로 투명해지며 올라가는 애니메이션
        from {
          opacity: 1;
          transform: translate(0, 0);
        }
        to {
          opacity: 0;
          transform: translate(0, -100%);
        }
      }
    
      @keyframes fadeOutDown { // 아래로 투명해지며 내려가는 애니메이션
        from {
          opacity: 1;
          transform: translate(0, 0);
        }
        to {
          opacity: 0;
          transform: translate3d(0, 100%, 0); // 3차원 좌표계
        }
      }

트러블 슈팅 경험

  • 깊은 depth url일 경우 public 파일들 불러올 수 없었음 ➡️ 경로 설정의 문제 pr

김찬우

개인의 성장 목표

  • useEffect 딥다이브
  • 애니메이션 효과를 좀 더 부드럽게 구현

기술적 고민거리

  • 재활용 하기 좋은 컴포넌트는 어떻게 설계하여야 할까?
  • 애니메이션을 렌더링하는 브라우저의 성능은 어떻게 최적화 할 수 있을까

트러블 슈팅 경험

  • three.js 의 카메라 포지션이 벡터 오브젝트 였는데 이걸 깊은 복사를 하지 않아 계속 값이 변경되는 오류가 있었다 → 최대한 깊은 복사를 지향하자..
  • 레이 캐스팅시에 리턴되는 mesh 오브젝트와 scene 내의 오브젝트는 달랐다. 3d 모델의 경우 mesh 오브젝트가 다수 일수 있어 해당 모델의 mesh를 순회하며 이벤트를 걸어주었습니다.

오승엽

개인의 성장 목표

  • React랑 TS사용에 익숙해지기
  • R3F, useFrame…

기술적 고민거리

  • 모델파일을 불러와서 사용하는데 scale이나 position을 조절하는게 힘들었음

    • 스케일계를 확인하고 규칙을 세움

    어떻게 지평 좌표계로 고정을 하셨죠?

  • 주사율에 따른 rAF속도 차이 해결

    • 처음에는 delta라는게 있는지 모르고 직전 프레임의 시간을 window.performance.now()로 저장해놨다가 구현하려고 코드를 작성하다가 delta라는 인자가 있는것을 알게되어서 쉽게 해결 할 수 있었음.
  • 내장그래픽 or 모바일에서 성능 최적화

    • s10 모바일에서 확인결과 gpu사용량이 99퍼센트가 된다고 함
    • 외장그래픽이 없는 노트북에서 cpu사용량이 너무 많아지고 느려진다고 함
      • snow를 지워보기도하고 애니메이션을 제거해보기도 했는데 고쳐지지 않음
      • 유리 재질을 가진 모델파일이 문제인가 싶어서 빼봤는데 빨라짐
      • blender에서 만들어온 재질이 gpu연산량이 많다고 생각함
        • 연산량이 적지만 유리처럼 투명함을 나타낼 수 있는 재질을 찾음
          • basicMaterial : opacity는 있었는데 유리처럼 빤딱빤딲 해지지를 않음
          • standardMaterial : basic보단 연산량이 많은것 같지만 유리재질을 비슷하게 표현할 수 있었음
      • material뿐만 아니라 useFrame을 각컴포넌트에서 가지고 있어서 생기는 문제가 아닐까 생각함
        • 이것을 해결하기위해 manager라는 컴포넌트를 만들어서 useFrame을 관리하려고 했음
        • useRef에 콜백을 담아서 manager의 useFrame에서 콜백을 실행시키는 방법으로 구현했었음
        • uesRAF = useFrame으로 생각하면됨
          • 해당방법으로 snow 100개상단에 부하를 걸어보고 manager에서도 부하를 걸어서 테스트를 해봤음
          • 본인 데스크톱기준 snow에서 for문 30만정도 해주니 프레임드랍이 생김
            • 같은 로직을 snow가아니라 RAFManager에 등록하니 프레임드랍 사라짐
            • 애니메이션을 한곳에 등록해서 사용하는 방식이 효과는 있을 수 있으나 callback 추가 삭제를 구현하기가 힘들 수 있음
            • 본 프로젝트에서는 3D object가 많아져도 200개가 안될것으로 예상되는데 애니메이션이 연산이 복잡한게아니라서 효과가 유의미하지 않을것으로 예상되어서 본 프로젝트에 적용시키지 않았음 → 나중에 문제생기면 다시 부활시킬수도..?
  • 붕어빵 안팜

    • 집중안될때 모델링하면서 쉬었음…

트러블 슈팅 경험

  • 이번주 고민거리가 다 트러블 슈팅이라 위의 내용과 동일함

최진수

개인의 성장 목표

  • 금요일날 진행했던 현황공유에서 다른 팀들의 진행상황을 보면서 더 분발해야겠다는 생각이 많이 들었습니다.
  • 주말까지 nest 공부 끝내자
  • 구현은 빨리빨리 하자

기술적 고민거리

  • 인프라를 처음 접해보아서 엄청난 난항을 겪었습니다. Nginx, 도커가 왜 필요한가, 어떻게 해야 안전할까 등 많은 것들을 생각하면서 서버 아키텍쳐를 생각해서 만들었지만 아직도 내가 만든것에 대한 믿음이 가지 않습니다.

트러블 슈팅 경험

  • github actions를 이용할때 백엔드 서버에서 도커 컨테이너가 풀 되지 않았습니다. 이유를 알아보다가 백엔드 서버가 private subnet에 들어가있어서 외부와 통신이 안되고 있었습니다. 이 부분을 해결하기 위해서 NAT gateway를 생성해서 백엔드 서버와 연결해주어서 아웃바운드 연결만 열어 주었습니다.
  • ssh bruteforce 공격을 받아서 어떻게 해결해줄까 고민하다 root ssh 액세스를 막아놓고 ssh 로그인용 유저를 새로 생성해주었습니다.

송현우

개인의 성장 목표

  • 기획단계에서 서버 구성에 대해 감을 잡기
  • FE입장에서 생각해서 API 명세서와 erd를 작성할 수 있도록 하기
  • 개발과정을 정리하고 블로그 포스팅 시도하기

기술적 고민거리

  • 서버를 효율적으로 구성하는 법
  • redis 활용하여 로그인 인증 관리 로직짜기
  • test코드 짜기

트러블 슈팅 경험

  • NAT Gateway연결
  • 서버 설계
  • REST API 설계
  • TypeORM 세팅

3주차

회고

서민아

개인의 성장 목표

  • 코드 작성 전 로직 생각하기
    • 나중에 틀 바꾸기는 너무 고생💦
  • 팀원분들께 배우기🙇

기술적 고민거리

트러블 슈팅 경험

// 🚨ERROR🚨

import { useContext } from 'react';
import { PrevProvider } from './PrevProvider';

const Visit = () => {
  const { view, setView } = useContext(PrevContext); 
  // Provider태그 밖에서 사용 ➡️ 변경감지 ❌
  // useContext를 Provider태그 안 자식들에서 선언❗

  return (
    <MessageProvider>
      <SnowGlobeCanvas back={setView} />
      <VisitHeader />
			{view ? <VisitButton /> : null} // setView 변경해도 view 변경❌
    </MessageProvider>
  );
};

export default Visit;

김찬우

개인의 성장경험

  • 스노우볼 줌 아웃 기능 구현
  • 라우팅 연결
  • 메타 태그에 대한 이해

기술적 고민거리

  • 라우팅의 기준과 좋은 라우팅 설계란
    • 깊게 고민하지 않은채 라우팅을 설계하여 SPA 느낌의 서비스가 드러나기 힘든것 같다.

오승엽

개인의 성장경험

  • 스노우볼 방문페이지 구현
  • axios로 api연동 해보기
  • useContext사용해서 상태관리 해보기
    • context type선언하고 초기화하는게 어려웠음
    • 초기값을 undefined로 하고싶었는데 그러면 type에 ‘ | undefined ‘ 를 추가해야함
    • 또한 undefined일때를 처리해주는 로직이 추가로 필요한 것 같음
    • 초기값을 목데이터로 해서 진행했음

기술적 고민거리

  • usecontext 로 상태 관리하기 useContext 상태관리
  • 100vh 기기마다 다른 문제
    • 사파리에서 주소창때문에 문제가 발생했음
    • 주소창을 합친 높이가 100vh라서 주소창 유무에따라 문제가 생김
    • 100%사용하니 해결되긴됐는데 … 찝찝함…

최진수

개인의 성장 목표

  • 배포에 시간을 조금 덜 들이고 이제 서비스와 비즈니스 로직에 더 집중할것이다.
  • 다음주에 예외처리와 벨리데이션을 완벽하게 해내겠다!

기술적 고민거리

  • 여태까지 인프라 관련된 것들에 집중을 많이 했었습니다. 하지만 서버측의 코드를 조금 더 꼼꼼하고 정확하게 작성해야 될것같습니다. 서비스 로직과 비즈니스로직이 현재 많이 부족한느낌이 전체적으로 들고있습니다.
  • 레디스에 리프레시 토큰을 담아서 엑세스 토큰이 만료 되었을때 갱신해주는 방식으로 바꿔야 할 것 같다.

트러블 슈팅 경험

  • 모르고 sudo chown -R proxyuser /. 를 그냥 실행해버렸다가 sudo su 가 실행이 안돼서 고치려고 서버를 포맷시킬까 생각했지만 같은 BE팀원 송현우님이 리커버리 모드로 들어가서 sudo 를 복구해주엇다!

송현우

개인의 성장 목표

  • 테스트코드까지 완성하자!!
  • 프론트 백 연동하는 법 익히자

기술적 고민거리

  • jwt token 관리하기 → refresh token redis로?
  • 테스트 코드 작성하기 → jest사용법 ㅜ
  • 프론트 배포 어떻게..?

트러블 슈팅 경험

  • 복구모드..
  • 쿼리 최적화
  • 서비스 로직 설계시 모듈 관계가 꼬여서 다시 작성하는 일이 생겼음 → 급할 수록 돌아가자 !! 미리 설계후 코딩하기

4주차

회고

서민아

개인의 성장 목표

  • 백과 API 통신 연결하기
    • 쿠키 저장을 백에서 해주다니❗🍪
  • 리팩토링,,,♻️

기술적 고민거리

  • 로그인 쿠키 어떻게 처리하지❓
    • 백에서 쿠키를 넘겨줌 ➡️ 자동으로 쿠키 저장됨
    • axios 소통 시 쿠키 값 자동 전달로 구현
    axios
      .get('/api/user', {
        withCredentials: true // axios 쿠키 값 전달
      })
      .then(res => {
        if (res.status === 200) {
          // 로직 구현
        }
      })
      .catch(err => {
        console.log(err);
      });

트러블 슈팅 경험

axios
  .get('/api/user', {
    headers: {
      Authorization: `Bearer ${cookieToken}`
      // 이렇게 쿠키 값 넘겨주지 않고 자동으로 전달되도록 설정하기
    }
  })
  .then(res => {
    if (res.status === 200) {
      // 로직 구현
    }
  })
  .catch(err => {
    console.log(err);
  });
  • vite, typescript, react 에서 .env 사용하기
// .env
VITE_APP_COOKIE_TOKEN = ABCDE
  // 홑 '' , 쌍 "" 따옴표로 감싸지 않기
  // 줄 끝에 , ; 를 붙이지 않기

// 실제 사용법
const cookieToken = import.meta.env.VITE_APP_COOKIE_TOKEN;

김찬우

개인의 성장경험

  • 스노우볼 생성 페이지 구현
  • axios 를 통한 Login 연동

기술적 고민거리

커스텀 훅 useSnowball 을 만들고 싶은데 어떻게 해야 효율적으로 커스텀 훅을 사용 할 수 있을까.

트러블 슈팅

오승엽

개인의 성장 목표

  • API 연동 해보기
  • 스노우볼 생성 기능과 스노우볼 조회 <> 버튼등 구현해보기
  • 리팩토링도 해보면서 중복코드를 뺀다던지 불필요한 렌더링을 막아보고싶음

기술적 고민거리

  • API 연동
    • visit페이지에선 authorize가 필요 없어서 구현하기 괜찮았음
    • login기능이 구현되어야 나머지 api를 연동할 수 있는데 로그인이 잘 안됨
    • 로그인 api를 axios로 요청하는줄 알았는데 그냥 a태그 등으로 이동시켜주면 되는거였음…
      • 로그인 성공하면 백에서 쿠키에 담아줌
      • 해당 쿠키를 포함해서 axios요청을 보내서 api통신에 성공함

최진수

개인의 성장 목표

  • 요번주에는 작성한 코드를 롤백을 많이 했다. 다음주는 시작전에 한번더 확인한후 진행해야 겠다.

기술적 고민거리

  • /api/snowball/:snowball_id/decoration api를 나누어야 할지 하나로 그냥 둬야 할지 고민이다.

트러블 슈팅 경험

  • 인터셉터, 커스텀 데코레이터, 파이프 개념들이 헷갈려서 여러번 잘못된 것으로 작성했다가 지우기를 반복했다.

송현우

개인의 성장 목표

  • 트랜잭션 잘 활용해보자

기술적 고민거리

  • 트랜잭션 범위를 어떻게 해야할까?
  • 격리 수준은 어떻게 해야할까?

트러블 슈팅 경험

  • 인터셉터와 파이프등을 도입하는 과정에서 불필요한 작업들이 많았던 것 같다

5주차

회고

서민아

개인의 성장 목표

  • 에러 디버깅🔥
  • 리팩토링,,,♻️

기술적 고민거리

  • import 시 다 다른 depth로 인한 복잡함

  • ThemeProvider

    • context 사용해서 속성 전달 가능
    import styled, { ThemeProvider } from 'styled-components';
    import { theme } from './utils';
    
    const App = () => {
      return (
        <>
          <ThemeProvider theme={theme}> // 자식 태그 내에서 theme 사용 가능
            <Outer>
              <Song />
              <BrowserRouter>
                <Routes>
                  <Route path="/" element={<Intro />} />
                </Routes>
              </BrowserRouter>
            </Outer>
          </ThemeProvider>
        </>
      );
    };
    import styled from 'styled-components';
    
    const StyledBox = styled.div`
      background-color: ${props => props.theme.colors['--black-primary']};
      // 다른 파일에서 사용할 때 props.theme으로 접근 가능
    `;
  • ~~.d.ts 파일 ➡️ definition으로, 타입스크립트를 위해서 정의

    • ThemeProvider 랑 같은 단에 styled.d.ts 파일 생성
    import 'styled-components';
    import theme from './utils/theme';
    
    type ThemeType = typeof theme;
    
    declare module 'styled-components' {
      export interface DefaultTheme extends ThemeType {}
    }

트러블 슈팅 경험

  • 너비가 정해져있고 글자가 넘을 경우, white-space: normal 속성으로 자동 줄바꿈 지원

김찬우

개인의 성장 목표

  • useContext 에 대한 딥다이브
  • useState 에 대한 딥다이브
  • createPortal , memo 에 대한 딥다이브

기술적 고민거리

  • useContext 의 provider의 value 로 useState 의 사용에 대한 고민
    • useState 의 set 함수를 provider 에 넣어 사용하는것보단 커스텀 훅을 만들어 상태관리를 시도하자.
  • react.memo 의 다양한 사용법 고민
    • props 의 참조 가 변경되었을때에만 감지함. 객체나 배열 내부의 값이 변경된것이라면 감지하지 못한다.
  • createPortal 은 특정한 컴포넌트도 등록할수 있는지 고민
    • useEffect 와 useRef 를 통해 원하는 컴포넌트에도 포탈을 만들어 하위 컴포넌트로 연결이 가능하다.

트러블 슈팅 경험

  • 직접 만든 모달이나 메세지 컴포넌트를 감싸는 div 영역에 클릭 이벤트를 걸어주었는데, 내부 컴포넌트까지 이벤트가 감지됨 (이벤트 버블링) → 내부 컴포넌트를 pointer-event : none 으로 시도해 보았지만, 해당 과정은 내부 컴포넌트의 이벤트를 무시하고 여전히 뒤 영역이 클릭됨 → 내부 컴포넌트에 Event.stopPropagation() 메서드를 적용하여 이벤트 버블링을 막음

오승엽

이번주 뭐했니

  • API연동 완료함
  • 스노우볼 생성부터 메시지 작성, 읽음처리 까지 다 구현
  • 무수히 많은 버그.. 잡기

고민…

  • useContext를 아직도 완벽히 이해하지 못한것 같았음
  • 메시지 읽음처리 할때 메시지읽음 api호출 후 다시 메시지정보를 받아오는 api를 호출해서 업데이트 시켜줘야하나?
    • 해당 방법은 메시지를 읽을때마다 요청을 보내는것이 효율적이지 못하다고 생각해서 메시지 읽음처리 api가 성공한다면 다시 데이터를 받아오지는 않고 이미 가지고있는 데이터를 직접 바꿔주었음
      • 어차피 새로고침이나 페이지 이동시에는 다시 fetch해오기때문에 정상적인 플로우에서는 문제가 없을것 같음
  • 메시지 읽음처리 해서 느낌표 없애줄때 산타가 다시 위에서 떨어지는 문제 발생!!
    • 원래 canvas내부에서 message정보를 가지고 map을사용해서 장식들을 생성해줬음
      • 그래서 메시지 정보가 바뀌면 캔버스전체가 리렌더링 되면서 메인장식이 다시 떨어짐
      • map함수로 장식을 생성해주는 컴포넌트를 별도로 분리했음
      • 원래 있던 context에서 스노우볼 정보와 메시지 리스트까지 전부 가지고있었는데 분리가 필요했음
      • snowBallData Context와 messageList Context를 분리했음
    • provider내부에 있는데 context값이 업데이트 되어도 리렌더링 시키고 싶지 않은 부분이 리렌더링 됨
    • 해당 컴포넌트에서 provider의 context값을 가져와서 사용하지 않으면 리렌더링이 일어나지 않을 줄 알았음
    • 근데 계속 리렌더링 되는거야….
    • 그래서 props로 data를 넘겨주고 React.memo를 사용해서 이전 props값과 비교해서 다를때만 리렌더링 되도록 해서 해결함

최진수

개인의 성장 목표

  • 시간이 없어서 테스트코드 까지 작성은 못하지만 마지막주에 부하테스트를 하고 조정을 해보도록 하자

기술적 고민거리

  • 현재 서버 한대에 백엔드 서버 하나를 돌리고 있는데 어디까지 감당이 가능한지와 안되면 다중화 어떻게 할지

트러블 슈팅 경험

  • jwt 엑세스 토큰과 리프레시 토큰 관리 로직들을 authService에 넣어줬다authGuard에서는 authService를 이용해서 access 토큰이 만기 되었으면 refresh 토큰을 검증하고 토큰의 payload를 이용해 access토큰을 재발급 해주는 방식으로 진행하였다. 이 부분에서 엑세스 토큰이 재발급 되지 않고 있어서 디버깅 하다보니 jwtService 모듈을 사용해 payload를 사인해주면 iat과 exp 가 들어간다. 이부분을 갖고 그대로 또 jwtService.sign을 해주면 exp가 벌써 포함되어있어 에러가 뜬다. 따라서 사인을 할 payload는 항상 iat과 exp가 없는지 확인해야한다.

송현우

개인의 성장 목표

  • 부하테스트 경험하기

기술적 고민거리

  • 트랜잭션 설정에 따른 부하 정도
  • 동시성 제어 테스트

트러블 슈팅 경험

  • 트랜잭션을 처음 적용해보면서 오해가 있던 개념들에 대해 다시 바로잡았다
Clone this wiki locally