전체 글 33

사용자 불편 최소화를 이미지 업로드 및 렌더링 방식 개선

📌 문제인식 회원가입 과정에서 사용자가 등록할 프로필 이미지를 선택하면 이미지를 등록하는 과정에서 화면 깜빡임이 발생한다. 사용자가 이미지를 선택하자마자 이미지를 Firebase Storage에 저장 후 URL을 받아오면 로딩시간이 생기기 때문에, 이미지의 URL을 state로 관리하고 클라이언트에서 임시 URL을 사용하고 storage에 저장이 완료되면 storage로 부터 받은 URL을 사용하여 Optimistic Update처럼 구현하려던 계획이었다. 하지만 storage에 업로드 후 받아온 URL로 대체하고 이미지를 읽어오는 과정에서도 딜레이가 발생해서 화면 깜빡임이 발생하는 것이었다. 위에서 말로 설명한 아바타 이미지가 등록되는 로직을 코드와 함께 조금 자세히 살펴보면 아래와 같이 진행된다. 사..

PROJECT/code-forest 2024.03.11

게시글 작성 시 Firebase Storage 이미지 경로 설정(Quill)

프로젝트를 거의 마무리 해 가는 지금 돌이켜보면 Quill 에디터를 다루면서 이런 저런 고생을 많이 했던 것 같다. 이번에는 게시글을 작성하면서 이미지가 저장되는 storage 경로에 대해 고민한 흔적을 남겨보고자 한다. ❓이미지? 저장 됐으면 된거지🤣 Firebase를 처음 다뤄보고 Quill 에디터를 처음 사용하는 나에게는 게시글 DB 경로나 이미지 파일을 어떤 경로로 설정해서 저장해야할지에 대한 고민은 사치처럼 느껴졌다. 파일을 어떻게 저장하지? 그 파일은 어떻게 불러오지? 등 단순히 기능하게 끔 하는 것 조차 도전적인 과제처럼 느껴졌기 때문이다. 결국 게시글을 저장하는 최초의 로직은 다음과 같이 구현했다. 게시글 작성 중 이미지가 첨부되면 유저의 uid를 파일명으로 하는 storage 경로에 이미..

PROJECT/code-forest 2024.03.04

게시글 이미지 업로드 로직에 대한 고민 문제 해결 과정(Quill)

개발자들이 이용하게 될 커뮤니티를 만들면서 에디터에 대한 고민을 많이 하게 되었다. 특히 개발자를 대상으로 한다는 점에서 Heading,코드블럭,indent 등의 기능을 반드시 제공해야 한다고 생각했다. 처음에는 에디터를 내가 생각하는 핵심적인 기능들만 모아 최대한 커스텀 제작을 하고자 했지만, 제한된 개발 기한 안에는 완성도 높게 만들기 어렵다고 판단하여 react-quill 에디터 라이브러리를 사용하게 되었다. 그리고 이번 글에서는 게시글 작성 페이지에서 이미지를 업로드하는 로직을 구현하며 내가 겪었던 실패들과 고민들에 대해 적어보고자 한다. Quill의 이미지 첨부 기본 값 그리고 내게 필요한 로직 기본적으로 Quill 에디터의 경우 이미지를 첨부하게 되면 사용자가 이미지를 등록하게 되면, 해당 파..

PROJECT/code-forest 2024.03.03

코드 스플리팅을 통한 번들 사이즈 최적화

이슈 프로젝트를 빌드하는 도중 아래와 같은 경고문을 발견했다. 해석을 해보면 JS파일로 번들링된 청크 중에 500kb를 초과하는 것이 있으니 줄이라는 말이다. 문제점 현재는 하나의 JS파일로 번들링 된 결과물로 웹 페이지를 배포하게 되는데, 이렇게 되면 사용자가 웹 페이지에 진입할 때 해당 페이지를 구성하지 않는 모든 페이지에 대한 정보를 불러오게 되고 초기 로딩을 느리게 만들어 사용자 경험을 악화시킨다. 실제로 아래와 같이 번들에서 사용하지 않는 부분이 무려 90퍼센트나 되는 것을 볼 수 있다. 번들 사이즈 최적화 번들 사이즈 최적화를 위해서는 아래와 같은 작업들을 할 수가 있다. ✅ 여러 파일로 번들링하여 실제로 사용되는 번들만 다운로드 받기 ➡️ 코드스플리팅 등 ✅ 번들링 될 자바스크립트 파일 크기..

PROJECT/code-forest 2024.02.28

Javascript - 최소 힙(MinHeap)

이진 트리를 기반으로 한 자료구조 부모 노드가 자식들보다 작거나 같은 구조, 가장 작은 값이 root에 위치하는 자료구조 우선순위 큐 구현, Heap Sort에 활용된다. 가장 작은 값을 O(1)의 시간으로 빠르게 찾을 수 있다. heapifyUp(); 새로운 노드가 삽입되고 자기 위치를 찾아가도록 하는 메소드 heapifyDown(); root 노드가 pop되고 최소 힙의 조건에 맞도록 트리를 재정비하는 메소드 class MinHeap { constructor() { this.heap = []; } push(value) { this.heap.push(value); this.heapifyUp(); } pop() { if (!this.heap.length) return null; const root = t..

비동기적으로 작동하는 useState를 알아보자

자바스크립트는 일반적으로 코드를 작성하면 동기적(Synchronous)으로 작동한다. 하지만 useState의 setter 함수인 setState는 비동기적(Asynchronous)으로 작동한다. 다시 말해 setState 함수의 실행이 완료될 때까지 기다려주지 않고 곧바로 다음 코드가 실핸된다는 것이다. 리액트에서 setState로 state를 관리하다보면 비동기적으로 작동해 내가 의도한대로 값을 갖고 있지 않을 때가 있다. setState가 의도대로 동작하지 않는 이유 자바스크립트는 동기적(Synchronous)으로 동작한다. 하지만 때때로 동기/비동기에 대한 이해가 부족하거나 라이브러리에서 제공하는 함수들에 대한 이해 없이 사용하게 되면 개발자는 의도대로 동작하지 않는 코드에 당황할 수 밖에 없다...

React 2023.12.18

프로그래머스 - 다단계 칫솔 판매

프로그래머스 - 다단계 칫솔 판매 풀이과정 문제는 길고 복잡하게 느껴졌는데, 특별한 알고리즘은 필요로 하지 않는 문제였다. 먼저 모든 데이터들이 개별 배열로 주어져서 이를 객체로 묶어줬다. // 판매원 : 판매원을 추천한 사람 을 이어주는 객체 const recommendation = new Object(); // 각 판매원이 얼마의 이익금을 가져갈지 저장하는 객체 const profit = new Object(); // 주어진 입력값을 통해 recommendation을 채우고, // profit은 모두 0으로 초기화 for(let i = 0; i < enroll.length; i++){ if(referral[i] !== '-') { recommendation[enroll[i]] = referral[i]..

Javascript - 연결리스트로 큐(Queue) 구현

큐를 이용한 알고리즘 문제를 풀 때 매번 shift 메소드를 이용해서 문제를 풀다보니 시간초과를 많이 겪게 된다. shift 메소드를 이용하면 맨 앞의 원소를 꺼내고 다른 모든 원소들을 한칸씩 인덱스를 당겨줘야하기 때문인데 연결리스트를 구현하게 되면 O(N)의 시간복잡도를 O(1)로 줄일 수 있다. class Node { constructor(data) { this.data = data; this.next = null; } } class Queue { constructor() { this.head = null; this.tail = null; this.size = 0; } enqueue(data) { const newNode = new Node(data); // 기존 데이터가 없는 경우 if (!this..

프로그래머스 - 부대 복귀(Javascript)

프로그래머스 - 부대 복귀 풀이과정 각 부대원들이 부대로 복귀하는 최단경로를 찾는 문제인데, bfs를 통해 각 부대원별로 목적지까지 최단 경로를 구하려다보니 시간초과가 발생했다. 아래는 시간 초과가 발생한 코드 function solution(n, roads, sources, destination) { const answer = []; const graph = [...Array(n+1)].map(()=>[]); for(const road of roads){ const [a,b] = road; graph[a].push(b); graph[b].push(a); } // source에서부터 graph를 순회하여 destination에 도착하는 최단거리를 구하는 bfs 함수 function bfs(start){ ..