안녕하세요,
프론트엔드 개발자 김민준입니다.

  • 나의 능력을 다른 사람에게 선보이는 것 을 즐깁니다. 이러한 성향을 바탕으로 사용자 및 소비자와 가장 가깝게 소통할 수 있는 프론트엔드 개발자를 선택했습니다.
  • 다른 사람과의 협업에 강점이 있으며 팀원과의 의사소통을 통해 결과를 만들어내는 것이 장점이 있습니다
  • 모든 일을 할 때 저에게 부족한 점을 배우려고 합니다. 결과도 중요하지만 과정을 통해 저 자신의 성장을 지향합니다.

Team Project.

FlawDetector | 코드 취약점 검사 시스템

FlawDetector | 코드 취약점 검사 시스템

2024.08 - 2024.09
웅진씽크빅 [Next.js 프로젝트 캠프 2기]에서 진행한 기업 연계 프로젝트 입니다. IT 서비스의 발전에 따라 발생하는 보안 사고 문제에 대응하기 위해 고안 된 프로젝트 입니다. AI를 사용해 소프트웨어 코드의 보안 취약점을 분석하여 해결책을 제시 할 수 있으며, 해외 취약점 관련 기사를 번역하여 제공해 사용자에게 보안 트렌드에 관련된 정보를 제공 할 수 있습니다.
TypeScriptNext.JSTailwind CSSTanStack-queryFirebaseLlama3 AI
기여도 40% / 5명 (FE 5)

담당파트

  • 전체 페이지의 퍼블리싱 및 기능의 40% 정도 구현

  • 사이트 상단과 하단의 Header, Footer 컴포넌트 퍼블리싱 및 기능 개발

  • 보안 사고 문제 기사들을 확인 할 수 있는 "취약점 DB" 페이지 퍼블리싱 및 기능 구현 100% 기여

구현 상세 내용

  1. cnnvd 사이트 https://www.cnnvd.org.cn/home/warn 의 취약점 게시글을 puppeteer 라이브러리를 사용해 크롤링한 뒤에 Llama3 AI 를 사용해 번역한 후 Firebase에 저장
  2. 저장된 게시글 데이터를 한 페이지에 5개씩 보이도록 구현
  3. 페이지네이션 직접 구현
  4. 상단의 3개의 배너는 현재 게시물 중 가장 최신의 게시물 3개를 게시, 또한 마우스 포인터 위치에 따른 애니매이션 구현
  5. HOT,NEW 버튼을 누르면 게시글을 최신순, 조회수 순으로 내림 차순 정렬 되도록 구현
  6. 게시글에 붙은 라벨은 조회수 상위 10개 게시물일 경우 HOT 라벨, 48시간 내에 업데이트 된 게시물인 경우 NEW라벨이 붙도록 구현
  7. 게시글의 핀 아이콘을 누르면 마이 페이지의 스크랩 된 게시물에서 확인 가능
  8. 게시글의 공유 아이콘을 누르면 게시글 상세 페이지 링크를 공유 할 수 있음
  9. 검색창을 통해 게시글 제목을 필터링 하여 나열 할 수 있음
  10. 우측의 실시간 토픽은 가장 많이 검색된 검색어를 내림 차순으로 나열
  11. 비 로그인 상태일시 접근 할 수 없도록 예외 처리 구현
  12. 페이지 로딩시에 skeleton ui 직접 구현하여 로딩 상태 구현
  • 보안 사고 기사글의 상세 내용을 볼 수 있는 "취약점 DB 상세 페이지" 퍼블리싱 및 기능 개발 90% 기여

구현 상세 내용

  1. 취약점 DB 페이지에서 게시글을 클릭하면 게시글의 제목, 게시 날짜, 라벨, 내용 등을 확인 할 수 있도록 구현
  2. 게시글 내용에 테이블이 존재 할 경우, 사용자가 데이터를 테이블 형식으로 볼 수 있도록 구현
  3. 핀 아이콘과 공유 아이콘을 통해 "취약점 DB" 페이지와 같이 스크랩, 공유 기능을 구현
  4. 하단의 비슷한 정보글은 같은 회사에 관련된 정보글을 가져오도록 구현
  5. 우측 하단의 버튼을 통해 게시들에 관련된 질의 응답이 가능 하도록 AI를 훈련하여 QnA 구현
  6. 페이지 로딩시에 skeleton ui 직접 구현하여 로딩 상태 구현

성과

  • 웅진씽크빅 [Next.js 프로젝트 캠프 2기] 우수상 수상

이슈 및 트러블 슈팅

1️⃣ puppeteer 라이브러리의 click 메소드와 setTimeout 함수를 통해 크롤링 타겟 페이지 내의 원하는 정보 얻어오기 구현

원인:

  • 회사측으로 부터 전달 받은 크롤링 타겟 페이지('https://www.cnnvd.org.cn/home/warn') 가 페이지 네이션, 글 상세 보기 와 같은 이벤트가 발생했을 때 url이 변경되지 않고 SPA 형식으로 이벤트가 처리 되는 것을 확인
  • 이 때문에 url을 통해 페이지에 접근 하는 것이 아닌, 페이지와 상호작용을 통해 원하는 데이터에 접근 하는 방식을 고안할 필요성을 느낌

해결

  • 이벤트가 발생 할 때 마다, 약간의 지연 시간이 발생한 뒤에 렌더링이 되는 것을 확인. 때문에 puppeteer의 click 메소드로 페이지와 상호 작용을 하며, 매번 click 이벤트가 일어날 때 마다 setTimeout을 사용해 지연 시간을 주어서 페이지와 상호 작용을 하는 방법을 고안
  • 시뮬레이션 결과 페이지와 성공적으로 상호 작용을 하는 것을 확인, 이후에 각 click 이벤트 사이에 데이터를 얻어오는 코드를 추가하여 크롤링 함수 개발 완료

2️⃣ 크롤링 데이터 번역 과정을 통해 발생하는 막대한 로딩 시간 확인. 사용자 로딩 시간 단축을 목적으로 크롤링 데이터 업데이트 방식을 변경

원인:

  • 최초에 회사의 기획에 의하면 매일 전체 크롤링 데이터를 가져와 캐싱하는 방식으로 구현 요청을 받음.
  • 크롤링 타겟 사이트가 중국 사이트 이므로 데이터를 가져올 때 번역을 해서 저장 해야 하는데, 이 때 하나의 기사의 데이터를 전부 크롤링 한 뒤에 한꺼번에 번역하는 것이 로딩 시간이 덜 걸릴 것으로 생각(한번 번역 할 때 마다 약 3000~6000ms 소요)
  • 그러나 Llama ai가 한꺼번에 번역 할 수 있는 데이터가 2024자 이므로 한번에 하나의 기사 전체 데이터를 번역 하는 것이 불가능 한 것을 확인(하나의 기사 당 약 20000자 이상의 글자 수)
  • 때문에 데이터를 쪼개서 가져 온 뒤에 각각 번역 해야 함
  • 하지만 이 방식으로 했을 때 하나의 기사를 전체 번역 후 저장 할 때마다 약 5분정도의 시간이 걸리는 것을 확인
  • 때문에 100개의 기사를 가져올 경우 약 300분의 시간이 소요 되므로, 현재 방식에서는 매일 300분의 로딩 시간이 발생되는 것이 우려됨

해결:

  • 데이터를 매일 매일 가져온 뒤 캐싱 하는 것이 아닌 파이어 베이스에 저장 하는 방식으로 변경
  • 이후 매일 데이터를 업데이트 할 때 가장 최신의 기사보다 업로드 날짜라 빠르면 데이터를 가져오는 방식을 선택
  • 이를 통해 매일 올라오는 게시글 수에 비례 하여서 로딩 시간을 가질 수 있으므로, 초기 계획에 비해서 로딩 시간 단축 성공

3️⃣ 아티클 테이블 데이터를 firebase 형식에 어긋나지 않기 위해 객체 형식으로 저장

원인

  • 크롤링 해야 하는 데이터 중에 <td>, <tr> 태그로 이루어진 테이블 데이터가 존재함
  • 처음에는 이 테이블 데이터를 크롤링 할 때 string[][] type 으로 저장하려했음
  • 그러나 firebase는 중첩 배열을 지원 하지 않아서 다른 type으로 저장 해야 했음
  • 이 때문에 데이터 저장 tool을 firebase가 아닌 다른 것으로 사용하려 했으나, 기업에서 firebase만을 사용하길 요청받음

해결

  • 테이블 데이터를 string[][] type이 아닌 object[] type으로 저장 하는 것으로 결정
  • 각 행의 데이터를 열의 개수에 따라 column1, column2, column3... 를 key로 하여서 object type으로 저장
  • 이러한 방식으로 모든 행의 데이터를 수집해 배열 type으로 엮으면 테이블 데이터를 object[] type으로 저장 가능
  • 이후 이렇게 저장한 object 데이터를 화면에 렌더링 할 때, 각 column들의 순서를 보장하기 위해 다음과 같은 배열을 사용해서 렌더링
    const keyArray = ['column1','column2','column3','column4' ....]

성과 및 느낀 점

1️⃣ 팀에서 컨밴션을 확실하게 정하고 코드 리뷰를 통해 서로의 코드를 보완하며 진행 하니 좋은 결과물이 나온 것 같다

  • 프로젝트 시작을 할 때 파일 이름, 함수 이름, type 작성, git 과 같은 대부분의 방면에서 컨밴션을 정하고 진행을 하으며, pr이 올라오면 팀원들 모두 코드 리뷰를 철저히 진행을 하였다.
  • 이러한 과정을 통해 대체적으로 코드들이 일관성이 있어서 서로의 컴포넌트들을 사용 및 수정 하기 쉬웠다. 또한 코드 리뷰 과정에서 내가 몰랐던 개발 방식에 대해 많이 공부 하게 된 점이 좋았다.
  • 결과적으로 지금 까지 내가 진행했던 프로젝트 중에서 진행 기간은 가장 짧았지만, 코드 가독성 이나 UI/UX 와 같은 종합적인 면에서 가장 완성도 있는 프로젝트였으며 많은 것을 배울 수 있었다.

2️⃣ 짧은 기간 내에 완성해야 하므로 성능을 고려 하지 않고 기능 구현을 한 점이 아쉽다.

  • firebase가 offset과 중간 키워드 검색 query를 제공하지 않아서 pagination과 검색 기능을 구현 할 때, 전체 데이터를 불러와서 처리하는 방식으로 구현됨
  • 이 방법이 데이터베이스로 부터 필요한 데이터만을 가져 오는 것이 아닌, 전체 데이터를 가져오기 때문에 Firebase 사용량을 초과 할 수 있는 위험이 있다. 때문에 필요한 데이터만을 가져오는 방식으로 성능 개선이 필요하다고 생각했다.
  • 그러나 시간 부족으로 인해 최종 발표 때 까지 개선하지 못했다. 때문에 이후에 리팩토링을 하면서 개선할 것이다.

3️⃣ Next.js를 사용해 풀스택 개발을 진행해본 것이 새로운 경험이었다.

  • 이전까지 팀 프로젝트를 할 때는 백엔드로 부터 api를 제공 받으면, 그것을 client에서 처리하는 온전히 프론트엔드 작업만 진행했었다.
  • 그러나 이번 프로젝트에서 내가 맡은 페이지는 데이터베이스 부터 내가 직접 설계하고 구현해야 했기 때문에 페이지에서 필요한 모든 것들을 0 부터 100까지 개발하는 풀스택 개발을 하였다.
  • 직접 필요한 데이터를 구해서 저장하고, field를 설계 하며 '이것을 프론트에서 어떻게 처리하지' 와 같은 고민을 통해 백엔드에 대한 지식을 좀 더 얻어가는 프로젝트 였던 것 같다.
PlanIT

PlanIT

2024.03 - 2024.04
헬스장 내의 회원 및 트레이너들이 원만하게 PT와 맴버쉽을 사용할 수 있도록 해주는 프로젝트 입니다. 사용자는 회원, 트레이너, 관리자 3개의 권한 중에 하나를 부여 받아서 이용할 수 있습니다.
TypeScriptReactStyled-ComponentsZustandReact-query
기여도 50% / 5명 (BE 3, FE 2)
  • Zustand를 선택한 이유

    • reduxzustand 중에서 고민
    • 초기 기획 시에 페이지 수가 적게 와이어 프레임이 설계됨. 또한 전역으로 관리 해야 될 상태가 적을 것으로 예상(endpoint가 유저, 트레이너, 어드민 으로 나누어져 있었기 때문)
    • 때문에 무거운 redux 보다 zustand를 사용하는 것이 프로젝트에 더 효율적이라고 판단
    • 그리고 zustand와 조합하기 위해서 react-query를 추가적으로 선택

    담당파트

  • admin 파트 전체 페이지 개발
  • 마이페이지 정보 확인 및 정보 수정 개발

이슈 및 트러블 슈팅

1️⃣ 계정 권한에 따라 Header에 다른 menuList가 표시 될 수 있도록 component 및 hook 재 설계

  • 원인:

    • 처음에는 계정 권한에 상관없이 메뉴 리스트의 디자인이 동일하였음
    • 그러나 어드민 파트에 페이지가 추가 됨으로 인해서 본래의 메뉴리스트 형태를 사용하면 디자인이 어그러지는 것을 확인
  • 해결:

    • 어드민 권한으로 로그인을 할 때 메뉴 리스트가 다른 디자인으로 표시 되도록 결정
    • 메뉴 리스트를 표시 하던 컴포넌트를 각각 일반 메뉴, 어드민 메뉴 로 컴포넌트를 분리하여 리팩토링

2️⃣ API 호출 횟수를 최소화 하여 성능 개선

  • 원인:

    • 전체 회원 조회 페이지에서 회원 한명의 정보를 보려면 전체 회원 정보 api, 회원 상세 조회 api 이렇게 두 가지를 호출 해야함.
    • 대부분의 페이지가 위와 같은 방식이어서 로딩 속도에 영향이 끼칠 것이 우려됨
  • 해결:

    • 전체 회원 조회 페이지에서 회원 한명의 element를 클릭하면 회원의 정보를 zustand를 사용해 캐싱 해두어서 확인 할 수 있게함. 이러한 방식으로 api 호출 횟수를 최소화

꼬망스 24학번 지원 사이트

꼬망스 24학번 지원 사이트

2023.12 - 2024.02
인하대학교의 중앙 밴드 동아리인 ‘꼬망스’의 24학번 대상 홍보 및 지원 페이지 입니다. 이 웹 서비스를 통해 신입생분들이 꼬망스에 대한 자세한 정보를 쉽게 접할 수 있으며, 꼬망스에 지원까지 할 수 있는 페이지 입니다.
TypeScriptNext.JSTailwind CSS
기여도 70% / 3명 (디자이너 1, FE 2)
  • Tailwind CSS를 사용한 이유

    • 서버 코드 없이 클라이언트 코드만 존재하는 프로젝트 였기 때문에 무엇보다 처음 렌더링 되었을 때 사용자에게 가장 빠른 속도로 페이지를 제공 하는 것이 목적이었음
    • 때문에 CSS-in-js 형식의 라이브러리를 사용할 경우 위의 목적에서 조금 아쉬울 수 있을 것이라고 생각
    • 또한 2명의 개발자 모두 Tailwind CSS를 협업 프로젝트에서 사용해본 적이 없어 이번 기회에 Tailwind CSS의 까다로운 문법을 좀 더 익히고 단점과 장점을 파악해 보려함

담당 파트

  • 프로젝트 팀장
  • 프로젝트 전체 아이디어 및 디자인 초안 기획
  • 프론트 기본 폴더 구조 제작 및 초기 세팅
  • 서비스 전체 레이아웃, Header, Footer등 공용 컴포넌트 구현
  • 인트로 페이지, About COMMENCE 페이지, FAQ 페이지 퍼블리싱 및 기능 구현
  • React => nextJS로 프로젝트 마이그레이션

이슈 및 트러블 슈팅

1️⃣ robots.txt 추가 및 index.html 수정을 통해 라이트 하우스 SEO 점수를 100점으로 개선

  • 원인:

    • 홍보 사이트인 만큼 SEO도 중요하다고 생각을 하였으며, 초기 SEO 점수가 77점 이었기 때문에 개선이 필요하다고 생각
  • 해결:

    • 라이트 하우스에 명시된 해결 방안 대로 개선 시작.
    • robots.txt 추가
    • 모든 페이지 최소 폰트 크기 11px로 맞춤
    • index.html<meta> 태그 및 <title> 추가를 통해 페이지 소개 문구를 작성
    • SEO 점수가 77점 → 100점으로 증가

2️⃣ 이미지 확장자 변환, 자바 스크립트 압축을 통한 성능 개선

  • 원인:

    • 대부분의 페이지에서 사진 파일의 용량이 커서 사진 로딩 시간이 긴 것을 확인
    • 또한 js 압축을 통해 잠재적인 속도 개선을 기대 할 수 있는 것을 확인
  • 해결:

    • 사용되는 이미지들의 확장자를 gifwebp로 변환. 또한 이미지의 크기를 렌더링 되는 크기에 맞게 축소
    • webpack.config.js의 설정을 통해 자바스크립트를 gzip 로 압축
    • 위의 과정들을 통해 라이트 하우스 기준 성능 점수 50점 → 77점으로 상승
강아지 분양 서비스 펫트리(Petree)

강아지 분양 서비스 펫트리(Petree)

2023. 10 - 2024. 02
강아지 입양 희망자와 분양자(브리더)를 연결하는 서비스입니다. 이 서비스를 통해 신뢰성있는 분양과정을 진행할 수 있습니다.
TypeScriptReactStyled-ComponentsRedux-toolkit
기여도 50% / 5명 (디자이너 1, BE 1, FE 3)
  • Styled-component 를 사용한 이유
    • 페이지 수가 많은 팀 프로젝트인 만큼 공통 컴포넌트의 사용 갯수가 많을 것으로 예상했음
    • 이 때문에 코드의 가독성과 prop를 사용한 동적 스타일링이 좋은 styled-component를 사용하기로 결정
    • TailWind CSS 사용 의견도 있었으나, 사용해보지 않은 분이 계셨으며 최초에 프로젝트가 결성 될 때 빨리 완성을 하는 것을 목표로 하였기 때문에, 익숙해지는 데에 어려운 TailWindCSS를 사용하지 않도록 하였음
  • Redux-toolkit을 사용한 이유
    • 상태 관리 라이브러리로 reduxzustand 중에서 어떤 것을 사용할지 고민하였음
    • 프로젝트를 빨리 완성하는 것이 목적이긴 했지만, 페이지 수가 많으며 다루어야 할 state의 수가 많을 것으로 예상
    • 이 때문에 zustand에 비해 복잡하지만 좀 더 구조적이고 표준화된 redux를 사용하기로 함
    • 그리고 코드를 간결화 해주기 위해 redux-toolkit을 사용하기로 함

담당 파트

  • 프론트엔드 개발자로 참여
  • 브리더 모아보기 페이지, 강아지 모아보기 페이지, 마이페이지 프로필 관리, 회원 정보 수정 퍼블리싱 및 기능 구현
  • 총 3가지의 공통 컴포넌트를 제작
  • 리덕스를 사용한 모아보기 페이지 세부 컴포넌트 및 사용자의 프로필 이미지 상태관리
  • 리덕스 가독성 및 사용 시에 오류 방지를 위한 폴더 이동
  • 제작한 페이지 및 컴포넌트 반응형 작업
  • 팀원들의 코드 리뷰 및 트러블 슈팅 지원

이슈 및 트러블 슈팅

1️⃣ 분양희망자 주거환경 (등록/수정/삭제) 기능 구현을 set type 과 blob type을 사용하여 설계 및 구현

  • 원인:

    • 주거환경 (등록/수정/삭제) 기능 구현 시에 사용하는 api put 메서드를 사용하기 위해서는 삭제될 이미지 id 리스트를 body에 추가해야함. 그러나 사용자가 하나의 필드에서 여러번 이미지 삭제를 사용하는 경우 같은 id가 여러 번 리스트에 추가 될 수 있음
    • 또한 이미지 id 리스트를 보내더라도 백엔드 서버에서 type 에러가 발생함
  • 해결:

    • 이미지 id 리스트를 submit 하는 과정에서 리스트의 type을 set type으로 변환해서 중복을 제거 한 뒤에 다시 Array type로 변환함
    • 또한 Blob 객체를 생성하여서 이미지 id 리스트를 첫번째 인자로 받고 두번째 인자인 option으로 type을 지정. 이런 방식을 사용 하여서 type 에러를 방지

2️⃣ 이미지 업로드 시에 Resizer를 사용하여서 에러 방지 및 용량 축소

  • 원인:

    • 이미지 업로드 기능 구현 시에 용량이 큰 이미지를 사용하는 경우 백엔드 서버에서 용량 에러가 발생하여 업로드가 되지 않음
  • 해결:

    • react-image-file-resizer 라이브러리를 사용하여 업로드될 이미지의 용량을 축소한 다음 백엔드로 전송하여 에러 해결. 이후에 업로드 된 이미지를 다시 클라이언트로 표시 할 때 성능 향상도 기대해 볼 수 있음

3️⃣ 견종 자동 검색 컴포넌트 제작 및 공통 컴포넌트로 리팩토링

  • 원인:

    • “브리더 견종 관리 기능” 구현 중 PM 분의 요청으로 견종 입력 시에 자동 검색 창을 통해 입력 하도록 개발 항목이 추가 됨
  • 해결:

    • setTimeoutArray.filter , react-hook-form 라이브러리를 사용해서 검색어가 변경 되면 0.2초 후에 검색어와 일치하는 견종 목록을 반환 하는 방식으로 자동 검색 기능을 구현
    • 이후 회의를 통해 다른 페이지에서도 사용될 여지가 있음을 파악함. 때문에 컴포넌트 파라미터로 width 변수를 받아서 페이지의 프레임에 맞게 재사용 하도록 리팩토링

4️⃣ 사용자 프로필 이미지가 Header 에 제대로 반영 되도록 redux와 localstorage를 사용해 재 설계 및 구현

  • 원인:

    • 로그인, 로그아웃, 프로필 이미지 수정 등 헤더에 표시할 프로필 이미지를 변경하는 이벤트가 발생하면 ,redux의 프로필 이미지의 상태를 관리하는 state를 사용해 변경 하도록 개발함. 그러나 페이지 이동 시에 state가 초기화 되어서 기본 이미지로 되돌아가는 현상 발생

-해결:

  • 로그인,로그아웃,프로필 이미지 수정 시에 프로필 이미지 url을 localstorage에 저장하도록 설계. 이후 Header 컴포넌트에서 localstorage에 저장 되어 있는 url을 가져와 프로필 이미지를 표시 하도록 구현함

성과 및 느낀 점

1️⃣ 폴더 구조에 대한 논의 없이 프로젝트를 시작했기 때문에 폴더 구조가 뒤죽박죽인 상태로 완성이 된 점이 매우 아쉽다.

  • 최초에 프론트 팀장 분이 page, component, assets, type으로 대분류를 해주시긴 했지만, 폴더 깊이와 폴더 생성 기준에 대한 것을 정해 놓지 않은 상태로 각자의 스타일에 따라서 개발을 하다보니 폴더 구조가 많이 복잡해졌다.
  • 이 때문에 제 3자는 물론, 직접 폴더를 만든 사람 입장에서도 컴포넌트 찾기가 매우 어려웠고, 같은 이름의 폴더가 존재 하는 경우도 있었다.

2️⃣ 폴더 구조 뿐만 아니라 코드 컨밴션 이나 공통 컴포넌트 사용 등에 관해서도 깊게 이야기 하지 않은 것이 아쉽다.

  • 각자의 코드 추상화 정도의 차이가 컸기 때문에 제 3자의 입장에서 코드를 파악하기 힘들 것 같다.
  • 그리고 처음에 공통 컴포넌트가 많을 것으로 예상하여 styled-component를 선택 했지만 정작 어떤 것을 공통 컴포넌트로 제작 할지 개발 이전에 이야기 한 것이 없어서, 개발 도중에 다른 사람이 만들어 놓은 것을 사용하는 방식으로 공통 컴포넌트가 결정 되었던 것 같다.

3️⃣ 나 혼자서 해결 하는 것보다 때로는 팀원들과 소통 하는 게 더 빠른 문제 해결이 될 수도 있는다는 것을 깨달았다.

  • 주거 환경 업로드 기능 구현 시에 어떻게 데이터를 전송해도 계속 에러가 발생해서 혼자서 1주일 동안을 고민을 하다가 백엔드 개발자에게 이야기 하고, 그 분이 api 수정을 해주셔서 빠르게 해결이 될 수 있었다.
  • 이러한 경험 덕분에 협업이라면 함께 문제를 해결 하는 것이 더 효과적일 수 있다는 생각을 했다.

4️⃣ styled-component가 아닌 TailWindCSS를 사용해서 프로젝트를 만들어보고 싶어졌다.

  • CSS-in-JS 의 특성상 스타일 코드가 js를 실행하는 때에 함께 실행되다 보니 js의 크기가 커져서 성능 면에서 아쉬움이 있었다.
  • 따라서 빌드 타임에 스타일이 생성되어 runtime 문제가 없는 tailwindCSS를 경험해보고 싶었다.

Award.

웅진씽크빅 [Next.js 프로젝트 캠프 2기] 우수상

2024. 04. 20
주식회사 웅진씽크빅웅진씽크빅과 유데미에서 개최하는 [Next.js 프로젝트 캠프 2기]의 프로젝트 결과 평가에서 15개의 팀중 상위 4팀에 뽑혀서 수상하게 된 상입니다.

Education.

인하대학교

2016. 03 - 2023. 02
컴퓨터공학과 학사 졸업

Certificates.

Opic IM1

2024. 02. 18
ACTFL