고객을 최우선으로 합니다.
고객의 소중한 2시간이 Good Game으로 기억될 수 있도록 유저의 목소리에 항상 귀 기울입니다. 플랩 구성원들은 사용자 중심으로 생각하기 위해 참가자 혹은 매니저로 매치에 직접 참여하여 현장에서 유저들을 만나고, 더 즐겁게 참여할 수 있는 방법에 대해 고민합니다.
그 안에서, 핵심에 집중합니다.
우리는 다양한 문제들 중에서 긴급하고 중요한 일, 우선순위로 집중해야 할 일에 대해 먼저 파악합니다. 문제의 핵심을 파악하고 보다 효과적으로 일할 수 있는 방식에 대해 항상 고민하는 자세를 무엇보다 중요하게 생각합니다.
이후 핵심사안에 대해 집중(Focus)하고, 집중하기로 한 일을 빠른 속도로 실행할 수 있도록 분기마다 OKR을 실시합니다. OKR은 조직 전체가 동일한 사안에 집중할 수 있도록 도와주는 경영 도구로써 이를 통해 우리가 하지 않아야 할 일을 확실히 정리하여 ‘선택과 집중’에 전념합니다.
그러기 위해, 모든 정보를 공유합니다.
업무와 관련된 정보는 사내 구성원 모두에게 투명하게 공개합니다. 각 팀 별 업무 진행 상황은 물론 지표와 재무 상황에 대해 협업툴(Slack, Notion)을 통해 기록하고 공유합니다. 또한 자체적인 플랩 데이터 센터를 고도화 하여 구성원들에게 필요한 정보를 제공하여 올바른 판단을 내릴 수 있도록 돕고 있습니다.
단, 의견은 수평적으로, 의사결정은 수직적으로 합니다.
팀원들이 자유롭게 의견을 낼 수 있는 환경을 조성하기 위해 노력합니다. 직급 없이 닉네임을 사용하고 누구든 의견을 제시할 수 있는 수평적인 분위기를 지향합니다. 또한 민주적인 의사 결정 방식은 다소 위험한 방법이라고 생각합니다. 팀 리더들은 데이터에 근거하여 의사 결정 권한을 바탕으로 구성원들과의 논의를 통해 최종 의사 결정을 내립니다.
★ 플랩의 회의 진행 방식
우리는 두 가지 방식으로 회의를 진행합니다. 의사결정이 필요없는 논의회의와 의사결정이 필수로 이루어져야하는 의사결정 회의로 구분됩니다. 논의 회의는 특정 이슈에 대해 누구나 자유롭게 의견을 제시하되, 반드시 의사결정이 이루어지지 않아도 괜찮습니다. 단, 리더는 구성원들이 충분한 시간을 가지고 고민할 수 있도록 사전에 해당 이슈에 대해 고지하고, 구성원은 깊은 고민을 거친 후 회의에 참여해야 합니다.
의사결정 회의에서는 기존에 논의했던 내용을 바탕으로 반드시 의사결정의 매듭을 짓습니다. 단, 리더는 다수결과 같이 민주적인 의사결정은 지양하고 데이터를 기반으로 한 종합적인 판단으로 최종 결정을 내립니다. 의사결정이 내려지면 구성원들은 해당 결정을 믿고 충분히 팔로우해야 합니다.
가치추구
첫 번째는 건강입니다. 건강한 신체와 정신은 한계를 뛰어넘는 도전정신과 올바른 선택을 돕는다고 믿고 있습니다.
두 번째는 성장입니다. 빠르게 변화하고 있는 산업에서 우리의 가장 큰 경쟁력은 구성원 개인의 성장이라고 확신합니다.
★ 플랩에서 생각하는 개인 성장의 범위
우리는 개인의 성장에 대해 세 가지로 구분하고 있습니다. 첫 번째는 직무와 관련된 성장입니다. 우리는 플랩 구성원이 맡은 직무와 관련하여 보다 깊고 넓은 성장을 이룰 수 있도록 강의 및 세미나와 같이 교육비를 지원하고 있습니다.
두 번째는 사고의 폭을 넓히는 성장입니다. 구성원들이 사고의 폭과 깊이를 확장할 수 있도록 제한 없이 도서 구입비를 지원하고 있습니다. 또한 플랩 이후의 커리어, 또는 앞으로의 삶의 방향에 대해 서로 이야기하고 생각을 나눌 수 있는 시간을 가집니다.
마지막은 커뮤니케이션의 성장입니다. 우리는 서로에 많은 것을 배울 수 있다고 생각합니다. 상호 신뢰를 바탕으로 서로의 강점을 발견하고, 잠재력을 발휘하여 더욱 발전할 수 있도록 동료 피드백을 시행합니다.
동료 지향점
긍정적인 사람
일하는 게 재밌고 즐거운 사람들이 있습니다. 그런 사람들이 모이면 회사에 항상 긍정적인 에너지가 넘칠 거라고 믿고 있습니다. 일을 하는데 있어서 반대하기보다는 대안을 찾고, 미래를 걱정하기보다 현재에 충실한 사람들과 함께하고 싶습니다.
건강한 사람
건강한 신체와 정신은 우리의 한계를 뛰어넘는 도전정신과 올바른 선택을 돕는다고 생각합니다. 스스로의 건강에 대해 관심을 가지고 정기적인 운동과 규칙적인 생활을 하는 것은 아주 기본적인 사항이지만, 우리는 정말 중요한 가치라고 믿고 있습니다.
성장 가능성이 큰 사람
빠르게 변화하는 스타트업 생태계에서 새로운 도전을 좋아하는 사람이면 좋겠습니다. 새로운 능력과 역할이 필요할 때, 배움에 대해 두려움이 없고 유연한 사고를 통해 성장할 수 있는 사람이 중요하다고 생각합니다.
성능 최적화, 트러블슈팅 경험이 있으신 분테스트 코드 작성 경험이 있으신 분AWS 배포 및 인프라 관리 경험이 있으신 분웹 접근성 및 웹 표준, 크로스 브라우징 경험이 있으신 분반응형 웹 개발 경험이 있으신 분디자인 시스템 이해와 경험이 있으신 분CSS 전처리기, 프레임워크 사용 경험이 있으신 분코드 리뷰, 페어 프로그래밍, 스터디와 같은 개발 문화에 관심이 많으신 분
콜백함수, 고차함수(함수를 인자로 받거나 함수를 리턴하는 함수), 익명함수, 화삺표함수, 생성자함수 등 존재
undefined와 null의 차이는 무엇인가요?
🟠 undefined 에 대한 설명
댓글
개발자 의도 여부
null은 nothing, empty, unknow
아예없는 값, 비어있는 값, 모르는 값을 표현하기 위해 사용
값, 식 , 문의 차이를 말해주세요.
🟠 값 정의
댓글
값: 식이 평가되어 생성된 결과
식: 값을 결정하기 위해 연산과정이 진행되는 구문
- 상수, 변수, 함수, 연산자들의 조합
- 의도를 가지고 있지 않음
문: 하나의 액션 단위
- 선언문, 할당문 ,if문 과 같이 데이터에 대한 의도를 가진 행위가 함께 함
객체의 값으로는 식은 가능하지만, 문은 불가하다
실행컨텍스트’는 스냅샷 형태의 변수환경(VE) + 실질적 정보를 가지고 있는 렉시컬 환경(LE)
’렉시컬환경(LE)’는 내부 식별자 정보인 ER +
자신을 호출한 외부환경에 접근하기 위한 외부환경참조(OuterEnvRef) + this 바인딩 정보
호이스팅 (Hoisting)란 무엇인가요?
댓글
‘호이스팅’은 런타임 이전에, “js엔진이 해당 컨텍스트의 식별자들을 최상단으로 끌어올려 놓은 후 실제 코드를 실행하는” 것 처럼 동작하는 것을 표현하는 가상의 개념입니다.
실행컨텍스트 생성 시, 렉시컬환경의 ER에 식별자정보를 저장하는 과정
함수 선언 역시 호이스팅 되며, 직관적인 코드 순서와 다르게 동작하므로 주의가 필요
scope란 무엇이며 var, let, const에 대해 설명해주세요.
댓글
스코프’는 식별자의 유효범위
모두 변수 선언 키워드
’var’는 함수스코프 + 런타임 이전 선언 할당
’let, const’ 블록스코프 + 런타임 이전 선언만
’let’은 선언, 초기화, 할당 분리
’const’는 선언,초기화,할당 동시 + 재할당 불가
’TDZ’는 스코프 시작 지점 부터, let/const 키워드를 만나 초기화 되기 직전 까지 해당 식별자에 접근이 불가한 영역
스코프 체인은 무엇인가?
댓글
스코프체인’은 식별자의 유효범위를 내부에서 외부로 차례대로 검색해나가는 방식
렉시컬환경의 외부환경참조(OuterEnvRef)를 통해 가능
클로저
클로저 정의
클로저 활용 사례 (counter, useState)
답변
debounce 사례
useState 사례
Promise, 비동기, 이벤트루프
동기와 비동기란 무엇인가요?
댓글
동기’는 선행 작업의 끝과 다음 작업의 시작지점이 일치하는 것.
”비동기’는 선행 작업의 끝과 다음 작업의 시작지점이 일치하지 않는 것
하나의 작업이 끝나기 전 동시에 다른 작업이 실행될 수 있는 것
[장단점]
비동기는 시스템 자원을 효율적으로 쓸 수 있는 반면,동시에 작업이 처리되어순서성 보장 어려움 + 후속 처리 작업 설계 복잡함
이벤트루프는 무엇인가?
댓글
이벤트루프’는, js엔진의 콜스택에서 쌓인 코드가 실행될 때, 비동기 처리를 도와주는 브라우저의 기능을 말합니다.
JS에서 비동기 동작들은 web API들을 통해 처리되며, 처리된 결과인 콜백함수들이 콜백큐에 담김
이벤트루프는 콜스택과 콜백큐를 번갈아가며 주시
콜스택이 비었을 때, 콜백큐에서 꺼내 실행
콜백 헬을 해결할 수 있는 방법은 무엇이 있을까요?
프로미스란 무엇이고 어떻게 사용되나요?
🟠 프로미스 등장 ES5? ES6?
🟠 프로미스 장단점
댓글
프로미스’는 비동기 처리를 위한 js내장 객체
콜백함수를 인자로 받음
콜백함수는 resolve와 reject 함수를 기본 인자로 가짐
콜백함수 내의 비동기 처리가 완료되면 resolve 호출하고 인자로 data를 넘김
[사례]
모두 Promise객체를 리턴하는 함수 사용
getData(userInfo)
.then(parseValue)
.then(auth)
.then(diaplay);
프로미스와 async/await의 차이점은 무엇일까요?
🟠 asnyc await 정의
ES6
ES 란 무엇인가요?
댓글
ECMAScript‘는 자바스크립트 표준을 의미
ES5 는 2009년, ES6는 2015년
[ES6]
1) let, const 키워드
2) 템플릿 리터럴
: ${} 를 통해 문자열 내에서 표현식 사용 가능
3) 화살표함수
: 함수표현식을 간결하게 표시
4) 구조분해할당
: 객체나 배열의 값을 해체한 후, 개별 값을 각각의 식별자에 할당하는 문법
5) 프로미스
: 비동기처리를 위한 새로운 방법
: 콜백헬 해결, 후속처리 메소드 지원
6) DefaultParameter
: 매개변수의 초기값을 지정
ES6 이상 버전을 브라우저에서 인식하지 못하면 어떻게 처리할 수 있나요?
Arrow 함수는 왜 사용하나요?
댓글
function 키워드 보다 간략하게 표현하여 가독성 증대 목적
this에서 차이가 있다.
화살표함수에서 this는 동적으로 함수 호출 방식에 따라 정해지는 것이 아닌, 항상 상위 스코프의 this를 가르키도록 하여 예측가능한 함수 사용에 도움
객체지향프로그래밍
힌트
객체지향과 함수형프로그래밍
객체지향: 객체를 통해 데이터와 메소드를 묶고, 객체들의 통신을 중심으로 구조
함수형프로그래밍: 데이터를 함수로 묶고 새로운 데이터를 만들어나가는 방식
a 사이드 이펙트 없다
b 재사용성 높다
c. 코드가 짧고 간결하다
선언형 프로그래밍
함수형프로그래밍 == 선언형 프로그래밍
명령형 프로그래밍 = 절차지향형
Goto, if-else, for-while
함수형 프로그래밍 == 선언형,
Stateless, Recursion, Pipe
5-1. 객체지향이란
1. 객체란
객체지향의 객체는 현실에 있는 것을 “추상화”한 것
추상이란
사물의 여러 측면 중 필요한 부분만을 남겨 표현한 것
2. 객체지향이란?
객체 위주로 설계하고 프로그래밍하는 패러다임
객체지향의 오해
패러다임일 뿐 언어와는 관계가 없다
절차지향보다 객체지향이 무조건 좋은 것이 아니다
복작합 프로그램에 객체지향이 더 적합
5-2. 프로토타입
js에서의 객체
클래스 기반 언어처럼 속성과 행위를 정의할 수 있다.
js 객체 생성방법
객체 리터럴, Object, 생성자함수
프로토타입이 필요한 이유
생성자로 객체 생성 시 같은 속성에 대한 메모리 낭비
[Typescript]
Typescript는 무엇이고, 왜 사용하나요?
댓글
[왜 사용]
협업/유지보수 위해
: 내가 아닌 다른 개발자도 읽는다. 가독성을 증진시켜 유지보수 비용을 줄인다.
생산성
: 자동완성 기능 강력하다고 생각
+ 에러를 컴파일 단계에서 발견할 수 있다는 점
타입스크립트의 장단점
🟠 단점?
기본타입의 종류와 유틸타입에 대해 아시나요?
🟠 유틸타입과 사례
type과 interface의 차이
🟠 잘모르겠다.
any와 unknown의 차이
🟠 unknown ?
힌트
any는 어떤 타입도 허용
unknown은 알수없음이라는 타입을 부여한 것
unknown.length 는 에러를 뱉어냄
enum은 무엇인가요?
🟠 enum 정의 사례
enum 정의 사례
enum은 상수의 집합
interface ⇒ 객체를 묘사하고 원형을 설계하는 모델링
type alias ⇒ 타입의 별명을 다는 것. 그런데 요즘 인터페이스가 하는 역할까지 하려고 함. 선 넘는 중? enum 정의 사례
virtualDOM은 htmlDOM을 메모리 상(js의 객체)에서 표현한 것입니다.
react에서 변경 발생 시 최적의 리렌더링을 하기 위해 사용하였고, 이는 재조정과정을 통해 이루어집니다.
재조정 과정을 통한 리렌더링 최적화
선언적 API (UI 상태와 DOM이 일치하도록 함)
Virtual DOM은 실제 DOM 변화를 최소화 시켜주는 역할을 합니다.
virtualDOM을 이용하는 이유는 효율성 때문입니다. virtualDOM을 활용하면 실제 DOM을 직접 바꾸는 것보다 시간 복잡도가 현저히 낮아지는데요.
먼저 브라우저는 HTML 파일을 스크린에 보여주기 위해 DOM 노드 트리 생성, 렌더트리 생성, 레이아웃, 페인팅 과정을 거칩니다. DOM 노드는 HTML의 각 엘리먼트와 연관되어 있기 때문에 HTML 파일에 20개의 변화가 생기면 DOM 노드가 변경되고 그 이후의 과정역시 20회 다시 이루어 집니다. 작은 변화에도 매우 복잡한 과정들이 다시 실행되기 때문에 DOM 변화가 잦을 경우 성능이 저하됩니다.
Virtual DOM은 뷰에 변화가 있다면, 그 변화가 실제 DOM에 적용되기 전에 Virtual DOM에 적용시키고 최종 결과만 실제 DOM에 전달합니다.
따라서 20개의 변화가 있다면 Virtual DOM은 변화된 부분만 가려내어 실제 DOM에 전달하고 실제 DOM은 그 변화를 1회로 인식하여 단 한번의 렌더링 과정만 거치게 됩니다.
AMStack에서 Markup을 위한 프레임워크로 사용
식자재마트 리스트 출력을 위한 기능으로 SideEffect가 발생하지 않기 때문에, SSG가 적합하다고 판단. 추후 상품 상세 페이지 마다 Meta태그 적용을 위한 것도 고려
1. 데이터 교환이 많은 앱인가? (Yes: React, No: Next)
2. 검색엔진노출이 중요한 앱인가? (Yes: Next, No: React)
3. 또한 프레임워크가 제공해주는 여러 기능들이 마음에 들고 공감하는가? => 그럼 사용
CSR, SSR, SSG, ISR 데이터 페칭 차이는?
댓글
CSR: useEffect를 통해 client에서 렌더링 이후에 데이터 페칭을 요청하는 방법
SSR: 페이지 이동 발생 시 , 서버에서 데이터페칭을 진행하고 완성된 HTML 파일을 내려준다.
SSG: 빌드 될 떄, 데이터 페칭을 진행하여 완성된 HTML 저장
ISR: SSG + 특정시간과 조건에 업데이트
SSR의 Hydration 과정
[Vue]
vue 영웅님 강의 필기 참고
link ⇒
Vue와 React 에 차이에 대해 아시나요?
힌트
: vue는 양방향 데이터 바인딩
: 정해진 구조나 패턴이 명확
: React 는 단방향 데이터 바인딩
: 자유도가 높다
Vue의 가장 큰 특징은 무엇인가요
[ webpack/Babel ]
[webpack]
댓글
모듈 번들링을 해주는 도구
여러개의 js 파일의 의존성 관계를 설정하고, 하나의 js파일로 만들어주는 역할
JS이외의 파일을 처리하기 위해서는 JS 형식으로 파일을 변환한 후, 번들러로 전달해야함. babel-loader, css-loader와 같이 loader를 사용. loader는 웹팩이 웹 애플리케이션을 해석할 때 자바스크립트 파일이 아닌 웹 자원(HTML, CSS, Images, 폰트 등)들을 변환할 수 있도록 도와주는 속성
Babel 은 무엇이고 언제/어떻게 사용하나요
댓글
트랜스파일러
◦ Jsx ⇒ js, TS ⇒ js, scss ⇒ css
[ 상태관리 라이브러리 - Redux/Recoil/ContextAPI ]
Context API
Redux
Recoil
React-query
힌트
contextAPI
간단한 전역상태 관리도구로서 적합
특정 상태가 변할 경우 하위컴포넌트가 모두 리렌더링 되는 성능이슈 존재
Redux
Flux 패턴 사용
action (type, payload) > reducer:(action, 이전 state) ⇒ 새로운 state > Store 저장
Recoil
atom과 파생 상태인 selector를 통한 심플한 구조
구독하는 컴포넌트만 을 리렌더링 함
api 캐싱과 suspense 지원 등 부가적 기능
React-query
client에서만 사용하는 상태와 server-data와 긴밀한 상태를 구분하겠다는 원리
key 기반으로 data를 페칭해와 캐싱하고, stale 판단 시 데이터를 refetching 해옴
scss는 css를 조금 더 효율적으로 사용하기 위해 자체 문법을 가지고 있는 대표적인 css전처리기 중 하나입니다.
[장점[
1) 변수를 지정함으로 재사용성을 증가 ($color변수)
2) nesting(중첩)을 통해 불필요하게 중복된 selector를 선언하는 것을 막고 가독성을 높일 수 있다.
3)조건문 반복문 등의 간단한 연산가능
4) mixin을 통해 자주쓰는 속성들을 모듈화 할 수 있다.
(버튼, 반응형틀)
이러한 CSS전처리기는 재사용성과 시간비용을 줄인다는 점, 유지관리가 용이하다는 장점이 있습니다.
단점)
바드시 컴파일과정 거쳐야 한다는 점
CSS in JS(styled component)의 장단점에 대해서 설명하세요.
💡
[개념]
css in Js는 문서단위의 스타일 시트가 아닌 컴포넌트 단위로 스타일 시트를 추상화하여 작성하는 방식으로 js 파일안에서 css를 같이 선언하는 방식을 말합니다.
[장점]
1) 컴포넌트 단위의 추상화(모듈화)
- 컴포넌트 단위로 React , Vue 같은 컴포넌트 단위에 잘 어울린다.
- css 별개로 문서단위로 작성하는 것 해결
- 오직 해당 컴포넌트에만 영향을 주어, 생성 수정 삭제가 자유로움
2) 유지보수의 장점
- 큰 규모의 프로젝트에서 css파일의 코드가 많을 경우
수십개의 스타일 시트를 찾아야하는 문제
- 겹치지 않는 변수명을 짓게 해준다.
[단점]
외부 의존성 (초기진입속도)
[↔인라인]
인라인은 DOM노드의 속성으로 추가하지만
css in Js는 별도의 style 태그를 생성하고 그 안에 작성코드를 작성한다.
selector를 가지므로 js에서 핸들링 가능하다.
id와 class의 차이는, 유일한 요소를 지정할 때에는 id속성을 사용하고, class는 복수의 요소에 적용할 때 사용한다는 점입니다.
(* id의 우선순위가 class 보다 높다)
CSS 박스 모델에 대해서 설명하세요.
💡
box model은 각각의 Object를 넓이와 높이를 가진 박스형태로 나타내어, 브라우저에 배치하기 위한 규칙입니다.
각각의 박스들은 content , padding, border, margin 로 구성된다.
content - html태그가 차지하는 공간 (width, height)
padding - content의 내부 여백
border - 테두리
margin - 테두리 밖 외부 여백
*기본적으로 padding, border는 width의 포함이 되지 않아, 실제 차지하는 공간의 계산이 어렵기 때문에,
box-sizing: border-box 옵션을 주어 width에 padding과 border를 포함시킬 수 있다.
CSS에서 px, em, rem, vh, vw 단위들의 차이점은 무엇인가요?
💡
[px]
px은 글꼴 크기 표시하는 표준단위 입니다. px은 화면 크기에 상관없이 고정되어 있기 때문에 반응형 웹등에 적합하지 않고, 화면크기가 고정적인 출력용 파일에서 유리합니다.
[em, rem]
px과 다르게 상대적인 단위입니다.
em은 부모요소의 글꼴 크기를 기준으로 자신의 글꼴 크기가 결정됩니다. 부모요소의 크기가 10px이면 자식요소에서 2em은 20px를 의미합니다.
rem은 html 루트요소의 폰트사이즈를 기준으로 하여 글꼴의 크기를 지정한다.
예를 들어 html의 font-size가 10px이라면 2rem은 20px이 된다.
[ vh (vertical height) vw(vertical width)]
너비와 높이값을 뷰포트(화면)의 크기를 기준으로 작성할 때 사용한다.
화면에 꽉 차는 크기를 지정할 때 유용하다.
[flex]
flex는 레이아웃을 편하게 잡기 위한 css의 속성으로 단방향 레이아웃 설계에 강점이 있습니다.
flex는 플렉스 컨테이너라는 부모요소와 플렉스아이템이라는 자식요소를 가지고, 메인축을 지정하여 수평, 수직 정렬을 구현합니다.
flex는 요소의 크기가 불분명하거나, 동적인 경우에도 요소를 효율적으로 정렬할 수 있다는 장점이 있습니다.
[grid]
flex가 단방향 레이아웃 설계라면 그리드는 2차원의 두방향 레이아웃 시스템입니다.
grid-template-columns, rows 속성을 통해 각 행과 열의 아이템 개수와 비율을 지정할 수 있으며
row-gap, column-gap 속성을 통해 각 행과 열 사이의 간격을 지정할 수 있습니다.
• [x] 1 SSR (Server Side Rendering) 과 CSR (Client Side Rendering)을 각각 설명해주세요. 특징장단점
◦ 답변
SSR
▪ 완전하게 만들어진 HTML 파일을 서버로 부터 받아, 웹브라우저에 렌더링
▪ (장점) 초기로딩속도 빠르다.
▪ (장점) SEO (검색엔진 최적화 가능) - meta 태그들미리 정의되어있음
▪ (단점) 매 페이지 요청시 마다 새로고침되어 UX 떨어짐
▪ (단점) 매 패이지 요청 때문에 서버 트래픽,부하 증가
▪ 동작과정
• client요청 → data,css 적용된 html + js 응답(server) → html먼저 렌더링(browser) → js 다운 후 실행(browser)CSR
▪ 첫 렌더링 시, HTML과 static파일을 먼저 전부 다운로드하고, 이후 필요한 리소스가 있을 때에만 서버에 요청하고 이를 웹브라우저에 반영하는 방식.
▪ (장점) 첫 로딩이후 렌더링 속도가 빠르다.
▪ (장점) 서버 부담이 적다.
▪ (단점) 초기 로딩속도 느리다.
→ resource를 chunk단위로 묶어서 다운로드, Razy Loading을 통해 초기렌더링에 필요한 부분만 먼저 다운로드 받는 방법
▪ (단점) SEO(검색엔진 최적화)에서 문제 발생
→ 구글엔진만이 js까지 크롤링함
→ react.helmet 라이브러리를 통해 각 컴포넌트 별로 meta 태그 지정,
→ 빌드시 하나의 html이기 때문에 SEO 어려움
→ react-snap을 통해, 배포시에 페이지 별(router)로 html파일을 생성하도록 함
• [x] 1-1 본인이 어떤 프로젝트를 진행할 때, SSR과 CSR 중 어떤 것을 선택하였고, 선택이유는 무엇인가요?
◦ 답변
▪ 서비스 성격에 따라 선택할 것
• 검색을 통한 상위 노출이 필요할 경우 (e-commerse) → SSR
• 첫 페이지 로딩이 중요한 경우 (e-commerse detailPage) → SSR
• 모바일에서 주로 사용하는 웹사이트 → CSR
▪ 참고
• https://miracleground.tistory.com/165
• [x] 2 SSR과 CSR을 중심으로, 렌더링 관점에서의 흐름 변화를 말해주세요.
◦ 답변
▪ 전통적인 렌더링 방식 (SSR)
▪ 터닝포인트
• 모바일 기기(스마트폰)의 급격한 발전
◦ 트래픽최소화, 속도와 반응성, 사용성(UX) 기준 올라가 반영
▪ CSR의 흐름
• React, Vue
▪ 다시 SSR 방식의 SPA
• Next.js
◦ 첫 페이지는 SSR을 통해, 채워진 Html을 받아 SEO문제를 해결하고,
다음페이지부터는 CSR 방식을 적용하여 사용성(UX), 서버부하를 해결한 프레임워크
• [x] 3 SPA(Single Page Application)와 MPA(Multi Page Application)을 각각 설명해주세요.
◦ 답변
▪ SPA는 한 문장으로 말하면, 모바일퍼스트 전략에 부합하는 단일 페이지 애플리케이션
▪ MPA는 link tag를 통한 화면전환 방식을 가진 멀티페이지 애플리케이션
• [x] 3-1 SPA (Single Page Application) 와 CSR (Client Side Rendering) 은 같은 개념인가요?
◦ 답변
▪ 다르다. 포커스하는 것이 다름.
SPA는 ‘페이지 수’를 기준으로 MPA와 같이 사용할 수 있는 keyword,
CSR은 ‘렌더링 주체’ SSR과 같이 연결지어 말할 수 있는 키워드
▪ 모든 SPA가 CSR방식을 채택하지는 않는다.
• Next.js의 경우 SPA이지만, SSR을 사용한다.
• 첫페이지 렌더링은 서버에서 담당하지만 페이지는 하나이다.
• [x] 3-2 SPA 의 단점을 말하고, 해결하기 위한 방법에 대해서 말씀해주세요 lazy loading
◦ 답변
1. 초기 구동 속도
▪ 원인 모든 정적파일을 초기에 받기 때문에 발생
▪ 해결1 lazy Loading을 통해, 첫 화면에 필요한 파일들만 먼저 다운로드
해결2 스켈레톤 UI 등을 통한 최소 사용성 확보
2. 검색엔진 최적화(SEO)
▪ 원인 페이지의 meta태그 정보를 검색 엔진이 확인할 수 없다.
▪ 해결1 크롬 브라우저 자체 검색엔진 에서 처리하도록 함.
▪ 해결2 SSR방식의 혼합
3. 보안
▪ 원인 js 핵심 로직이 노출될 수 있다는 점
▪ 해결 client에서 핵심로직을 최소화하고, server에서 핵심로직 다루는 것
출처
https://m.mkexdev.net/374
• [x] 4 SEO(검색 엔진 최적화)는 무엇인가요?
◦ 답변
웹 브라우저에 URL 입력시 렌더링 전 까지의 과정에 대한 설명
답변
브라우저 이벤트감지 ⇒ DNS (도메인→IP) ⇒ ARP( IP ⇒ MAC) ⇒ TCP (3way)
마크업/스타일 로직과 컴포넌트의 기능로직을 ‘변경가능성’을 기준으로 두고 관심사 분리를 하려고 하였다.
스타일 로직은 자주 변경되기 때문에 사용자에게 역할을 넘겨 사용부의 외부로 위임,
바뀌지 않는 컴포넌트의 기능로직 부분은 추상화 하여, 컴포넌트 내부 로직으로 처리
상태관리/스타일 분리를 통한 관심사 분리의 초점에 대해 구체적으로 이야기 해주세요
댓글
변경가능성 기준으로,
변화가 자주 발생하는 스타일 코드는 사용하는 때에 따라 다르게 사용할 수 있도록 관여를 하지 않았고,
해당 컴포넌트가 반드시 가져야하는 상태는 추상화해보는 것으로 구현하였다.
(달력의 1주일이 7일이고, 일요일은 빨간색이다.)
스타일 이외의 UI 상태를 제어하기 위해 최소한의 인터페이스만을 열어두고자 하였는데,
dataSource, TableModel , FilterData 을 인자로 받고,
headerGroup과 rowModel을 API 로 제공한다.
Headless 컴포넌트를 어떻게 구현하셨나요?
답변
🟠 합성컴포넌트(Compound Component) 방식과 커스텀Hook으로 구현 가능
커스텀 Hook을 통해 구현
DataTable의 고유의 기능 고민
data를 정해진 Table모델에 맞추어 배치하여 테이블형태로 표현하는 것
부가기능으로 filter, search, sort등의 기능을 가짐
DataTable을 사용하기 위해서는 TableModel을 정해진 형식에 맞춰 입력해주어야 하고, 그 결과로 open된 api를 통해 구현부를 작성해줄 수 있다.
TableModel의 입력
label, accessor (data와의 연결을 위해 data객체의 key값을 받음)
cell, header는 Custom한 값을 cell에 표현하기 위한 optional한 프로퍼티
customHook의 open된 API의 interface와 사용방식
TableModel에 맞게 처리된 data를 headerGroups와 rowModel로 받게 되고, 해당 리스트를 순회하며 THeadCell과 TCell 내부에 render함수를 통해 값을 출력하도록 한다.
DX 측면에서 어떤 인터페이스 고민을 하셨나요?
답변
인터페이스는 결국 내부구현을 보지 않고서라도, 사용하는 쪽에서 쉽게 이해할 수 있는 것이 중요하다고 생각했고,
이러한 원칙을 지키기 위해 노력했다.
최소한의 prop을 받고, 최소한의 api를 제공한다
data, tableModel, filter query ⇒ tableModel과 filterQuery에 맞는 data만을 선별 후 Custom 적용 된 cell의 값들을 내려준다.
댓글
1) 인터페이스는 사용하는 쪽을 위한 것이고
2) 사용하는 쪽에서 인터페이스를 보고 어떻게 동작할지 예상 가능하여야 한다.
라는 원칙을 지키기 위해 노력
DataTable Hooks는 2개의 인자를 받는데, dataSource와 TableModel 이다.
그중 TableModel 이 dataTable을 표현하는 가장 중요한 객체이기 때문에,
TableModel의 interface에 무엇을 담아야하는가 고민을 많이 했고,
결과적으로
1) dataSource와의 연결을 위한 accessor
2) TableHead에 표현되는 값인 label
3) TableHead와 TableCell에 dataSource를 커스텀하여 사용할 수 있도록 하는 header, cell 을 기본 interface로 선정하였다.
ref
인터페이스
인터페이스는 사용하는 쪽을 위한 것이다.
컴포넌트를 사용하는 쪽에선 인터페이스를 보고 어떻게 동작할지 예상 가능해야 한다.
인터페이스는 외부와의 의존성을 만든다.
useModal Hook 구현
힌트
포인트
모달 사용부에서 해당컴포넌트와 모달 상태 관리를 위한 코드가 섞여서 가독성이 떨어지는 가장 큰 문제
⇒ 개선 이후 모달트리거의 이벤트핸들러를 통해 어떤 모달이 열리고, 제출 시 어떤 동작을 하는가를 props로 넘기도록 하여 직관적으로 이해되는 코드로 개선됨
모달은 열고닫는 상태,
모달트리거-모달 내부에 어떤 컴포넌트를 띄울 것인지 결정
모달 내부 컴포넌트 렌더링 부분을 어디에 위치 시킬 것인가
useModal 훅은 왜 만드신건가요? 어떤 역할을 하나요?
답변
학습측면 모달의 수가 많아지는 상황에서의
why 파편화된 모달 관리를 효율적으로 관리하기 위해서
how ContextAPI를 통한 모달 상태 중앙 관리
문제점
모달을 사용하는 부분에서, 각각의 개별 모달 상태를 관리
모달 관련 코드가 흩뿌려져 있어 모달의 동작을 예측하기 어렵다.
해결책
사용부의 개별 모달 상태 ⇒
1) Context API로 전역에서 열려있는 모달에 대한 정보를 상태로 관리하고,
2) 앱의 최상단에서 열려있는 모달을 전부 렌더링 하도록 함
전역상태 ⇒ openModals 상태 및 open, close와 같은 dispatch 함수
추가 개선사항
모달의 공통 로직은 중앙에서 처리
매번 모달컴포넌트를 import 하는 것이 아니라, 모달컴포넌트들을 중앙에서 객체로 맵핑하여 관리하고, 이름만으로 바로 사용할 수 있도록 개선
모달을 중앙화 해서 관리할 경우, 존재하는 모든 모달이 import 되는 이슈
lazy 로딩 적용하여, 모달이 열릴 경우만 import 하도록 개선
효과
모달을 열기위한 컴포넌트 내부의 state 관리를 외부에서 관리합니다.
파편화된 모달 컴포넌트를 Modals에 모아서 관리합니다.
모달을 닫아주기 위한 부분도 컴포넌트 내부에서 Modals 로 옮겨 개발자가 신경쓰지 않아도 닫히도록 처리합니다.
Lighthouse 기반 Performance 최적화
최적화 관련 수행했던 내용
포인트
번들 사이즈 최적화하여 TBT 지표 개선
차트의 높이를 미리 계산해서 CLS 지표를 개선
리렌더링 최적화
답변
bundle 사이즈 감소 ⇒ TBT 시간 감소
0) webpack-bundle-analyzer를 통해 현재 bundle 분석
1) webpack mode=production으로 설정하여 최적화
2) lodash에서 사용하는 함수만을 import 하도록 하는 트리쉐이킹
3) moment 라이브러리를 dayjs로 대체
차트의 높이를 미리 계산 ⇒ CLS 지표 개선
1) 차트를 로딩하는 동안 높이를 부여하지 못함
2.1) chart.js 라이브러리 문서에서 canvas요소가 2:1 의 비율을 가짐을 확인
2.2) 너비는 알고 있기 때문에 이를 통해 미리 wrapper 컴포넌트에 높이를 지정
2.3) Wrapper: width:100% , position: relative , padding-bottom: 50%[결과]
CLS = 0 으로 ≤ 0.1 이 되어 좋은 평가
리렌더링 최적화
[문제]
하나의 차트가 변화가 발생하여도, 병렬적인 다른 모든 차트가 리렌더링 되는 현상
[원인]
- 부모컴포넌트의 state가 바뀌면서 모두 리렌더링
[해결]
- React.memo는 props가 같다면 리렌더링 되는 것을 방지
[추가]
- useCalback
: 부모컴포넌트가 리렌더링 되며 하위컴포넌트로 보내는 props가 재생성 되는데, props는 얕은 비교를 하기 때문에 동일참조값이어도 새로운 값으로 판단하고 리렌더링 발생
useCallback을 통해, memoization된 함수 전달
- 함수형업데이트
: useCallback의 의존성 배열로 인하여, 부모 state가 변할 때 props함수가 재정의
: setState() 첫번째 인자를 통한 함수형 업데이트 사용하여 의존성배열 제거
디바운스를 통한 최적화
키보드 이벤트가 연속적으로 발생하는 상황에서 debounce 처리
Debouncing은 함수가 마지막으로 호출된 후 특정 시간까지 실행되지 않도록 해줍니다. 빠르게 발행하는 이벤트(예시 스크롤, 키보드 이벤트)의 응답으로 어떤 비싼 계산을 수행해야 할 때 사용하면 좋습니다.
성능 측정 기준/지표 에 대해서 설명
답변
라이트하우스는 6가지 지표를 가지고 측정
FCP (First Contentful Paint)
: 의미있는 컨텐츠 처음 표시까지 시각
: 2초 이내 인지 가능
SI (Speed Index)
: 뷰포트가 빠르게 채워지는 정도
LCP ( Largest Contentful Paint)
: 뷰포트의 가장 큰 영역이 로드되는 시간
: 2.5초 이내 표시
: <img>요소, 텍스트노드가 있는 블록요소 등 제한이 있음
TBI (Time To Interactive)
: 마지막 LongTask의 종료시점 까지의 시간
: 약 4초 이내
TBT (Total Blocking Time)
: LongTask의 메인스레드 점유로 인해 사용자 인터랙션이 차단된 시간의 합
: 0.3 초 이내
CLS (Cumulative Layout Shift)
: 레이아웃의 불안정한 변화의 정도
: 이동한 영역의 크기와 이동 거리의 곱으로 측정
: 0.1 이하
React의 memoization 방법에 대해서 설명해주시고, 언제 사용해야하나요?
답변
사용해야할 때
Context API 에서 Provider의 dispatch 함수들의 모음인 객체 값
컴포넌트 리렌더링 시, dispatch 함수는 항상 같지만 항상 새로운 참조가 생성되기 때문에 useMemo를 통해 memoization
계산 비용이 크고, 재사용될 가능성이 높은 값 useMemo
React.memo를 사용한 자식 컴포넌트에게 props를 넘겨줄 때 useCallback
debounce와 throttle의 차이점에 대해서 설명해주세요
답변
debounce는 연속된 함수호출이 있을 때, 마지막 호출된 함수
특정 시간이 지나기전 함수 호출되면, 이전 함수를 실행하지 않음
input에 대한 이벤트에 주로 사용
throttle은 실행횟수의 제한을 두는 함수
n초 동안 최대 1번만 실행되도록 제한을 두는 것
스크롤이벤트에 주로 사용
[2.2 경험]
특정 프로젝트에 기여한 내용
각 프로젝트에서 가장 어려웠던 부분 혹은 고민이 있다면?
Naver 인턴
프로젝트 설계는 어떻게 진행하셨나요?
힌트
과제분석 > 스택선정
컴포넌트 구조 설계 (Header, Overview, Widget)
interface 설계
[프로젝트 기여 내용]
답변
Lighthouse 기반 성능 개선
bundle 사이즈 감소
번들애널라이저는 무엇이냐
상세
로딩시간을 줄이기 위해 시도
0) webpack-bundle-analyzer를 통해 현재 bundle 분석
1) webpack mode=production으로 설정하여 최적화
2) lodash에서 사용하는 함수만을 import 하도록 하는 트리쉐이킹
3) moment 라이브러리를 dayjs로 대체
결과
총 3.98MB ⇒ 1.62MB로 감소
TBT 시간이 감소함
CLS 지표 개선
상세
CLS지표는 컨텐츠가 변화하여 얼마나 불안정한가를 나타내는 지표
[문제]
차트를 로딩하는 동안 높이를 부여하지 못함
[해결]
- chart.js 라이브러리 문서에서 canvas요소가 2:1 의 비율을 가짐을 확인
- 너비는 알고 있기 때문에 이를 통해 미리 wrapper 컴포넌트에 높이를 지정해준다.
- Wrapper: width:100% , position: relative , padding-bottom: 50%[결과]
CLS = 0 으로 ≤ 0.1 이 되어 좋은 평가
리렌더링 최적화
상세
문제]
하나의 차트가 변화가 발생하여도, 병렬적인 다른 모든 차트가 리렌더링 되는 현상
[원인]
- 부모컴포넌트의 state가 바뀌면서 모두 리렌더링
[해결]
- React.memo는 props가 같다면 리렌더링 되는 것을 방지
[추가]
- useCalback
: 부모컴포넌트가 리렌더링 되며 하위컴포넌트로 보내는 props가 재생성 되는데, props는 얕은 비교를 하기 때문에 동일참조값이어도 새로운 값으로 판단하고 리렌더링 발생
useCallback을 통해, memoization된 함수 전달
- 함수형업데이트
: useCallback의 의존성 배열로 인하여, 부모 state가 변할 때 props함수가 재정의
: setState() 첫번째 인자를 통한 함수형 업데이트 사용하여 의존성배열 제거
디바운스는 무엇이냐
실제 데이터 기반 개선 액션 useCase 3가지 제시
더 shallow 한 타겟을 찾아 집중 광고 집행 원할 때
특정 타겟에 대하여 잘 나가는 소재를 찾기를 원할 때
개선액션 지표는 클릭률과 전환률로 설정
[가장 어려웠던 부분과 해결과정]
답변
도움이 되는 리포트 만들기
기획팀과의 회의 ⇒ 단순 위젯 보여주는 것으로는 개선액션 이끌어내기 어려움
개발적인 부분
구현능력 자체가 부족했었다
chart.js 문서를 읽고, 필요한 기능 개발을 위해 주어진 인터페이스, API를 통해 드릴다운 필터링, 비교기능
라이브러리 사용의 장단점을 알게 되었다.
최적화 부분은 하나씩 원인을 찾아가며 해봤던 점이 흥미로웠고 재미있었다.
그래프는 어떤 라이브러리를 왜 사용했나요?
canvas와 svg 차이에 대해 아시나요?
답변
svg는 선언적
html 코드로 어떻게 그릴지 작성
벡터로 해상도에 따라 깨지지 않음
내부 css 동작
canvas는 드로잉 API
js를 통해 어떻게 그려야할지 명령형으로 작성
동양농산 프로젝트
[프로젝트 수행 내용]
답변
아버지가 운영하는 식자재마트 홈페이지 개발
JAMStack 적용하기 (Next + Strapi)
JAM Stack 이란?
답변
JAMStack은 ‘preBuiltPage’와 ‘재사용가능한 API’
를 통해 서버 없이 배포 및 운영되는 모던 웹 개발 구조 이다.
프로젝트 설계는 어떻게 진행했나요?
Next.js 를 사용한 이유가 있나요?
SEO를 위한 메타태그 지정은 어떻게 해주었나요?
[가장 어려웠던 부분과 해결과정]
Headless한 데이터 컴포넌트 개발
합성컴포넌트 패턴을 통한 Select 컴포넌트 개발
CheQuiz
[프로젝트 기여 내용]
퀴즈세트 생성 Form 구현
제어/비제어
성원님이 잘 설명해주셨는데요, 제어/비제어 방식이 갖는 장, 단점도 고려하셔야 합니다.
제어 방식의 경우 컴포넌트 state로 관리하고 항상 동기화가 이루어지기 때문에 복잡한 요구사항이 생기더라도 처리가 좀 더 쉬워집니다. 단점은 '동기화'에 대한 비용입니다. 만약 50개의 input이 있고 그걸 모두 제어 컴포넌트로 관리한다고 하면, 1글자만 쳐도 50개의 input이 모두 렌더링이 됩니다. 이런 경우에 useMemo 같은 별도의 최적화 작업이 필요해지며, 만약 form이 엄청 복잡한 구조(Array안에 Object안에 Array...)를 갖는 경우 골치가 더욱 아파집니다. 최근에 react-hook-form 라이브러리가 인기를 얻는 것도 이런 form 상태 관리를 성능 영향 없이 쉽게 처리할 수 있도록 구현한 덕분입니다.
비제어 방식의 경우 이벤트 핸들러(onChange, onBlur 등)로만 처리하기 때문에 제어 방식의 단점이 가진 "동기화 비용"이 0 입니다. 단점은 상태 동기화가 불가능하기 때문에 특정 요구사항 구현(ex: 다른 컴포넌트의 상태가 바뀌었을 때 해당 컴포넌트의 상태를 변경)이 어렵습니다. 실제로 서비스를 만들다 보면 다른 컴포넌트의 state에 의존하는 경우가 많아서 제어 방식으로 구현해야 하는 경우가 많이 생깁니다.
react-hook-form 라이브러리의 경우 특이하게 비제어 방식을 사용하되, state가 아닌 ref를 사용해서 컴포넌트를 제어합니다. 제어 컴포넌트의 단점인 성능 이슈를 다른 방법으로 해결한 것이죠. ref를 input에 매핑해서 처리하면 브라우저 화면의 DOM을 직접 수정하기 때문에 다른 React 컴포넌트에 불필요한 리렌더링이 일어나지 않는 장점이 있습니다. 뿐만 아니라 에러 처리, 써드파티 라이브러리와의 연동, 에러 발생 시 해당 input 자동 포커스 기능 등 흔히 개발자들이 맞닥뜨리는 케이스들을 구현해놓아서 도입을 고려해보시는것을 추천드립니다.
block : 부모 컨테이너 너비만큼 채움 + 새로운 줄에서 시작, 옆에 HTML 요소 불가
inline : 내용만큼 너비 가짐 + 다른 컨텐츠 옆에 존재 가능
margin, padding 사용 불가
inline-block inline과 달리 width, height, margin, padding 지정 가능
기타
table
position 속성은 무엇인가요
답변
static : 기본 속성
relative - absolute : relative 를 기준으로 absolute 요소가 위치함
fixed : 요소는 해당 위치가 아닌 뷰포트를 기준으로 배치 (스크롤 시 미이동)
padding과 margin의 차이
답변
margin은 대상 요소의 외부여백을 의미하고, padding은 대상요소의 내부 여백을 의미합니다.
selector의 종류와 차이
답변
id와 class의 차이는, 유일한 요소를 지정할 때에는 id속성을 사용하고, class는 복수의 요소에 적용할 때 사용한다는 점입니다.
(* id의 우선순위가 class 보다 높다)
flex 와 grid를 통한 레이아웃의 차이
답변
👨🏽💻
[flex]
flex는 레이아웃을 편하게 잡기 위한 css의 속성으로단방향 레이아웃 설계에 강점이 있습니다.
flex는 플렉스 컨테이너라는 부모요소와 플렉스아이템이라는 자식요소를 가지고, 메인축을 지정하여 수평, 수직 정렬을 구현합니다.
flex는 요소의 크기가 불분명하거나, 동적인 경우에도 요소를 효율적으로 정렬할 수 있다는 장점이 있습니다.
[grid]
flex가 단방향 레이아웃 설계라면 그리드는 2차원의 두방향 레이아웃 시스템입니다.
grid-template-columns, rows 속성을 통해 각 행과 열의 아이템 개수와 비율을 지정할 수 있으며
row-gap, column-gap 속성을 통해 각 행과 열 사이의 간격을 지정할 수 있습니다.
CSS의 박스모델이란
답변
CSS 박스 모델은 문서 트리의 요소에 대해 생성되고 시각적 포매팅 모델에 따라 배치된 사각형 상자를 나타냅니다. 각 박스에는 content 영역(예: 텍스트, 이미지 등)과 padding, border, margin 영역을 선택적으로 사용할 수 있습니다.
CSS 박스 모델은 다음을 계산합니다.
블록 요소가 공간을 얼마나 차지하는지.
테두리 또는 여백이 겹치거나 충돌하는지 여부.
박스의 크기.
박스 모델에는 다음과 같은 규칙이 있습니다.
블록 요소의 크기는 width, height, padding, border, margin에 의해 계산됩니다.
height 가 지정되어있지 않으면, 블럭 요소는 포함하고있는 내용만큼의 높이를 가질 것이고, padding을 더합니다.(float가 아닌경우).
width 가 지정되지있지 않으면, float가 아닌 블록 요소는 [부모의 너비-padding]에 맞게 확장됩니다.
요소의 height는 내용의 height에 의해 계산됩니다.
요소의 width는 내용의 width에 의해 계산됩니다.
기본적으로, padding과 border는 요소의 width와 height의 일부가 아닙니다.
box-sizing: border-box 옵션은?
기본적으로, 요소들에 box-sizing: content-box가 적용되면, 내용의 크기만 고려됩니다.
리디에서는 컴포넌트를 5단계가 아니라 atom, block, pages의 3단계로 나눈다고 한다. 이렇게 되면 pages부터 시작된 prop이 atom까지 4단계가 아닌 2단계로 끝날 수 있어서 props drilling issue를 예방할 수 있을 것 같다.
그리고 컴포넌트는 각각의 디렉토리를 가지고 index.tsx로 최상위 컴포넌트를 반환한다. index.tsx는 container 컴포넌트의 역할을 하게해서 오직 로직만 남기고 presentational 컴포넌트와 분리한다.