이 글은 아래에 첨부되어 있는 글의 한글 번역입니다. 오역이 들어 있을수 있습니다.
만약 프론트엔드 면접을 준비하고 있고 프론트엔드 도메인 지식을 빠르게 refresh 하고 싶다면 이 cheatsheet는 많은 시간을 아껴줄 것입니다.
목차
Intro
Web Knowledge
1.Caching
2.HTTP/2
3.Security
Web Performance
1.Critical rendering Path
2.Reflow
3.preload,preconnect,prefetch,prerender
4.Rendering Performance
5.Workers
6.Image Optimization
DOM
1.Elements
2.Manipulation
3.Document Fragment
4.Event delegation and bubbling
HTML
1.Semantic Elements
2.Accessibility
3.Responsive web
Javascript
1.this
2.Closure
3.Inheritance
4.Asynchronous Javascript
5.Hoisting
6.Currying
7.Higher-order functions
Design patterns
1.Mixin
2.Factory
3.Singleton
4.Facade
5.MVC,MVVM
6.Server vs Client-Side Rendering
Conclusion
You are Awesome ❤️
Learn More
Intro
물론 모든 프론트엔드 지식을 하나의 글에 담기에 공간은 충분하지 않습니다. 그리고 이것은 이 cheatsheet가 이루고자 하는 바가 아닙니다. 이것은 단지 시니어 프론트엔드 엔지니어들은 친숙해야하는 frontend 주제의 지름길일 뿐입니다. 이것들은 인터뷰에서 자주 언급되었고 아마존과 링크드인으로부터 오퍼를 받을수 있게 도와주었습니다. 재밋게 읽으시고 주제의 링크를 클릭함으로써 깊게 들어가는 것에 주저하지 마세요🙌
Web Knowledge
1. Caching
- Cache-Control: 요청 및 응답 캐시 명령
- Etag: <cache_id> 를 비교하여 리소스가 업데이트 되었는지 확인합니다. 업데이트 되지 않은 경우 cached된 버전을 업데이트 합니다.
2. HTTP/2
장점
- 복수의 HTTP 연결 요청(HTTP/1 은 오직 6개만 지원함)
- 서버에서 클라이언트에게 이벤트를 보낼수 있다.(SSE:Server Sent Event)
- 압축된 headers
- 더 안전함
단점
- 서버 요청이 남용될수 있다.
- LoadBalancer가 HTTP/1을 지원하고 server는 HTTP/2를 지원하면 느려질 수 있다.
3. Security
- Transfer-Encoding - body를 어떻게 암호화할건지 정한다: chunked, gzip => (헤더의 한종류)
- Access-Control-Allow-Origin(Cross-Origin Resource Sharing -- CORS) : origin domain의 API에 접근할수 있는 도메인 리스트들을 정의해 놓는다
- JSONP - 도메인 간 데이터에 접근하기 위한 스크립트 실행
- X-Frame-Options - iframe으로부터 clickjacking을 예방한다.
- Cross-Site Request Forgery(CSRF) - 사용자는 세션을 가지고 있고, 공격자는 link를 생성한다, 사용자는 링크를 클릭하고 요청을 수행한다, 공격자는 사용자의 세션을 강탈한다. 예방법: captcha, 방문한 사이트로부터의 로그아웃
- Content-Security-Policy - 해로운 코드의 실행을 예방한다.
- X-XSS-Protection - 오래된 사이트를 위해 XSS 보호가 가능하게 한다.
- Feature-Policy - 브라우저 기능에 필요하지 않은것들은 disable 한다
- Referrer-Policy - 다른 사이트로의 링크가 있을때 링크를 클릭함으로써 중요한 데이터를 포함할수 있는 URL의 origin을 보낼 것이다.
- 사용자에게 HTML 넣는것을 허락하지 않는다 (innerHtml)
- UI 프레임워크를 사용하고 node_module들의 업데이트를 계속 유지하고 서드파티의 사용을 제한한다.
Web Performance
1. Critical Rendering Path - 브라우저가 페이지를 그리는 단계. 그 단계들은
- DOM - 브라우저는 Document Object Model을 컴파일 합니다.
- CSSOM - 브라우저는 CSS Object Model을 컴파일 합니다.
- Render Tree - 브라우저가 DOM 과 CSSOM을 결합하여 tree를 렌더합니다.
- Layout - 브라우저가 각 object들의 위치와 크기를 계산합니다.
- Paint - 브라우저가 tree를 화면의 pixel로 변환합니다.
CRP 최적화
- 소스 순서를 최적화 합니다. -- 중요한 리소스를 가능한 빨리 로드합니다.
- 소스의 수를 최소화 합니다. -- 숫자를 줄이고 비동기를 사용합니다.
2. Reflow - 브라우저는 렌더후에 각 요소들의 위치와 구조를 다시 계산합니다.
Reflow 최적화
- DOM의 뎁스를 줄입니다.
- 긴 CSS 선택자를 피하고 규칙을 최소화 합니다
3. preload, preconnect, prefetch, prerender
- preload - 더 빠르게 로드되어져야할 필요가 있는 우선순위가 높은 소스들을 load 합니다. <link rel="preload">
- preconnect - handshake를 가속화 해야할 필요가 있는 리소스들이 있다면 대기시간을 줄이기 위하여 <link rel="preconnect">를 사용합니다.
- prefetch - 낮은 우선순위의 리소스들을 불러오고 캐시를 사용합니다. <link rel="prefetch">
- dns-prefetch - 리소스를 요청하기 전에 도메인 이름 확인하는 대기시간을 줄이기 위해 사용합니다.<link rel="dns-prefetch">
- perrender - prefetch와 비슷하고 전체 페이지를 cache 하기위해 사용합니다. <link rel="prerender">
4. Rendering Performance
JS:
- 무거운 동작들은 Web worker로 수행합니다.
- animation을 수행하기위해 setTimeout 대신 requestAnimationFrame을 사용합니다.
Style:
- 선택자의 복잡성을 줄입니다.
- 계산을 필요로 하는 스타일을 사용하는 요소들을 줄입니다.
Layout: (어떻게 요소들이 위치되어지고 크기를 이루는지)
Paint: (픽셀 그리기: 색상, 그림자, 레이아웃의 변경은 repaint를 불러온다)
- layout repaint를 최적화하기 위해 will-change를 사용합니다.
5. Workers
- Service Worker - 오프라인 app을 만들기 위한 도구
- Web Worker - 백그라운드에서 무거운 동작들을 수행한다.
6. Image Optimization
Format:
- 만약 animation이 있다면 - gif대신 <video>태그를 사용하세요
- 만약 높은 디테일과 해상도가 있다면 - PNG
- 기하학적 형태가 필요하다면 - SVG
- text 로고가 있다면 - font text
- 사진이 있다면 - JPEG
Compression:
- SVG - SVGO와 같은 최적화 도구를 사용하고 gzip을 사용하세요
- WebP - 웹을 위해 최적화된 image format을 사용하세요
- SVG 태그로부터 metadata 속성을 지우세요
- Sprites를 사용하세요
Cache and Lazy Load:
- 정적 데이터의 제공을 위해 CDN을 사용하세요
- image와 비디오의 Lazy Load를 사용하세요 - <img loading="lazy" />을 사용하거나 lazysizes 같은 라이브러리를 사용하세요
DOM
1. Elements:
- selector: getElementById, getElementByTagName, querySelector, querySelectorAll
- navigation: children(elements), childNodes(nodes), firstElementChild, lastElementChild, parentElement, previousElementSibling, nextElementSibling;
- attributes: classList, clientHeight, clientWidth, childElementCount, setAttribute(attrName, value), removeAttribute(attrName)
2. Manipulation:
createElement('div'), append, prepend, el.cloneNode(true), remove(), insertBefore(newNode, beforeNode), insertAfter(newNode, afterNode);
3. Document Fragment - 복수의 요소를 가질수 있는 document의 가상의 복제본을 만든다. document fragment를 DOM에 넣어줌으로써 단 한번의 reflow만 실행시킬수 있다.
4. Event delegation and bubbling:
- 클릭과 같은 이벤트를 발생시킬때 parentElement를 통해 <html>까지 bubbling 되어진다.
- html (bubble click) -body (bubble click) -div (bubble click) -p -p (click)
- 위임은 성능의 증가를 위해 사용한다. 아래와 같은 구조가 있다고 가정해보자
-div.parent
-p.child
-p.child
-p.child
우리는 .child에 addEventListener을 할당하고 싶다. 이러한 경우 3개의 요소에 이벤트를 붙여야 하는데, 대신에 .parent에 이벤트를 붙여서 로직을 해결할 수 있다
document.querySelector(".parent").addEventListener("click",
function(event) {
if(event.target.classList.contains("child")){
// your logic is here
};
}
);
HTML
1. Semantic Elements - 이름과 함께 의미를 명확하게 개발자와 브라우저에게 나타낼수 있다: article, aside, details, figcaption, figure, footer, header, main, mark, nav, section, summary, time
2. Accessibility
- 헤더태그를 사용한다 <h1>, <h2>, <h3>
- <img alt="" 를 사용한다
- Tab키를 이용해 focus를 이동시킬때를 위해 tabindex="index_position" 속성을 사용한다.
- roles를 사용한다. <ul role="list"><li role="listitem">, <dialog role="dialog"와 같이. 모든 리스트는 이곳에서 찾을수 있습니다.
- accesskey="key"를 사용한다. 키보드 단축기 생성을 위해
- 요소들을 나타내기 위한 속성들을 사용한다: aria-label="label_text" 혹은 aria-labelledby="text_id", aria-describedby="text_id" 그리고 <label id="text_id">label_text</label>
- 색깔의 대비와 질감을 사용한다.
- text size를 사용한다
- video에서 caption을 사용한다
3. Responsive web
- <meta viewport name="viewport" content="width=device-width, initial-scale=1.0">을 추가한다. 브라우저의 확장 방향을 알려주기 위해
- <img max-width="100%">를 사용하면 이미지는 해당 이미지의 크기보다 더 커지지 않을 것이다.
- <picture><source srcset="" media="">를 사용한다. 화면 크기 별로 다른 이미지를 명확히 해주기 위해서
- 반응형 font size들을 사용한다: em 과 rem
- media query들을 사용한다
Javascript
1. this
- this는 함수가 호출되는 객체의 참조입니다.
- this의 default는 window 입니다.
- 함수가 호출된 곳에서 context를 가져옵니다.
- 화살표 함수 -> 는 함수가 정의된 곳으로 부터 context를 가져옵니다.
- this는 다른 함수 안에서 함수를 호출할때 context를 잃어버립니다.
function Foo() { console.log(this); } Foo(); // at this line the context is 'window' // output 'window' var foo1 = new Foo(); // at this line the context binds to 'foo1' // output 'Foo {}'
- this context의 명확한 할당: foo1.apply(context, arrayOfArgs), foo1.call(context, arg1, arg2, ...), var foo2 = foo1.bind(context, arg1, arg2, ..) --- 주어진 context와 함께 함수를 반환해 줍니다.
2. Closure - 다른 scope에서 호출되었을 지라도 scope를 기억하고 접근할 수 있는 기능(함수가 block scope 내에서 function을 반환한 경우)
function a(arg1) { // arg1 scoped
var arg2 = 0; // arg2 scoped
return function b() {
++arg2;
return arg1 + arg2
}
}
var foo = a(2);
foo(); // 2
foo(); // 3
var foo2 = a(4);
foo(); // 4
foo(); // 5
3. Inheritance
- obj2로 부터 ob1을 상속받기 위해 object와 다른 object를 연결지을수 있다. var obj1 = Object.create(obj2);
- JS는 프로토타입 상속을 사용한다. 각각의 Object는 __proto__ 를 가진다. 만약 우리가 object의 속성에 접근한다면 Js 엔진은 해당 객체가 속성을 가지고 있는지 체크하고 만약 가지고 있지 않다면 프로토타입을 확인한다. 해당 속성을 찾으려고 계속 __proto__ 연결을 통해 접근하고 만약 정의되어 있지 않다면 undefined를 반환한다.
- Event loop: JS에는 세 형태의 메모리가 있다: 함수 호출을 위한 stack, 객체들을 위한 heap, setTimeout을 위한 queue, Js 엔진은 stack의 함수를 첫번째로 실행하고 만약 stack이 비었다면 queue로 부터 이벤트를 pop 한다. 만약 queue의 이벤트가 함수의 호출이 필요하다면 이것을 stack에 담고 이 과정을 queue가 비어질때까지 실행한다. 이것을 event loop라 부른다.
- Js는 callback, promise, async-await을 비동기 동작을 수행하기 위해 사용한다. 아래의 글에서 좀 더 많은것을 확인할 수 있다.
https://itnext.io/the-evolution-of-asynchronous-patterns-in-javascript-64efc8938b16
5. Hoisting
- Js 컴파일에서 function 정의는 block scope의 최상단으로 이동한다, 그 후에 var가 위치된다.
- let과 const도 hoisting 된다 하지만 temporary dead zone에 위치한다
// Code example // After hoisting
1. console.log('hoisting'); 1. function foo() {
2. var a; 2. return null;
3. function foo() { 3. }
4. return null; 4. var a;
5. } 5. console.log('hoisting');
6. a = 5; 6. a = 5;
6. Currying - 중첩된 함수들
function calcABC(a) {
return function(b) {
return function(c) {
return a + b + c;
}
}
}
console.log(calcABC(1)(2)(3)); // 6
- map, reduce, filter, find
- Higher-order 함수들을 연결지을수 있다.
[1,2,3,4,5].map((num) => ({age: num})).filter((el) => el.age < 4); // [{age: 1}, {age: 2}, {age: 3}]
Design patterns
1. Mixin - 함수의 기능을 확장한다.
// Option 1
class Person {}
let Mixin = {foo(){}};
Object.assign(Person.prototype, Mixin);
let person = new Person();
person.foo();
// Option 2
let Mixin1 = {foo1(){}};
let Mixin2 = {__proto__: Mixin1, foo2(){}};
2. Factory - 하나 혹은 다른 여러개의 객체들을 생성할 수 있는 class(단위 테스트에서 다른 mock 데이터를 생성하고 싶을때 유용하다)
personFactory.one({name: 'John'}); -> Person{name: 'John', age: 5}
personFactory.many(); -> [Person{name: 'Bill', age: 7}, Person{name: 'Anna', age: 3}]
3. Singleton -- 객체의 생성 없이 함수를 직접 불러올수 있는 class
let mySingleton = (function(){
let instance = null;
function init() {
return {
// list all the methods
method(){};
}
}
if (instance === null) {
instance = init();
}
return instance
})();
mySingleton.method();
4. Facade - 복잡한 로직을 추상화 시키고 이걸 class로 감싼다, 예를들면 component와 API layer 사이에 있는 서비스
ui component - Facade service (complex state object) - API layer(Redux);
5. MVC, MVVM -- Model Viw Controller, Model View ViewModel
React는 MVC
- state - Model
- JSX - View
- actions(위반시 view와 섞일수도 있다) - Controller
Angular는 MVVM
- component -- ModelView
- template -- View (위반시 재사용 불가)
- properties -- Model
6. Server vs Client-Side Rendering
SSR - 사이트가 안정적이고, 정적이고, SEO에 초점을 두고 있고 추가 서버를 결제할 수 있다면 SSR을 사용하라
장점
- 빠른 page 로드(보이는 건 가능하지만 동작은 안한다)
- 검색엔진에 더 좋다(빠른 인덱싱)
- 정적 콘텐츠가 많은 사이트에 더 좋다(블로그들)
단점
- 서버 요청이 더 많다
- interact를 위한 render가 느리다
- 전체 페이지가 reload 된다.
CSR - 사이트가 개발중에 있고 동적이라면 CSR을 사용하라
장점
- 초기 로드 후에 렌더가 빠르다
- web app에 좋다
단점
- 초기 로드에 시간이 많이 소요된다
Conclusion
big tech 대기업의 프론트엔드 면접을 통과하기 위한 자신감을 가지기위해 개발자가 알아야할 필요가 있는 지식은 매우 많다.
비록 코딩 문제와 시스템 디자인으로 구성된 더 복잡한 라운드가 있을지라도 웹 관련 질문들을 해결하기 위해 프론트엔드 도메인 지식은 중요합니다.
'Frontend > Javascript' 카테고리의 다른 글
innerHTML, insertAdjacentHTML, textContent, innerText (0) | 2022.03.01 |
---|---|
🔥Javascript questions (0) | 2022.02.28 |
🔥 System Design Concepts that Helped Me Get Sr Frontend Offers From Amazon & LinkedIn (번역글) (0) | 2022.02.27 |
js + cypress (0) | 2022.02.23 |
var, let, const (0) | 2021.11.10 |