프론트엔드 개발자들

프론트엔드 개발자들

프론트엔드 개발자들을 위한 커뮤니티 클럽입니다.

공개 178 멤버

가이드라인

["개인 또는 단체, 속한 조직을 비방하는 글을 '금지'합니다.","타인의 글을 공유할 땐 왜 공유하려고 하는지 이유도 함께 적어주면 좋습니다.","\b작성한 글을 공유할 땐 어떤 내용인지 간단하게 요약해주면 좋습니다.","기술 관련 질문을 올릴 땐 '문제 상황', '시도한 방법' 등을 적어서 답변하는 분에게 충분한 정보를 제공해줍니다.","조직 문화 등 비기술 관련 질문을 올릴 땐 정확히 어떤 내용이 궁금한지 '명확'하게 '요약'되어 있으면 좋습니다."]

유서경 Quartz

유서경 Quartz

개발 1년차, 이력서 없이 커피챗으로 이직하기 - 2024년 상반기 회고

안녕하세요. 다들 2024년을 잘 보내고 계신가요? 저에게 2024년은 제 인생에서 가장 다이나믹하고 학습한 것이 많은 한 해입니다. 새로운 커리어를 도전해보고 싶지만 나를 평가하고 증명해야 하는 취업 시장에 나가기는 쉽지 않은데요, 이번 글에서는 제가 올해 커피챗을 통해 좋은 기회들을 얻어 새로운 팀을 찾은 경험을 적어보려 합니다.

image.png

어떤 개발자가 되고 싶나요?

동료, 새로운 사람들과 커피챗을 하다보면 가장 많이 들었던 질문입니다. 작년에 이 질문을 들었다면 혼자서 하나의 서비스를 온전히 만들 수 있는 사람이었겠지만, 지금은 소프트웨어로 문제를 해결하고 그만큼의 가치를 인정받을 수 있는 사람인 것 같습니다.

저는 개발자를 평생 해야할 일이라고 생각하지 않습니다. 삶의 태도가 바뀐다면 언제든지 일하는 방식도 바꿀 수 있다고 생각합니다. 제가 작년 새로운 환경을 찾게 된 이유는 “내가 관심있는 도메인”의 문제를 해결하고 싶었기 때문입니다.

1인 개발 vs 새로운 회사

작년 말, 많은 고민 끝에 2024년을 노마드 개발자로 살기로 결심했습니다. 저에게 2023년은 개발자로 처음 취업하고, 혼자 만든 앱 사용자가 1600명이 넘고, 좋아하는 운동에서 2년만에 승급하기까지 하여 원하는 목표를 모두 이룬 한 해였습니다. 그럼에도 불구하고 성취감보다는 권태로움이 더 크게 느껴졌고, 이제는 나의 리소스를 온전히 한 곳(1인 개발 앱)에만 집중해보자는 결론을 내렸습니다.

image.png

그런데 예상치 못하게 2023년 회고글을 읽고 좋은 포지션을 제안해주시는 커피챗 요청이 계속 생겼습니다. 특히 초기 스타트업 단계에서 혼자서 문제를 정의하여 서비스를 만들고 운영한 저의 경험을 유니크하게 평가해주셨고, 감사하게도 하나의 글만으로도 저도 모르는 저의 강점을 파악해주시기도 하였습니다.

글로만 적어보면 행복한 고민이지만, 사실 이미 고심 끝에 1인 개발을 하기로 결정을 내린 상황이었기에 다시 불어난 선택지로 괴롭기도 했습니다. 그럼에도 개발자 커리어 목표 중 하나인 노마드를 잠시 미루고 다시 새로운 팀을 찾기로 마음먹은 이유는 같은 시간, 노력을 투자해도 더 큰 결과물을 도출할 수 있는 좋은 기회가 많아보였기 때문입니다.

커피챗

지금까지의 저의 구직 경험을 되돌아보면, 나의 능력을 회사에 증명하기 위한 대답을 많이 했던 것 같습니다. 포지션의 합격 여부를 회사에서 결정짓다보니 당연한 수순일 수 있지만, 이번 이직 활동에서는 저도 회사의 핏을 확인하기 위해 많은 질문들을 했습니다.

  • 어떤 문제를 해결하기 위해 프로덕트를 만들고 있는지?

  • 요즘 어떤 문제를 겪고 있는지?

  • 이 포지션에 내가 합류했을 때 무엇을 기대하는지?

2024년 상반기 회고

결론적으로, 저는 지난 4월부터 디스콰이엇에 합류하여 재미있게 일하고 있습니다. 지난 세 달 동안 개인적으로도 많은 일이 있었는데요, 생각보다 더 많이 성장하고 배운 것 같아 뿌듯하기도 하고 힘들기도(ㅋㅋ) 합니다. No pain, no gain…. 😎

새로 알게 된 것

  • 팀으로 일하는 법

    가끔 “내가 혼자 결정하고 실행하는 것이 빠르지 않을까?”라는 생각이 들 때가 있습니다. 특히 저는 1인 개발을 할 때가 많으니 의사 결정이 느리다고 생각하는 경우가 많았던 것 같습니다. 올해 새로 알게 된 것 중 저에게 가장 큰 변화를 가져온 것은 팀원들에게 신뢰를 얻고, 나도 팀원들을 신뢰하여 서로의 역할을 잘 구분하고 위임하는 것입니다.

  • 모든 것은 학습이다.

    올해 3월, 2주간 치앙마이로 노마드 여행을 다녀왔습니다. 새로운 나라, 문화권을 여행하며 친구를 사귀는 것, 새로운 팀을 만나고 팀원들과 문화를 만드는 것 그리고 새로운 코드 베이스에서 기술을 익히는 것 모두 학습이라고 생각합니다. 영어를 잘하는 것, 외향적으로 사람들과 이야기하는 것, 좋은 코드를 짜는 것보다 어쩌면 다양한 것을 학습하려는 자세가 더 중요하다는 생각이 들었습니다.

더 알고 싶은 것

  • 소프트웨어의 가치 인정받기

    어느 순간 코드를 짜서 소프트웨어를 만드는 것이 매일 소비하는 커피를 만드는 것보다 고도화 된 것이라 생각하고 있었습니다. 그러나 모두가 보편적으로 좋아하고 가치를 인정받는 커피와 같은 프로덕트를 생산해내기는 쉽지 않은 일입니다. 디스콰이엇을 통해 좋은 제품들이 많아지고 더 많은 가치를 만들어낼 수 있으면 좋겠습니다.

마무리하며

긴 글 읽어주셔서 감사합니다. 새로운 팀을 찾거나 빌딩하는 일은 모두가 한 번 쯤은 겪는 어려움인 것 같습니다. 제가 디스콰이엇에 합류하고 처음으로 개발한 메이커 찾기가 드디어 배포되었는데요, 비슷한 어려움을 겪고 있는 분들께 도움이 되었으면 좋겠습니다.

p.s. 아래 첨부 사진과 다른 화면이 나타난다면 여러분은 다른 테스트에 걸리신 겁니다.. ㅎㅎ

image.png

18
14
준프

준프

타입스크립트에서 Type vs Interface

타입스크립트를 활용해 개발하실 때 타입과 인터페이스를 언제 사용하시나요?

관련된 글은 정말 많지만 어딘가 모르게 비어있는 듯한 느낌을 받는 건 이 글들이 기술적 차이를 주로 다루고 사용자에게 선택지를 주기 때문이라고 생각합니다. 즉, "타입과 인터페이스는 서로 비슷한 기능을 하지만 대부분 사용하는 데 큰 차이를 못 느낄거야. 그러니까 선호하는 걸 사용해."라고 말하는 듯 합니다. 결국 왜 타입을 선택했고 왜 인터페이스를 선택했는지 그 이유는 다시 스스로 만들어내야 합니다.

이번에 소개해드리는 글의 결론은 다른 글들과 비슷하지만 인터페이스와 타입 어노테이션에 대해 미묘한 공통점, 차이점을 드러내고 있습니다.

In TypeScript, think of an interface as a set of rules or requirements that an object must follow. It’s like a contract that says, “Hey, if you want to be a ‘Client,’ you must have a ‘name’ and an ‘address.’”

그리고 개발자가 OOP에 친숙하다면 인터페이스를 함수형 프로그래밍에 친숙하다면 타입을 사용하는게 아닐까? 하는 생각이 들게 만드는 문장도 있습니다.

Interfaces are also more readable when you’re thinking in terms of object-oriented programming.

In addition, many developers prefer using types because they align well with the functional programming paradigm.

길지 않지만 타입과 인터페이스 사이에서 방황하고 있다면 도움이 되지 않을까 합니다.

2
1
준프

준프

리액트 상호작용 시간을 4배 개선하기

이번에 소개해드리는 글은 리액트 상호작용 시간을 개선하는 경험을 공유하는 글입니다.

글쓴이는 겉으로 보기엔 단순해보이는 성능 이슈를 해결하기 위해 어떤 과정을 거쳤는지 정말 자세하게 공유하고 있습니다.

이 글을 통해 제가 얻은 인사이트는 이렇습니다.

  • 보통 리액트 성능 이슈가 있다면 이렇게 깊게 먼저 들어가지 않는 편입니다. 간단하게 해결할 수 있는 방법은 없는지 알아보는 시간을 갖습니다. 하지만 글쓴이는 성능 이슈가 발생했을 때 프로파일링을 먼저합니다. 프로파일링은 쉬운 과정은 아닙니다. 어떤 함수가 성능 문제를 일으키는지 다소 깊게 파악해야 합니다. 그리고 이 경우 리액트에 대해 잘 알고 있어야 합니다. 예를 들어, performSyncWorkOnRoot가 리액트 렌더링 과정에서 호출되는 함수라는 걸 알아야 합니다.

  • 또한 자신의 리액트 코드 뿐만 아니라 AG Grid라는 외부 라이브러리의 코드도 함께 살펴봅니다. 보통 외부 라이브러리에서 문제가 발생하면 파헤쳐보기 전에 우회하여 해결 할 수 있는 방법을 탐색합니다.

  • 원인을 파악하기 위해 다양한 도구를 사용합니다. 크롬 개발자도구와 리액트 프로파일링 도구를 합리적인 이유를 갖고 적절한 때에 사용합니다. (이유도 함께 적어놨습니다.)

  • 이 모든 과정에서 상당한 양의 '지식'이 사용됩니다.

한 가지 문제를 풀기 위해 이렇게 오랜 시간을 사용할 수 있는 건 '확신'이 필요하다고 생각합니다. 다른 방법보다 이 방법이 문제를 해결하는 데 더 확실한 방법이고, 해결할 수 있는 더 좋은 방법이라는 확신이 있어야 중간에 의구심을 품지 않고 끝까지 해낼 수 있습니다. 그리고 그 확신은 명확한 계획에서 나옵니다.

He was convinced before that the formula is correct because he derived it carefully. But now he is more convinced, and his gain in confidence comes from a different source; it is due to a sort of "experimental evidence."

<HOW TO SOLVE IT>

그리고 이렇게 해낼 수 있는 다른 이유 중 하나는 계획을 실행하기에 필요한 지식과 경험입니다. 이 글을 읽어보면 상당한 양의 지식과 경험을 볼 수 있습니다.

Good ideas are based on past experience and formerly acquired knowledge.

<HOW TO SOLVE IT>

이 글을 통해 문제를 어떻게 해결해야 하는지 한 번 더 생각해보게 되는 계기가 됐습니다. 또한 내가 다루고 있는 도구나 방법론에 대해 얼마나 알고 있고 경험했는지, 그 경험은 어떤 종류인지 돌아보게 됐습니다.

최근 시청한 영상을 추가로 남깁니다.

그 사이의 균형을 잘 유지해야죠. 예술가인 동시에 과학자가 되어야 합니다. 이미 정해진 레시피를 무시하고 모든 걸 처음부터 '이해'하려고 한다면, 아무것도 만들지 못할 겁니다. 하지만 본질을 '이해'하지 않고 아무 생각 없이 레시피만 따라 한다면, 잘못된 제품을 만들 겁니다.

그렇게 복잡하게 생각할 필요 없습니다. 컴퓨터를 새로 만든다고 해보죠. 만약 여러분에게 일을 맡긴 의뢰인이 컴퓨터 성능을 10% 높이고 싶다고 한다면, 메모리 용량을 늘리거나 부품을 추가하겠죠. 아니면 컴퓨터의 설정을 만져서 성능 효율을 최대치로 끌어올릴 겁니다. 하지만 부품을 추가하고 설정을 바꿀 수록, 구조도 복잡해지고 관리도 어렵죠. 언젠간 벽에 부딪힐 겁니다. 아무리 부품을 덕지덕지 붙여도 성능이 더 좋아지지 않는 시점이 오겠죠. 그러면 대부분 사람들은 이렇게 말해요. "어쩔 수 없어요. 이게 한계입니다." 하지만 극소수는 이렇게 얘기하죠. "지금의 구조는 더 이상 한계야. 뭘 새롭게 추가한다고 바뀔 건 없어. 새로운 구조를 처음부터 다시 짜보자." 그렇게 기존 구조를 뜯어보고 난 후에 사람들은 비로소 알게 됩니다. 아예 처음부터 새로운 구조를 만드는 것이 훨씬 빠르고 간단한 방법이에요.

이 글의 목차는 아래와 같습니다.

  • 상호작용 프로파일링

  • AG Grid: 불필요한 렌더링 고치기

  • AG Grid: 렌더링 제거하기

  • useEffect 덜 실행하기

    • areEqual의 깊은 이야기

  • 여전히 남아 있는 작업

    • 더욱 세분화된 업데이트

    • useSelector vs useStore

  • 잘 동작하지 않은 것

  • 결과

0
2
유서경 Quartz

유서경 Quartz

1년 묵힌 기술 부채 해결기 (feat. TanStack Query)

image.png

안녕하세요. 주짓수 앱을 만들고 있는 유서경입니다. 출시한 지 1년 2개월된 앱에 1년 된 기술 부채가 있다면 믿으실 건가요? 놀랍게도 제게 벌어진 일입니다. 드디어 지난주! 이 기술 부채를 해결한 따끈따끈한 이야기를 공유해보려 글을 작성합니다. 제가 이 앱을 운영하며 가장 속이 뻥 뚫리고 그래도 내가 개발자로서 성장했구나를 느낀 시점이었습니다. 이 글은 아래와 같은 분들이 읽기 좋습니다.

  • Expo managed workflow 환경에서 Firebase를 사용하는 분

  • TanStack Query 도입기가 궁금한 프론트엔드 개발자 분

  • 기술 부채를 도대체 왜 1년이나 묵히고 있었는지 궁금한 분

  • 1년 동안 서비스의 성장을 가로막았던 기술 부채가 궁금하신 분

  • 1년 동안 기술 부채로 불안에 떨었던 인디 메이커의 머릿속이 궁금한 분

직접적인 코드보다는 문제를 해결한 과정을 소개할 예정이니 가벼운 마음으로 재미있게 읽어주세요.

기술 부채 소개

Post Black Belt는 제가 혼자 기획, 개발 그리고 운영까지 하고 있는 인디 앱입니다. 타 서비스도 마찬가지이겠지만 1인 개발에서 가장 부족한 리소스는 시간입니다. 저의 경우 회사 일과 병행하며 주말이나 여가 시간을 활용했기 때문에 특히 복잡한 이슈를 깊게 생각해볼 시간을 마련하기 힘들었습니다.

기술 부채가 왜 발생했나요?

이 앱은 제가 프론트엔드와 백엔드를 구분하지도 못했던 시절 만든 저의 첫 서비스입니다. 따라서 대부분의 개발 환경, 구조 세팅이 미숙합니다. 처음 이 프로젝트의 목표는 "취업 준비"였기 때문에 기능을 구현하는 것을 우선으로 하고 기술 스택 선정이나 운영은 고려하지 않았습니다. (저 혼자 사용하려 했었습니다 😶)

게다가 제가 프론트엔드 개발자이다보니 (BaaS 임에도 불구하고) 데이터베이스 사용과 관리에 매우 취약했습니다. Post Black Belt는 상당히 독특하게 local DB와 Firestore DB를 모두 사용하고 있는데, 그 이유는 1년 전 땜빵식 해결 방법을 채택했기 때문입니다. 😱

어떤 기술 부채였나요?

처음에는 사용자의 일기를 local SQLite DB에 저장하고 있었고, 앱을 삭제하거나 캐시를 지우게 되면 데이터가 유실되는 이슈가 있었습니다. 사용자가 점점 많아짐에 따라 해당 문제가 크리티컬하게 작용할 것이라 생각하였고 local DB에 일기를 저장하는 동시에 Firestore에도 함께 저장하여 일기를 백업해두도록 하였습니다. 아래 그림을 보면 일기를 생성하고, 수정하고 지우는 로직을 local DB와 Firestore에 함께 수행하고 일기를 읽는 로직은 local DB에서 가져오는 것을 확인할 수 있습니다. local DB를 Firestore로 완전히 대체하지 않은 이유는 SQL DB를 NoSQL DB로 변환하는 데에 꽤 많은 리소스가 필요하고, Firestore의 Read 쿼리가 많이 나와 비용을 지불하고 싶지 않았기 때문입니다.

image.png

그러나 여전히 3가지 큰 문제점이 남아있었습니다.

  1. local DB가 여전히 Source of Truth로 작용한다.

    이제 사용자가 앱을 삭제해도 데이터가 사라지지는 않습니다. 그러나 여전히 일기의 원본은 사용자 기기 내에 있고, 실제로 Firebase 로그인 핸들링이 제대로 되지 않아 만료되는 이슈가 있었을 때 사용자 기기 내에서만 일기가 저장되는 부차적 이슈가 있었습니다.

  2. Firestore에서 제공하는 자체 캐싱을 사용하지 못하여 Read 쿼리가 많이 발생한다.

    Post Black Belt는 Expo 환경으로 개발되었습니다. 제가 처음 앱을 구축했을 때는 Firebase의 React Native용 패키지를 활용하기에 Expo managed 환경의 제약과 버그가 있어 Firebase JS SDK를 선택하였습니다. 그리고 이 경우 지속성 캐시를 활용할 수 없다는 것을 나중에 확인하게 되었습니다....

    image.png

  3. SQL과 NoSQL이 혼용되어 개발 경험이 매우 좋지 않음

    많이들 아시다시피 Firestore는 NoSQL DB입니다. 따라서 local에서는 SQL로 저장해서 쿼리하고 백업은 NoSQL로 구성한다는 것이 개발자로서 꽤나 불편한 경험이었습니다.

왜 기술 부채를 해결하지 않았나요?

위의 문제가 있음에도 제가 이 기술 부채를 해결하지 않았던 이유가 있습니다. (이 글의 제목이 "묵은"이 아니라 "묵힌"인 이유는 의도적으로 해결하지 않았기 때문입니다.)

제가 갖고 있던 가장 합리적인 해결 방법은 local DB를 없애고 Firestore를 Source of Truth로 사용하는 것입니다. 그러나 이 경우 사용자가 많아질수록 Read 쿼리 비용 함께 증가하기 때문에 고려하고 싶지 않았습니다. 사이드 프로젝트는 이미 제 시간이라는 거대한 리소스를 투자하고 있는데 그 이상을 사용하면서 스트레스를 받고 싶지 않았기 때문입니다. 당시에는 사용자보다는 저의 개발 프로젝트라는 인식이 강했기 때문에 정기적인 비용이 지불되면 지속하기 어렵다고 판단하였습니다. (지금은 사용자를 위해 만들고 있습니다. 😇)

왜 1년 만에 기술 부채 해결을 결정했나요?

그럼에도 불구하고 이 기술 부채를 해결하기로 결정한 이유는 두 가지입니다. 첫 번째는 지난 1년 동안 불안함과 찝찝함으로 저를 너무나 괴롭혔기 때문입니다. 더이상 관련 CS가 들어올까 걱정에 떨며 살고 싶지 않았습니다🫠. 두 번째는 이 문제가 서비스의 성장을 막고 있다면 우선순위가 높은 기술 부채이다라는 동료 개발자의 조언 때문이었습니다. 실제로 신규 기능을 기획할 때 이 기술 부채가 꽤 큰 걸림돌이 되고 있었습니다. 아마 제가 느끼기에 너무 거대한 문제여서 부채를 못본 척 하며 미뤘을 수도 있습니다.

여러분은 이런 상황에서 어떤 결정을 하시나요? 정말 하기 싫지만 문제를 해결해야 할 때, 정말 해결할 사람이 나 하나일 때, 이 경우에는 내가 이 프로덕트의 CTO라고 생각하고 막중한 책임감을 부여하면 됩니다. 이게 인디 메이커의 장점이자 단점이랄까요.. ㅎㅎ 믿고 의지할 곳은 나뿐입니다...

기술 부채 해결을 위한 옵션들

처음 기술 부채를 발견했을 때보다 1년이라는 시간이 지났으니, 이제 더 많은 옵션을 고려할 수 있습니다. 다시 정리하자면 아래 문제들을 해결해야 합니다.

(1) local DB를 삭제하고 서버의 DB를 Source of Truth로 사용

(2) Read Query 비용 문제 해결

(3) SQL, NoSQL 중 한 가지만 사용

Supabase로 마이그레이션 해보자

최근 BaaS에서 Firebase의 대안으로 RDB인 Supabase의 인기가 급부상하고 있습니다. 실제로 Supabase에서도 Firebase로부터의 마이그레이션을 잘 지원하고 있으며, 비용도 쿼리 당이 아닌 용량으로 계산되어 (1)부터 (3)의 문제를 모두 해결할 수 있습니다. 이왕 부채를 해결하는 김에 개발 경험이 좋았던 Supabase로 아예 넘어가버리자!라는 원대한 계획을 만들었지만 두 가지 이슈가 있었습니다.

  • Firebase Auth를 함께 이전하려면 로그인 상태 유지를 위해 서버를 띄워야 하고, 월간 5달러의 비용이 발생함: (2)보다 많은 비용 발생

  • Firebase를 Supabase로 먼저 대체한 후 (1)을 해결해야 하여 한 번에 너무 많은 문제들을 다뤄야 함: 문제 해결 범위가 너무 방대해짐

Firebase를 JS SDK에서 react-native-firebase로 마이그레이션 해보자

그러면 (2)의 문제를 해결하기 위해 패키지를 변경하는 것은 어떨까요? 이미 서비스 내에서 Firebase를 사용하고 있으므로 상당히 간단해보이며, 추가로 JS SDK를 React Native에 사용하여 제한되었던 Firebase의 타 서비스(GA4, Remote Config 등)을 활용할 수 있게 됩니다. 그러나...

  • 여기도 마찬가지로 Auth 변경으로 로그인이 풀리는 문제가 있습니다. 이 경우 서버를 새로 구성하거나 최악의 경우 모든 사용자에게 재로그인을 받아야 합니다.

  • 큰 문제는 아니지만 JS SDK 코드를 react-native-firebase 인터페이스에 맞게 모두 수정해야 합니다.

서버 상태 관리 툴인 TanStack Query를 도입하자

여기까지 오는데 제 설 연휴와 주말을 모두 써버렸습니다.. 하하.. 하지만 CTO가 여기에서 무너지면 안됩니다.. 이제는 프론트엔드 개발자 베이스다운 해결 방법을 사용해보려 합니다. 서버 상태 관리 툴을 도입하여 직접 캐시를 관리하는 것입니다.

이 방법의 장점은

  • 내가 직접 캐시를 관리하여 비용을 조절할 수 있다.

  • 현재 환경에 TanStack Query Layer만 추가하면 된다.

단점은

  • 처음 사용해보는 라이브러리로 적응 기간이 필요하다.

    • 이미 회사에서 Apollo Client를 사용해보았기 때문에 완전히 어색하지는 않을 것이다.

  • 사용자가 많아질 경우 (2)의 문제가 다시 발생할 수 있다.

    • 아직 발생하지 않은 문제를 먼저 고민할 필요없다. 비용이 많이 발생하면 사용자들이 많아지는 서비스에 기뻐하며 그때의 문제를 또 다시 해결하면 된다.

TanStack Query 간단 사용기

TanStack Query는 FE에서는 상당히 인기가 많은 도구이고, 2023년 React Native 설문조사에서도 Data Fetching 도구로 1위를 수성할만큼 커뮤니티도 개발자 만족도도 좋은 편입니다.

image.png

인디 메이커는 대부분의 문제를 혼자(요즘은 GPT 선생님과 함께지만) 해결해야하기 때문에 좋은 커뮤니티를 갖춘 라이브러리는 중요합니다. 저는 공식 문서도 읽기는 했지만 maintainer의 best practice와 실용적인 팁이 담겨있는 TkDodo's Blog에서 많은 도움을 받았습니다. 해당 블로그 내용은 v5 이전의 내용이어서 deprecated된 부분도 있지만 활용 방법만 잘 숙지하면 v5에도 충분히 적용 가능합니다.

또한 React Native 앱을 사용하는 경우 캐시를 AsyncStorage에 저장하여 앱이 종료되었다 다시 켜져도 캐싱을 유지하게 할 수 있습니다. 제가 Firebase JS SDK의 사용하지 못한 이유는 AsyncStorage가 아니라 indexedDB를 활용하기 때문입니다.

간단한 캐싱 예시를 보여드리자면,

Mar-12-2024 12-00-05.gif

위에서는 처음 12월의 일기를 불러올 때 서버에 요청하여(로딩 인디케이터) 데이터를 가져오지만,

Mar-12-2024 12-00-10.gif

12월의 데이터를 재요청할 때는 서버 요청없이(로딩 없음) 캐시에서 바로 데이터를 가져오는 모습을 확인할 수 있습니다.

이 캐시는 사용자가 앱을 종료하였다가 다시 켜도 유지됩니다. 캐시의 상태는 사용자가 CUD를 발생시키면 fresh > stale로 변경되어 서버에 재요청을 발생시키도록 하였습니다. 캐시 상태 관리도 상당히 중요한데요, Post Black Belt는 아직 사용자 개인 일기장으로만 활용되고 있으므로 비용 최소화를 우선적으로 고려하였습니다. 서비스가 성장하여 네트워킹 기능이 생기면 캐싱 정책도 유연하게 변경될 예정입니다.

개인적으로 마음의 짐으로 생각하던 부채를 해결하여 기분이 좋은데요, 치앙마이로 디지털 노마드를 오기 전에 해결해두어 조금 더 가벼운 마음으로 일할 수 있게 되었습니다. 긴 글 읽어주셔서 감사합니다!

Post Black Belt

주짓수 수련자들을 위한 기술 기록 다이어리

1
5
준프

준프

Shift Left Testing이 어떻게 버그, 시간 그리고 돈을 아낄까?

이번에 소개해드리는 글은 Shift Left Testing이 무엇인지 소개하는 글입니다. 사실 그보다는 제품을 만드는 과정에 대해 거시적으로 살펴볼 수 있도록 합니다. 이 내용이 도움이 되었다면 함께 일하는 동료와 논의해보는 것도 정말 좋을 것 같습니다.

버그의 책임은 누구에게 있는가?

이 글은 가장 먼저 제품에서 발생한 버그의 책임은 어디 그리고 누구에게 있는지 간단하게 알아봅니다. 사실 이 문장에서 조금 뜨끔한 포인트가 있습니다. 제품을 개발하는 과정 마지막에 제품이 정상적으로 동작하고 기대한 동작을 하는지 검증하는 과정(QA)이 있다면 코드를 작성하면서 은연중에 아래와 같이 생각한다는 것입니다.

"마지막 검증 과정에서 중요한 버그는 발견되고 이후 수정 기간에 수정하겠지"

하지만 이렇게 했을 때 결과는 그리 유쾌하지 않습니다. 아래는 검증 과정에 강하게 의존하면 발생하는 문제에 대한 제 생각입니다.

  1. 신뢰가 떨어집니다. 이러한 태도는 좋지 않은 질을 가진 코드를 생산해냅니다. 그리고 마지막 검증 단계에서 발견되는 버그의 갯수가 감소하지 않습니다. 결국 다른 구성원이 개발자를 신뢰하지 못하는 문제가 발생합니다.

  2. 시간과 돈이 많이 듭니다 1. 신뢰가 낮다면 비용은 증가합니다. 개발자가 만든 코드에 대한 신뢰가 낮기 때문에 검증 시간과 인력이 많이 듭니다.

  3. 시간과 돈이 많이 듭니다 2. 배포 하기 전 마지막 단계에서 하는 검증이기 때문에 이 때 발견된 버그는 수정할 시간이 부족하고 급하게 처리하다보면 또 다른 버그를 만들어내기 마련입니다. 만약 버그를 고치지 못했다면 제때 배포하지 못하고 다음 스프린트로 넘어갑니다.

그리고 이 글에선 아래와 같이 강조합니다.

The quality of the code is a shared responsibility among the entire team.

좋은 결과물에 대한 책임은 마지막 검증 단계, 개발자 등 특정 단계나 팀의 책임이 아닙니다. 각자가 자신의 책임이라 생각하는 태도가 중요합니다.

Shift Left Testing이란?

따라서 마지막 단계에 의존하는 검증이 아니라 개발 과정의 왼편(Left)으로 검증(Test) 과정을 이동(Shift)시킴으로써 더 나은 방법의 검증을 해야 한다고 강조합니다.

Shift Left Testing에 대해 저자는 아래와 같이 소개합니다.

Shift left testing means focusing on testing from the very beginning when we start thinking about how to approach a task.

이 방법의 자세한 수행 방법을 요약하면 아래와 같습니다.

  1. 자세한 인수 조건(acceptance criteria)

  2. 관계된 모든 구성원이 인수 조건을 파악함

  3. 개발자는 마지막 검증 단계 전에 반드시 테스트를 해야함

  4. 개발 과정에서 PM과 검증 팀으로부터 지속적인 피드백

이 방법은 실제로 업무를 하며 개선해나가는 과정과 닮아 있어 더욱 공감이 됐습니다. 이 방법을 처음 도입하거나 도입하는 중이지만 잘 안 된다면 아래 세부 내용을 살펴보는 게 도움이 되리라 생각합니다. 이 내용은 제가 추가한 내용입니다.

  1. PM 또는 모든 괸계자는 자세한 인수 조건을 준비하고, 개발자는 인수 조건에 따라 개발해야 합니다. 이 글에서 소개한 것처럼 준비하는 것만으론 충분하지 않습니다. 때로 이 과정은 매우 번거롭고 힘듭니다. 저 처럼 덤벙대는 성격을 가진 사람이라면 더욱 그렇습니다. 하지만 훈련해야 합니다.

  2. 인수 조건이 자세하게 준비되어야 하는 이유는 버그는 코드로부터 나오는 것 뿐만 아니라 애초에 잘못된 인수조건에서 나올 수 있기 때문입니다. (이 글에서도 이 부분을 강조하고 있습니다.)

  3. 보통 전문 QA 팀이 있지 않은 조직에선 모든 관계자가 함께 검증을 합니다. 그렇기 때문에 더욱더 인수 조건을 모두 파악하고 있어야 합니다. 그래야 발견하지 못한 문제 케이스를 발견할 수 있습니다.

  4. 개발자는 마지막 검증 단계 전 반드시 테스트를 해봐야 합니다. 여기엔 단위 테스트, 개발자 간의 테스트 등을 포함합니다. 이 방법은 마지막 검증보다 비용이 낮고 속도가 빠릅니다.

  5. 시작부터 마지막 단계까지 지속적으로 피드백을 주고받아야 합니다. 왜냐하면 우리 모두 사람이기 때문에 각 과정에서 문제를 발견할 수 있기 때문입니다.

  6. 지속적인 피드백과 개선이 필요하려면 변경에 유연한 코드를 작성해야 합니다. (이 역시 소개한 글에서 강조하고 있습니다.)

더 자세한 내용은 소개해드리는 글을 참고해보시는 걸 권해드립니다. 위 내용을 더 자세하게 설명하는 것 뿐만 아니라 실제 적용 결과를 공유하고 있기도 합니다.

뿐만 아니라 테스트와 관련해 이전에 공유해드린 '테스트는 센서다'라는 글을 다시 공유드립니다.

0
0
준프

준프

15가지 유용한 HTML 속성

이번엔 간단하고 가볍지만 정말 좋은 정보를 담고 있는 아티클을 소개하려고 합니다. HTML 속성하면 접근성과 관련이 있거나 잘 쓰지 않는 속성을 소개하는 경우가 있는데요, 이 글에선 '이런 속성도 있었어?'하는 부분이 종종 있습니다.

이 글에서 소개하는 속성을 나열해보면 아래와 같습니다. 자세한 내용은 글을 참고해주세요 :)

그리고 사용해보기 전 caniuse에서 사용 가능한지 확인해보는 습관도 중요합니다 !

  • contenteditable

  • spellcheck

  • translate

  • multiple

  • reversed

  • draggable

  • accesskey

  • poster

  • onerror

  • theme-color

  • favicon

  • touch-icon

  • loading

  • async

  • defer

0
0
준프

준프

모던 프론트엔드 아키텍처를 위한 5가지

이 글의 제목은 스팸처럼 느껴지지만 내용은 그렇지 않았습니다. 각 주제를 간단하게 나열하고 있지만 분명 인사이트를 주는 내용들이 많았습니다. 각 주제가 어떤 내용을 설명하고 있는지, 어떤 인사이트가 있는지 목차와 함께 살펴보겠습니다.

  • 디자인 시스템

  • 컴포넌트 재사용

    • 컴포넌트를 분리하고 디렉터리에 관리하는 방법에 대해 소개합니다. 이 글에서 가장 눈에 띄는 부분이었습니다. 최근 스타일 및 요소의 중복(DRY)에 대해 고민하고 있었는데 그 결과와 비슷하기도 해서 나름 뿌듯했습니다.

    • 우리는 중복을 제거하기 위해 컴포넌트를 분리하는데, 각 컴포넌트의 크기가 크기 때문에 사용처마다 다른 사용방법을 대응해줘야 하는 문제가 있습니다. 그래서 그런 가능성을 줄이기 위해 최대한 독립적인 부분들, 즉 작은 크기의 컴포넌트를 사용해야 합니다.

    • 다만, 이렇게 했을 때 문제도 있습니다. 컴포넌트 구조를 파악할 때 인지부하가 발생할 수 있고 아무리 작고 독립적인 컴포넌트로 세분화 한다고 하더라도 예상하지 못한 문제를 얼마든지 마주할 수 있기 때문입니다. 관련해서 또 다른 좋은 글을 소개합니다.

  • asset 최적화

    • 이미지, 자바스크립트, CSS, 폰트 및 아이콘, 비디오 및 오디오, 문서, 퍼포먼스 측정

    • 각 세부 내용은 자세한 내용을 다루고 있진 않습니다. 다만 어떤 자산에 대해 어떻게 최적화를 하면 좋은지 소개하고 자산의 종류에 어떤게 있는지 안내하는 것만으로도 큰 가치가 있습니다. 프론트엔드 사이드에서 최적화를 할 수 있는 범위가 어디까지인지 거시적으로 파악하는데 도움이 됩니다.

  • 각 수준의 캐싱

    • 브라우저, CDN, DNS, 애플리케이션 수준의 캐싱에 대해 소개합니다.

    • 이 역히 자산 최적화와 비슷합니다.

  • 낙관적 동시성

    • 낙관적 UI 업데이트에 대해 소개합니다. 또한 서버 요청으로부터 에러를 받았을 때 어떻게 재조정하는지 안내합니다.

    • 또한 문서 수정에 낙관적 UI를 적용하기 위해 프론트엔드에서 문서 버저닝을 하는 방법도 간단하게 소개합니다.

    • 낙관적 동시성과 관련해 이전 글을 다시 보는 것도 도움이 될거 같습니다.

0
0
준프

준프

자바스크립트 함수 활용, Higher Order Function

이번에 소개해드릴 글은 자바스크립트 함수를 활용하는 방법에 대한 글입니다. 그 중 함수를 감싸(wrap)는 방법은 정말 간단하면서도 활용가치가 높은 방법 중 하나입니다.

먼저 볼 글은 로직을 처리하는 도중 에러를 던지는 함수에 대한 이야기입니다. 몇몇 경우 에러가 아닌 null을 반환해야 하는데, 어떤 방식으로 할지 고민하는 과정을 담고 있습니다. 이 이야기가 좋았던 이유는 '지금 바로 떠오르는 답을 통해 어쨋든 원하는 결과를 만들어내면 그만'이라는 것에서 한 발 더 나아가 고민하고 더 나은 방법을 만들어내는 과정이 담겨있기 때문입니다. 어렵지 않은 글이기 때문에 결과도 좋지만 과정도 함께 보면 좋을 거 같습니다.

또한 댓글에 정말 좋은 내용이 담겨 있습니다.

  • 에러의 의미 전달의 중요성

  • try...catch의 비용

다음으로 볼 글은 Higher Order Function에 대한 글입니다. 다음과 같은 세 가지 HOF에 대해 소개하고 있습니다.

  • Functionality-wrapping

  • Functionality-altering

  • Functionality-creating

단어는 어려워보이지만 살펴보면 그리 어려운 내용이 아닙니다. 특히 함수의 실행 시간 측정 그리고 로깅을 위해 함수를 감싸는 방법은 위기의 순간에 사용하곤해서 알아두면 도움이 되리라 생각합니다. 그 밖의 내용 역시 유용하며 함수를 더 유연하게 바라볼 수 있는 경험을 제공합니다.

특히 이 글은 시리즈로 구성되어 있는데, 좋은 내용이 있는 거 같아 살펴보면 좋을 거 같습니다.

0
0
준프

준프

CSS Layers: 스타일링 작업의 게임 체인저

이번에 소개해드리는 글은 CSS의 Cascade Layers에 대한 글입니다. 이 글은 짧고 핵심을 짚습니다. 기존에 CSS 스타일 작업이 @layer를 통해 어떻게 바뀔 수 있는지, 어떤 흐름으로 작업하면 좋을지, 디버깅은 어떻게 하는지 간단하게 소개합니다.

스크린샷 2024-02-14 오후 10.08.43.png

목차를 요약하면 아래와 같습니다.

  1. 왜 css layers를 알아야 하는지?

  2. css layer를 정의하고 사용하기

    1. layer 생성

    2. layer 순서

    3. 중첩 layer

    4. CSS import와 함께 layer 사용

  3. css layer 디버깅

  4. 브라우저 지원 범위

대규모 프로젝트를 운영하다보면 스타일 우선순위 또는 덮어쓰기 등의 문제로 정말 많은 시간을 씁니다. 심지어 기존 요소에 적용한 스타일에 영향을 주지 않고 적절한 스타일을 적용하기 위해 요소를 뜯어 고치는 일도 많습니다. 이러한 문제는 아무리 CSS를 체계적으로 관리하고 사용하더라도 부딪히는 것 같습니다.

css layers를 사용하면 이런 문제가 발생할 가능성을 조금은 낮출 수 있을지 모르겠습니다. css 파일을 불러오는 순서나 !import가 아닌 layer를 적용하는 순서에 따라 스타일 '집합'을 적용하는 건 더 좋은 방법입니다.

이 짧은 글을 통해 css layer에 대해 알고, 당장 적용하지 못하더라도 더 나은 방법으로 스타일을 적용하는 방법에 대해 고민하는 계기가 되면 좋겠습니다.

0
0
준프

준프

일에서 경계를 정하세요

이번에 소개해드릴 글은 일과 삶의 경계를 설정하는 것과 관련된 글입니다.

이 글의 목차와 요약은 아래와 같습니다.

  1. 삶의 다양한 영역에서 경계를 정의하기

    1. 어떤게 협상 불가능한 것인가?

    2. 상황에 따라 유연하게 대응할 수 있는 건 무엇인가?

    3. 감당할 수 있는 책임과 당신의 목표에 적합하지 않는 목표는 무엇인가?

    4. 당신의 한계는 어디까지인가?

  2. 예의를 갖춰 분명하게 의사소통하기

    1. 우리의 생각과 기분이 다른 사람에게 전달된다는 환상을 갖고있지 않은지 점검해봐야 합니다.

  3. 당신의 기대에 맞춰 당신의 행동을 조정하기

    1. 당신의 목표와 가치에 맞춰 행동하는 건 다른 사람에게 강력한 메세지를 전달합니다.

  4. 모든 사람을 기쁘게 할 수 없다는 걸 받아들이기

  5. 경험하고 조정하고 적응하기

    1. 경계는 시간이 지남에 따라 그리고 상황에 따라 조정하고 적응해야 합니다.

'워라벨'이라는 말이 떠오를 수 있고 어느정도 연관이 있을 수 있습니다. 하지만 이 글을 통해 공유하고 싶은 건 '부드러움', '밸런스'보단 '한계를 시험해보고 한계를 파악하고 그 경계를 넘지 않는 한 노력하는 모습'입니다.

그러기 위해선

  • 나 자신을 잘 알아야 하고

  • 내 책임은 무엇인지 명확하게 하고

  • 이것들을 다른 사람에게 명확하게 전달

해야 합니다.

이 규칙은 나 뿐만 아니라 다른 사람에게도 마찬가지입니다.

  • 다른 사람은 어디에 가치를 두고 어떤 목표를 갖고 있는지

  • 이 사람의 책임은 어디까지인지

  • 이것들에 대한 내 기대는 무엇인지

명확하게 파악하고 역시 '분명하게 전달해야 합니다.'

지식을 나열하자면 이렇고, 지키기란 정말 어려운 일입니다. 그렇다고 포기하기엔 이르고 옳거나 좋은 방향을 새겨두고 잘 해내고 있는지 점검하면 좋겠습니다.

관련해서 존 카맥의 일하는 방식에 대한 인터뷰 영상을 공유합니다 :)

0
0
준프

준프

DOM에 대해 다시 알아봅시다

이번에 소개해드릴 글은 HTML과 DOM 등에 대해 설명해주는 글입니다. 제목은 다소 가벼워보이지만 내용은 절대 그렇지 않습니다. 읽다보면 중요한 내용이 툭-툭- 놓여있습니다. 관련해서 반드시 알아야 하는 내용도 많습니다.

목차는 아래와 같습니다. 개인적으로 밑줄을 치거나 저자가 '중요'하다고 한 내용을 포함하는 경우 볼드처리했습니다.

  • HTML이란?

    • 선언적

    • 의미론적

    • 하이퍼링크

    • 스트리밍

  • HTML 문서의 구조를 만들기

  • DOM

    • EventTarget

    • Node

    • Element

    • HTMLElement

    • SVGElement & MathMLElement

    • DocumentFragment

    • Attr

      • Content Attributes

      • Boolean Attributes

      • IDL Attributes

    • CharacterData

    • Text

    • Comment

  • Composing Light and Shadow DOM

  • Events

    • Listeners

    • Event Options

    • Event Propagation

    • Custom Events

목차만해도 엄청난 양이네요.

인상깊게 본 내용을 글을 보지않고 떠올려보면 Node vs Element, Streaming, input value attribute, event is synchronous, event callback function... 정말 많네요. 이정도 내용을 책으로 보려면 상당히 읽고 메모해둬야 하는데, 핵심을 잘 정리해두고 관련 링크를 잘 달아놔서 더욱 좋은 글인 것 같습니다.

0
0
준프

준프

추상화란?

최근 추상화에 대해 열심히 공부하는 중입니다. 추상화를 정의하는 유명한 문장 몇몇이 있지만 실제로 어떻게 활용해야 하는지, 제품을 만들면서 추상화를 언제 논의해야하는지 고민이 되기 마련입니다.

이번엔 추상화와 관련된 좋은 글 두 편을 소개하려고 합니다.

하나는 문동욱님의 '추상이란 무엇일까'라는 글입니다. 추상화를 프론트엔드 코드를 예시로 정말 잘 설명해주신 글이라 강력 추천합니다.

그 다음은 추상화를

  • 비즈니스 추상화

  • 제품 추상화

  • 기술적 추상화

로 세분화하여 소개합니다. 특히 각 추상화는 어떤 특징을 갖고 있고 어떤 절차로 추상화를 하는지 쇼핑몰 서비스를 예를 들어 비교적 자세히 설명하고 있습니다.

두 글 모두 술술 읽히는 쉬운 글은 아니지만 한 번 눈에 넣어두면 복잡한 제품을 만들 때 많은 도움이 될거라 생각합니다.

0
1
준프

준프

웹 컴포넌트 2024

이번에 소개해드릴 글은 W3C Web Components Community Group의 멤버, 브라우저 관계자, 라이브러리 제작자, 커뮤니티 구성원들이 모여서 웹 컴포넌트에 대해 나눈 이야기를 잘 정리해 놓은 글입니다.

평소 웹 컴포넌트를 다룰 일이 없고 그래서 잘 알지 못했는데 이번을 계기로 많은 정보를 얻을 수 있었습니다.

세부 목차와 요약을 살펴보면 아래와 같습니다.

  1. Declarative Shadow DOM (DSD)

    1. 선언적 Shadow DOM으로 해석할 수 있을 것 같습니다. Shadow DOM은 마크업, 스타일, 동작을 캡슐화 하는 한 방법인데요, DSD는 이걸 서버에서 준비하고 웹 페이지에서 하이드레이션 할 수 있는 방법을 제공합니다.

    2. 그 밖에도 많은 장점을 소개하고 있습니다.

  2. CSS Slot Content Detection

    1. 요소의 컨텐트가 변경되었을 때 스타일을 조정할 수 있는 방법을 제공합니다.

    2. 지금도 combinator, pseudo-selector를 사용해 가능한데 이 방법들이 복잡(?)하고 퍼포먼스적으로 좋지 않아 제안했다고 합니다.

  3. Scoped Element Registries

    1. 커스텀 DOM을 대규모 프로젝트에서 관리하기 용이하도록 제안된 기능입니다.

    2. 2023년에 Chromium에 프로토타입이 적용됐다고 하네요.

  4. ARIA Mixin

    1. ElementInternals를 통해 ARIA Mixin이 모든 최신 브라우저에 제공되었다고 합니다.

    2. 이를 통해 ARIA를 문자열로 한땀한땀 넣는게 아니라 객체의 속성을 통해 관리할 수 있다고 합니다.

  5. Cross Shadow Root ARIA

  6. Open Stylable

    1. 전역 스타일을 특정 웹 컴포넌트의 Shadow DOM 내부에도 영향을 주도록 하는 방법입니다.

  7. Container Style Queries

  8. CSS Module Scripts, Imports, and the @sheet Proposal

    1. 이걸 통해 css를 import 할 수 있게 되고

    2. 웹 컴포넌트에 적용되는 스타일을 포함하는 CSS Style Sheet를 한 파일로 번들링 할 때 독립성을 보장할 수 있다고 합니다.

  9. HTML Modules and Declarative Custom Elements

생소한 개념도 많고 '우와'하며 보게되는 지점도 많았던 것 같습니다. 매일 관성적으로 보던 코드에서 발전하는 코드를 보니 부지런해져야겠다는 생각이 들었습니다. 그리고 프로젝트의 성격에 따라 한 번쯤 사용해본다면 기술 선택의 폭이 넓어지지 않을까요?

이 글을 읽으며 찾아본 몇몇 문서를 추가로 공유합니다.

0
0
준프

준프

객체가 비어있다는 건 어떻게 확인하나요?

이번에 소개해드릴 글은 단순하지만 자바스크립트에 대해 많은 세부사항을 알게 하는 글입니다.

이 글에선 객체가 비어있다는 판단을 어떻게 하는지와 관련된 몇몇 방법을 소개합니다. 이 과정에서 아래와 같은 키워드를 알게 되고 확장해서 공부한다면 많은 도움이 되리라 생각합니다 :)

  • JSON.stringify

  • hasOwnProperty

  • Object.keys

  • Object.defineProperty

  • Object.getOwnPropertyNames

  • Symbol

  • Object.getOwnPropertySymbols

  • Reflect.ownKeys

0
0
준프

준프

모던 아키텍처: Functional Core - Imperative Shell 개조

이번에 소개해드릴 글은 코드의 구조와 관련된 글입니다. 이 글에서 강조하는 건 '요청 - 응답' 구조와 '고립과 모듈화를 통한 관심사의 분리' 그리고 '부수효과'입니다.

요약하자면 관심사를 잘 분리하더라도 각 고립된 모듈 내부에서 부수효과가 발생하면 코드 전체의 데이터 흐름에 문제가 발생하고 코드의 중요한 요소에 큰 타격을 준다는 것입니다. 따라서 Functional Core - Imperative Shell(FCIS) 방법을 사용하기를 제안합니다.

이 방법은 비즈니스 로직인 코어는 순수하게 유지하고 부수효과는 외부로 밀어냅니다. 그리고 Shell과 Core 사이에 단방향 요청 - 응답 구조를 갖춥니다.

이 방법은 다른 방법들에 비해 단순하고 명확해서 작은 규모의 코드부터 큰 규모의 구조까지 적용할 때 고려하면 좋은 구조라는 생각이 듭니다. 특히 부수효과가 많이 발생하는 프론트엔드 코드 구조를 생각해보면 더 알아보면 좋겠다는 생각입니다.

0
0
Add Kim

Add Kim

빈티지 영화의 시각적 효과를 웹사이트에 적용해봤다

처음으로 저를 소개하는 웹사이트를 제작하고 있습니다 !
현재는 메인 페이지를 완성했고 이제 추가적으로 연결 페이지들 만들 예정이에요 !
만들게 되면 또 올리도록 하겠습니다 !

개발에 뛰어든지 : 132일

[ 체험 해보기 ! ]

image.png

옛날 영화의 안좋은 화질의 느낌과
특유의 어두운 색감 ,

투박한 폰트로 빈티지한 느낌을 줘봤습니다

영화자막 효과와 레이아웃을 통해 최대한 영화처럼 보이게 하고 싶었어요

마우스 커서 인터렉션에 손전등의 빛을 쏘는듯한 효과를 적용해서 웹을 구경하는 재미를 더했습니다 !

재밌게 봐주시고

더하면 좋겠는 기능이나 효과같은것들 피드백 해주시면 정말 감사하겠습니다 !

0
0
준프

준프

유닛 테스트는 '테스트'가 아니라 '센서' 입니다.

테스트를 접해보지 않은 분과 대화를 나누다보면 테스트와 관련된 여러가지 이야기를 나누게 되는데요, 특히 테스트를 작성해야 하는 이유에 대해 이야기를 나누는 경우가 많습니다.

그러다보면 테스트가 실패했을 때 그리고 성공했을 때, 테스트는 어떤 것을 검증해야 하는지 등 많은 이야기를 매번 나누게 됩니다.

이번에 소개해드리는 글은 '테스트'가 코드에서 어떤 역할을 하는지 그리고 테스트의 성공과 실패는 무엇을 의미하는지 설명해주는 글입니다.

프론트엔드에서 테스트는 고비용 작업으로 많이 알려져있습니다. 하지만 테스트가 없기 때문에 이 글에서 소개하는 코드 수정으로 인한 '의도하지 않은 변경'이 발생하고 뒤늦게 발견하는 경우도 종종 마주합니다. 그래서 주의하자는 취지로 고비용의 꼼꼼한 QA가 포함됩니다.

프론트엔드에서 적정 수준의 테스트는 무엇인지 항상 고민합니다. 쉽지 않은 문제지만 그렇다고 포기하기엔 아쉽기도 합니다. 여러분의 의견은 어떠신가요?

이 글에서 인상 깊었던 몇몇 문장을 인용합니다.

If that were true, you’d need to write fewer tests as you got better at writing code, right? For a confident programmer, unit testing would soon start to feel like an unwelcome obligation imposed as part of a box-checking process.

"Unit tests are not about checking that the code works."

(당신이 코드를 잘 작성했다면 테스트는 적을 수록 좋은 게 맞다고 생각하나요? 확신에 찬 개발자라면 테스트 통과 표시는 그리 달갑지 않을 수 있습니다.)

It also needs to tell you exactly what you changed. If it’s something you intended to change, you can change the test to match. If it’s an accident, you leave the test as it is and go back to fix the production code.

Good unit tests are ones which separate the code cleanly into small pieces that can change independently. When a good unit test fails, it points directly at a specific piece of code or behaviour and says, “this changed: was that intentional?”

(내가 수정한 코드에 대해서만 테스트가 실패했다면 의도한대로 수정한 게 맞습니다. 만약 다른 유닛 테스트까지 실패한다면 의도하지 않은 코드가 영향을 받았을 가능성이 있습니다.)

When we write unit tests, what we’re really writing are change sensors.

(테스트가 아니라 센서라고 이해해보는 건 어떨까요?)

0
1
준프

준프

캐시를 다루는 방법

캐시, 스레드와 관련된 글은 주로 백엔드 개발자가 다루는 내용이 많습니다. 하지만 개인적으로 프론트엔드 개발자도 스레드와 얼추(?) 친하다고 생각합니다. 왜냐하면, 한 명의 사용자라고 하더라도 브라우저의 한 세션이 유지되는 동안 동일한 자원에 예상할 수 없는 간격으로 접근할 수 있기 때문입니다. 그래서 그런지 누구나 동일 자원에 접근하는 순서를 보장하기위해 땀을 흘리며 코딩해본 경험을 한 번쯤 가져보지 않았을까요? 이건 접근 속도에 차이가 있을 뿐 스레드를 다룰 때와 비슷한 이슈라고 생각합니다. (접근 시간 간격과 동일한 자원)


그리고 캐시를 활용해 퍼포먼스 향상을 하기 위해선 그 뒤에 어떤 비용(관리, 컴퓨팅 자원 등)이 있는지 이해하는 것도 중요하다고 생각합니다. 만약 관리하는 데 많은 비용이 든다면 캐시를 활용했더라도 지속적으로 유지하기 어려운 전략이지 않을까... 하는 생각을 항상 갖고있는 편입니다. 그래서 그런지 캐시를 활용하기 전에 다른 방법으로 성능을 개선할 수 있는 방법은 없는지 먼저 고민하려고 합니다.

이번에 소개해드리는 글은 캐시를 다룰 때 발생할 수 있는 문제와 캐싱 전략, 그리고 캐시 무효화 전략을 다루는 글 두 편입니다. 한 글의 시작은 유명한 문장으로 시작하는데, 너무 인상적이어서 알고있는 분도 많으리라 생각합니다.

There are only two hard things in Computer Science: cache invalidation and naming things. - Phil Karlton

'앗! 너무 어렵고 내가 평소에 다루는 개념이 아닌데?'라고 생각하기 보단 한 번 스윽 보고 캐시를 다뤄야 할 때 한 번 검토해보는 것도 좋지 않을까요? :)

0
0
준프

준프

Adapter 패턴 사용하기 (feat. React, TanStack Query)

Adapter 패턴에 대해 아시나요? 이 패턴은 인터페이스가 다른 두 객체를 이어주는 방법을 제공합니다. 프론트엔드에서 이런 상황이 가장 많이 발생하는 곳은 API 응답값과 컴포넌트에서 사용하는 속성간의 구조차이(인터페이스 차이)가 있습니다.

이번에 소개해드리는 글은 이러한 차이를 Adapter 패턴을 통해 해소하는 방법을 소개합니다.

DTO를 사용하는 것과 큰 차이를 못 느낄 수도 있지만, 이 패턴은 단순히 데이터의 구조가 다를 때만 사용하는 게 아니라 인터페이스, 즉 메서드(행동)의 인터페이스가 다른 경우에도 사용할 수 있으므로 알아두면 의외의 도움이 되리라 생각합니다.

그 밖에 TanStack Query에서 데이터를 변환하는 방법에 대한 좋은 아티클도 남깁니다 :)

0
0
Add Kim

Add Kim

프론트엔드 입문하고 첫 정식 프로젝트 제작을 시작했어요 !

개발에 뛰어든지 : 115일

[ 체험 해보기 ! ]

피드백은 사랑입니다

image.png

골든서클이론에 기반해서 목표를 설정하고, 목표의 신념과 목적을 잊지않게 상기시켜주는 콘텐츠를 만들어 보고싶어, 제 나름대로 만들어보고 있습니다 !

오늘부로 긴 잠적을 깨고 메인 홈페이지를 완성한걸 올려봅니다 !

하지만.. 이제 시작이겠죠 ? ㅎㅎㅎ

0
2