
최근 한 회사에서 진행 한 기술 면접에서 면접관분들이 나를 좋게 봐주셨는지, 바로 TeamFit 면접을 제안해 주셨다. 당시에 TeamFit 면접에 대해서는 준비를 하지 않은 상태여서 순간 고민했지만 왠지 지금 당장 TeamFit 면접을 진행하는 게 청신호인 것 같아 바로 진행했다. 내가 느낀 결과는 폭망. 핑계 아닌 핑계를 대자면 어느 정도 나라는 사람을 돌아보고 준비를 한 상태에서 면접에 들어갔어야 했는데, 그러지 못해서 그런가 면접에 들어가서 그런지 횡설수설하며 내가 하고 싶은 말도 제대로 못 했다.. 😥 역시 기회는 준비된 사람에게 오는 법 이라는 걸 다시 한번 느꼈다. 평소 내가 생각을 깊게 하고, 나에 대해 자주 돌아봤으면 면접이 망하는 건 극복하지 못하더라도 내 생각을 잘 표현할 수 있었..

최근 FitLink 프로젝트에서 디자인 시스템을 구축하면서, 모노레포로 이루어진 프로젝트의 각 도메인 내에서 디자인 시스템을 활용한 공통 컴포넌트를 구현하며 HOC(Higher Order Component)를 활용했던 경험을 공유합니다.우리가 코드를 인지 하는 간략한 과정얼마전부터 '프로그래머의 뇌'라는 책을 읽으며, 코딩에 영향을 주는 인지 과정에 대해 알게 되었습니다. 책에서 말하는 인지 과정은 아래와 같습니다.코드가 초래하는 혼란에는 코드에 대한 지식이 없거나, 필요한 정보를 가지고 있지 않거나, 코드가 너무 복잡한 경우다지식이 없는 것은 LTM(장기 기억 공간)에 해당 내용이 없는 것반면 지식이 아닌 어떤 정보가 부족한 경우 STM(단기 기억 공간)에 해당 내용이 없는 것많은 정보를 처리할 때(복..

현재 진행하고 있는 FitLink 프로젝트에서 디자인 시스템을 개발하며 어떻게 하면 확장성 있게 개발할 수 있을지 고민하였습니다.디자이너분께서 다른 디자인 시스템과는 차별화된 디자인을 만들어주셨고, 우리는 그 요구사항에 맞게 Headless UI를 지원하는 Radix Primitives를 사용해 우리의 입 맛에 맞게 커스텀하여 대부분의 디자인 시스템을 구현하였습니다.하지만 우리의 디자인 시스템 중, Radix Primitives에서 지원하지 않는 컴포넌트들은 어떤식으로 설계를 해야 확장성 있는 컴포넌트로 만들 수 있을지 정말 많은 고민을 하게 되었습니다.그렇게 수 많은 고민을 하던 중 확장성 있는 개발을 위한 방법 중 하나로, '제어/비제어를 상위 레벨에서 핸들링 할 수 있게 해주면 어떨까?' 라는 고민..

useState 동작을 직접 구현하려 하다보니 자바스크립트 기본기가 정말 중요하다는 것을 느꼈습니다. 이 글을 통해 간단하게 useState를 구현하면서 자바스크립트의 기본기와 더불어 useState의 동작 원리를 알아보려합니다.첫번째 useState 구현 시도우선 맨처음 useState를 구현했던 코드입니다. 해당 코드는 문제가 있습니다.function useState(state) { let _val = state; function setState(newState) { _val = newState; } return [_val, setState];}const [state, setState] = useState(0);console.log(state);setState(1);..

이번 글에서는 프로그래머스 데브코스에서 진행했던 프로젝트인 짤뮤니티를 Next로 마이그레이션 진행과 동시에 서버 이관 작업이 이루어지면서 생기는 불편함을 해결하기 위해 MSW를 도입했던 경험을 작성하려 합니다.MSW 사용 이유우선 위에서도 언급을 했듯이 React 환경으로 구현된 짤뮤니티 프로젝트를 Next로 마이그레이션 진행 작업과 동시에 서버 이관 작업이 이루어져 모든 API가 가동을 멈춰 페이지 및 컴포넌트가 제대로 작동을 하는지 테스트를 해 볼 수가 없었습니다. 이러한 불편함을 해결하기 위해 MSW를 도입하게 되었고, 이미 모든 API가 구현이 되어있었기 때문에 백엔드와 API 스펙에 대해 협의하는 과정을 생략할 수 있어 훨씬 수월하게 MSW 작업을 진행할 수 있었습니다.MSW란 무엇인가?MSW란..

현재 프로그래머스 데브코스를 수료한지 2개월 하고도 반절 정도가 지난 시점, 저는 6개월간의 프로그래머스 데브코스 과정에서 무엇을 배웠을까요?저는 데브코스를 처음 시작했을 때, 막연하게 아래 사진과 같은 목표가 있었습니다. 아래 사진은 데브코스 자기소개란에 적어두었던 저의 목표입니다 ㅋㅋㅋ 부끄럽네요 ㅎ 시간이 지나 다시 되돌아보니 어떤 기술을 얼마만큼 알았고, 어떤 기술을 사용해보았고, 코딩테스트 실력이 어떻고 이런것 보다 저는 개발자로서 커리어를 이어나가는 데에 중요하다고 생각되는 부분을 배운 것 같습니다. 문제가 아니어도 문제로 삼는 법(스스로 성장하는 법)우리는 늘 삶 속에서 문제를 마주하지만, 누군가는 문제를 마주하지 않을 수 있습니다. 하지만 문제가 되지 않을 것을 문제를 삼는다면, 그것은 문..

프론트엔드 개발자는 유저에게 좋은 경험을 제공해야 한다는 의무가 있습니다. 이번에는 프론트엔드 개발자가 유저에게 좋은 경험을 제공할 수 있는 skill중 하나인 preFetch에 대해 이야기 해보려합니다. 우리는 프로덕트를 개발하면서 유저의 다음 행동을 어느정도(?) 예상할 수 있습니다. 다음 예시를 한번 보시죠. 위 사진은 제가 진행한 '대박 사건'이라는 편지 서비스의 페이지 일부입니다. 해당 페이지는 박을 터트리면 박 속에 들어있던 편지지들이 나타나는 페이지입니다. 그렇다면 위 상황에서 유저의 다음 행동을 예상해볼까요? 1. 유저는 박을 클릭하여 터트려 박 속에 들어있던 편지지들을 볼 것이다2. 뒤로 돌아간다 아마도 위 두 가지 정도로 유저의 다음 행동을 예상할 수 있을 것입니다. 만약 네트워크 환경..

이번에는 리액트 프로젝트에서 내가 진행했던 번들 사이즈 최적화에 대해 이야기 해보려 합니다. 그렇다면 왜 나는 번들 사이즈를 최적화하려 했을까?우선, 우리 서비스를 프로덕션 레벨에서의 성능을 확인해보기 위해 build를 해보았습니다. 위 스크린샷을 보면 root 밑의 assets/index-UgkYlaLr.js 하나의 파일로 번들 파일 전체를 차지하고 있는 것을 볼 수 있고, 밑에 스크린샷의 로그에서는 index-UgkYlaLr.js의 크기가 704.19KB인걸로 매우 크다는 걸 알 수 있죠. 로그에 나와있는 경고에도 500KB가 넘는다고 알려주며 코드 스플리팅을 해서 사이즈를 줄이라고 권장하고 있습니다.코드 스플리팅이란 무엇인가?코드 스플리팅은 말그대로 한국어로 번역하면 코드 분할입니다. 우리가 코드 ..

이전에 진행했던 프로젝트에서 이미지 확장자로 .png를 사용했었다. 하지만 png는 jpeg, webp에 비하면 용량이 훨씬크다.이렇게 되면 이미지를 렌더링 하는 데 있어서도 시간이 오래걸리고 이는 유저의 페이지 이탈을 야기 할 수 있다. 우선 png가 왜 타 확장자에 비해 용량이 큰지 알아보기 위해 올리브영 기술 블로그를 참고하여 레스터 이미지와 벡터 이미지에 대해 알아보자.✅ 레스터 이미지래스터 이미지는 픽셀에 표현하고자 하는 색상을 그려서 이미지 형태로 표현하는 방식이다. 개발자들이 주로 사용하는 JPEG, PNG, GIF 등이 대표적인 레스터 이미지이다. 이 레스터 이미지는 여러 픽셀이 모여서 하나의 이미지를 만들기 때문에, 사이즈가 크거나 품질이 더 좋은 이미지를 만들기 위해서는 그만큼의 정보를..

해당 성능 최적화 포스팅은 여러 주제로 나누어 시리즈로 작성 할 계획이다.이전에 진행했던 프로젝트에서 시간이 급급한 나머지 놓쳤던 성능 최적화 부분에 대해 리팩토링을 해 보았다.우선 유저에게 가장 먼저 보여지는 화면을 개발하는 프론트엔드 개발자는 유저에게 제공하려는 웹 사이트를 빠르게 보여줘야하고, 사용자의 동작에 따른 빠른 인터랙션을 제공해야한다. 즉, 좋은 사용자 경험(UX)을 제공 해야하는 것이다. 아래는 구굴이 공개한 시간대별 페이지 이탈률로 페이지 로딩 시간이 1초에서 3초로 증가하면 페이지 이탈률이 32%로 증가한다고 하고, 1초에서 10초가 되면 페이지 이탈률이 123%나 된다고한다. 프론트엔드 성능 최적화에는 성능 최적화 외에도 접근성, SEO 등 다양한 부분이 있지만 우선 성능 최적화에..

JavaScript를 사용하는 개발자라면 개발을 하면서 디버깅을 하기 위해 console.log()를 많이 사용 할 것이다. 협업을 하는 과정에서 디버깅을 위해 작성했던 console.log()를 코드리뷰를 통해 발견하여 제거 할 수도 있지만, 이 또한 사람이 하는 일이라 못 보고 지나쳐 console 로직이 그대로 main에 push되어 배포 사이트에서 console이 찍히는 일이 조금씩은 있을 것이다. 지금부터 배포 단계에서 자동으로 console이 제거되어 개발자들이 마음 놓고 console을 찍어 디버깅 해볼 수 있도록 설정해보자! 하지만 이 설정은 동료 개발자들의 human error를 줄여주기 위한 수단 일 뿐, console이 main 브랜치에 남아있으면 보기 좋지 않으니 무조건 consol..

이 글은 내가 프로그래머스 FE 데브코스 과정속에서 2번의 팀장 맡으며 느꼈던 회고 글이다. 나는 외향적인 사람이다. 다양한 사람을 만나는 것을 좋아하고 그 사람들과 만나 다양한 이야기를 하며 그 사람들을 알아가는 것이 즐겁다.이러한 것이 즐거운 이유는 그 사람을 알아가는 것도 즐겁지만 그 사람과 대화하다보면 내가 겪어보지 못했던, 내가 알지 못했던 부분에 대해 자연스레 알고, 배울 수 있다.(일단 정적을 참지 못하는 성격이 한 몫 하기도 한다 ㅋㅋ) 나는 이러한 성격을 바탕으로 주로 학창시절 팀 과제가 있다면 팀장을 맡은 적이 많다. 다른 사람이 팀장을 하고 싶어 할 수도 있으니, 내가 하겠다고 먼저 나서지는 않지만 주로 결과적으로 보면 이미 나는 팀장이 되어있다 ㅋㅋㅋㅋㅋㅋ 숙연해진 분위기가 느껴지면..

최근 진행했던 짤을 공유하고 자유롭게 사용할 수 있는 "짤뮤니티" 프로젝트에서 맡았던 OAuth 2.0 로그인 기능에 대해 작성해보려 한다. 우선 나는 잘 모르는 서비스에서 회원 가입을 요구할 때, 대부분 거부감이 들었었다. 내 개인 정보를 잘 모르는 서비스에 제공해야 한다는 것이 썩 내키지 않았기 때문. 그렇다면 다른 사용자들도 나처럼 거부감이 들지는 않을까? 또 회원가입을 해야 하는 프로세스 자체가 귀찮지는 않을까?라는 고민에서 시작되어 자체 회원가입 및 로그인 없이 Oauth 2.0 서비스를 사용하기로 결정하였고, 구글, 카카오, 네이버 총 3개의 서비스를 이용하여 로그인을 진행했다. 우선 OAuth의 프로세스를 알아보기 전, OAuth에서 쓰이는 구성 요소 용어에 대해 알아보자.OAuth 구성 요..

클로저란?클로저란 함수가 선언된 환경의 스코프를 기억하여 함수가 스코프 밖에서 실행될 때에도 기억한 스코프에 접근할 수 있게 만드는 문법이다.음... 텍스트로는 이해가 어려우니 직관적인 코드로 살펴보자!function a(name) { const greet = 'hello, '; // 지역 스코프라 함수가 종료되면 메모리에서 사라짐. return function () { console.log(greet + name); };};const world = a("world");const ik = a("ik");world(); // hello, worldik(); // hello, ik 현재 전역 Lexical 환경에는 현재 각각 `a()`과 `world()`, `ik()`이 들어있다..

기존에 진행했던 SNS 플랫폼 기반 익명/기명 편지 서비스 "대박 사건" 프로젝트에서 각 페이지에 따로 구현되어 존재했던 편지 작성, 이전에 작성한 편지 수정, 댓글 작성 컴포넌트(모두 Textarea로 이루어짐)를 공통 컴포넌트로 묶어 재사용성을 높여보았다. 위 구조로 완성된 UI와 문제점에 대해 간단하게 알아보자. 위 사진의 주황색으로 표시된 컴포넌트 모두가 비슷한 UI를 가지고 있고 우측의 이전 편지 수정하는 컴포넌트만 버튼 아이콘 두 개가 추가되어있다. 위 UI를 바탕으로 현재 코드의 문제점은 코드의 중복. 이를 해결하기 위해 Textarea를 하나의 고정된 UI를 가지고 있는 공통 컴포넌트로 구현하려 고민했었고, 당시 생각했던 구조는 아래와 같다. 하지만 위와 같은 설계는 치명적인 단점이 존재했..