안녕하세요. 꼬동입니다.
해당 글을 번역한 글입니다.
FE 면접을 준비 중이라면, 면접 전 해당 글을 보시면, 많은 시간을 줄일 수 있을거에요.
Intro
물론 하나의 글에 FE의 방대한 지식을 담을 수 없지만, 족보로서 충분한 역할을 할 수 있을거라고 생각합니다.
토픽들을 모아모아서 적는 글이라고 생각하시면 될거 같네요. 아마 시니어 FE 개발자라면, 다 친숙한 내용이 될거 같습니다.
Web knowledge
1. 캐싱 (Caching)
- Cache-Control
- HTTP 캐시를 효율적으로 관리하기 위한 헤더 (https://toss.tech/article/smart-web-service-cache)
- Etag
- 캐시 ID(cahce_id). cache_id를 체크하여 리소스가 같은지 아닌지 비교한다. 다르면, 캐시 버전을 업데이트한다.
2. HTTP
- HyperText Transfer Protocol
- 웹에서 정보를 주고받을 수 있는 프로토콜
- HTTP/1.1
- Connection당 하나의 요청을 처리 하도록 설계 (동시전송이 불가) 덕분에 Latency(대기 시간)이 길어짐. connection당 하나의 요청처리를 개선하기 위해 pipelining을 적용. 어느 정도 성능개선 했지만 Head of Line Blocking이라는 문제 발생. 이러한 단점을 해결하기 위해서 icon image들을 한 곳에 모아서 전송을하고, CSS/Javascript를 minify하고, 스타일시트를 HTML 문서 상위에 배치 / 스크립트를 HTML 문서 하단에 배치했다. 허나 근본적인 문제는 해결하지 못 함.
- HTTP/2
- HTTP/1에서 성능을 개선한 프로토콜 / 하나의 connection에서 응답 순서에 상관없이 stream을 주고 받는다. (pipeline의 개선) / 우선순위 stream 가능 / 서버에서 클라이언트의 요청에 대해 리소스를 마음대로 보낼 수 있음 (이는 때로 문제가 된다) / 헤더 정보 압축 가능
- 참고로, 포트번호가 정해지지 않으면, 자동으로 80이 부여된다.
3. 보안
- Access-Control-Allow-Origin (Cross-Origin Resource Sharing - CORS)
- origin domain의 API에 접근할 수 있는 도메인 목록을 정의 (https://evan-moon.github.io/2020/05/21/about-cors/)
- Transfer-Encoding
- 본문 인코딩 암호화 방법을 지정하는 것
- innerHtml을 유저가 사용할 수 없도록 합시다. (https://til-devsong.tistory.com/101)
- UI 프레임워크를 사용하고, node_modules를 꾸준히 업데이트하고 서드파티 서비스의 사용을 제한하자
- Cross-Site Request Forgery (CSRF)
- 공격자가 사이트 요청 위조 (https://namu.wiki/w/CSRF) / 방어 방법 : Referrer 검증, CSRF Token 사용, CAPTCHA 사용
4. 웹 퍼포먼스
- 웹 렌더링 순서 : 브라우저가 page를 그릴 때 순서를 알아보자 (https://d2.naver.com/helloworld/59361)
- DOM
- Browser가 Document Object Model을 컴파일
- CSSOM
- Browser가 CSS Object Model을 컴파일
- Render Tree
- Browser가 DOM과 CSSOM을 결합해서 tree를 render
- Layout
- Browser가 각 object의 size와 position을 계산
- Paint
- Browser가 스크린에 tree를 convert하여 그림
- 웹 렌더링 최적화 하기
- 중요한 리소스를 가능한 빨리 load하기, 리소스 수를 가능한 줄이고, 비동기적으로 로드하기
- Reflow
- Browser가 elements의 position과 geomeries를 재계산하는 것
- Reflow 최적화 하기
- DOM depths를 줄이기, 긴 CSS selector들을 줄이고, 규칙을 최소화하기
- preload, preconnect, prefetch, prerender
- preload : 더 빨리 로드해야하는 우선 순위 리소스를 loads <link rel="preload">
- preconnect : 만약 handshake를 먼저 하고 싶은 리소스들이 있다면, preconnect를 사용해서 지연시간을 줄인다. <link rel="preconnect">
- prefetch : 낮은 우선순위 리소스를 load하고 캐싱 <link rel="prefetch">
- prerender : prefetch에 전체 페이지를 캐싱 <link rel="prerender">
- 렌더링 성능
- JS : heavy task를 web worker에 옮기기, animation을 수행하기 위해선 requestAnimationFrame을 setTimeout 대신 사용하기
- Style : 복잡한 selector 줄이기 / Style을 적용하는 elements 수를 줄이기
- Layout : layout 변경 줄이기, flexbox 사용, css-grid 사용 (https://d2.naver.com/helloworld/8540176)
- Paint : layout repaint를 하기 위해 will-change를 사용하기
5. Workers
- Service Worker
- 오프라인 앱을 구축하기 위한 interceptor
- Web Worker
- background 환경에서 heavy한 task를 수행 (https://www.zerocho.com/category/HTML&DOM/post/5a85672158a199001b42ed9c)
6. Image 최적화
- Format
- animation을 쓰면 gif 대신 <video> 태그 / 높은 해상도와 디테일을 원하면 png / 기하학적인 모양을 원하면 svg / text logo를 원하면 font size / 사진을 원하면 jpeg를 쓰자
- 캐시와 Lazy Loading
- 정적 데이터 배포를 위해서 CDN을 쓰자 (https://cwangg897.tistory.com/93) / image와 video는 Lazy Loading을 이용하자. 예를들어 <img loading="lazy" /> 또는 lazysizes와 같은 라이브러리를 사용 (https://helloinyong.tistory.com/297)
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), removeAttribute(attrName)
- DOM Node와 Element 차이 (https://stackoverflow.com/questions/132564/whats-the-difference-between-an-element-and-a-node-in-xml / https://talkwithcode.tistory.com/24)
2. Manipulation
- createElement('div'), append, prepend, el.clonNode(true), remove(), insertBefore(newNode, beforeNode), insertAfter(newNode, afterNode)
3. Document Fragment
- 여러 elements를 메모리에만 정의한 Document, 실제로 DOM Tree에는 영향을 주지 않으며, inserting 하게되면, reflow를 야기한다. (https://7942yongdae.tistory.com/70) / createElement("div")와는 다름
4. Event delegation and bubbling (https://joshua1988.github.io/web-development/javascript/event-propagation-delegation/)
- event를 emit하면 (ex. click) 이벤트는 <html>까지 bubbling이 됩니다. parentElement를 통해서요.
-html (bubble click)
-body (bubble click)
-div (bubble click)
-p
-p (click)
- delegation은 성능을 향상시키기 위해서 사용됩니다. 아래와 같은 구조가 있다고 쳤을 때,
-div.parent
-p.child
-p.child
-p.child
여기서 .child에 addEventListener를 할당한다고 합시다. 이러면, 3개의 elements에 전부 eventListener를 붙여야하는데, 당연히 더 좋은 방법이 있겠죠. .parent elements에 event를 붙여봅시다.
document.querySelector(".parent").addEventListener("click", function(event) {
if (event.target.classList.contains("child")) {
// logic
};
});
HTML
1. Semantic Elements
- 브라우저와 개발자를 위해서 의미를 명확하게 정의하여 이름을 정한 것 (ex. <body> / <header> / <footer> / <aside> / <details> / <section> ...) (https://webdir.tistory.com/310)
2. Accessibility
- header <h1> <h2> <h3> 사용
- <ing alt=""> 사용
- tab 키로 포커스를 이동하려면 tabindex="index_position"
- role을 사용하자
- 단축키을 만들기 위해선 accesskey="key"를 사용하자.
- element를 설명하려면 aria-label="label_text" 또는 aria-labelledby="text_id", aria-describedby="text_id" <label id="text_id">label_text</label>과 같은 attribute를 쓰자
3. Responsive web
- <meta viewport name="viewport" content="width=device-width, initial-scale="1.0" 태그로 browser에게 scale 정보를 주자
- <img max-width="100%"를 사용하면 image가 자체 크기보다 커지지 않는다.
- em / rem을 사용하여 반응형 폰트 사이즈를 사용 (http://triki.net/prgm/3250)
- media query를 사용 (https://offbyone.tistory.com/121)
JavaScript
1. this
- this는 함수가 불린 곳에서의 object 참조자이다.
- 기본 this context는 window이다. (https://ggodong.tistory.com/244) 내 글이니까 강조 ㅎㅎ;;
- context (호출된 위치에서 함수를 가져오는 것)
- arrow function (함수가 정의된 곳에서 context를 가져옴)
- this는 한 함수 안에서 다른 함수를 호출하면 사라진다.
function Foo() {
console.log(this);
}
Foo(); // 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 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로부터 obj1을 상속 받기 위해서 var obj1 = Object.create(obj2); 로 가능하다.
- JS의 경우엔 prototype inheritance를 사용한다. 각각의 object는 __proto__를 가지는데, 만약 우리가 object의 property에 접근한다고 할 때, JS Engine의 경우 해당 object가 property를 가졌는지 확인하고, 그게 아니라면 __proto__ chaining을 통해 property 이름을 찾고, 그래도 찾지 못하면 undefined를 뱉는다.
4. Asynchronous Javascript
- Event loop
- JS에서는 3가지 타입의 메모리가 있는데, stack / heap / queue가 있다.
- stack : function call을 위해 사용
- heap : object들을 위해 사용
- queue : setTimeout을 위해 사용
- JS engine은 stack의 함수를 먼저 실행합니다. 만약, 비어있다면, queue에서 event를 꺼내서 실행합니다. 만약 event queue가 다른 함수를 가지고 있다면, 이를 stack에 push를 하고 이를 반복합니다. 이를 event loop라고 부릅니다.
- JS는 비동기 처리를 하기 위해서 callback, promise, async-await를 사용합니다. (https://itnext.io/the-evolution-of-asynchronous-patterns-in-javascript-64efc8938b16)
5. Hoisting
- JS 컴파일 단계에서 함수 정의가 block scope의 최상단에 올라가는 것을 말함.
- 실행 컨텍스트 생성 시, 렉시컬 스코프 내의 변수 선언이 끌어올려지는 것이 호이스팅
- let과 const는 호이스트 되긴하지만 Temporary Dead Zone에 존재함. (https://noogoonaa.tistory.com/78)
6. Currying (Nested functions)
function calcABC(a) {
return function(b) {
return function(c) {
return a + b + c;
}
}
}
console.log(calcABC(1)(2)(3));
7. High order functions
- map, reduce, filter, find
- 이를 이용해서 chaining을 할 수 있다.
[1,2,3,4,5].map((num) => ({age: num}).filter((el) => el.age < 4);
디자인 패턴
디자인 패턴의 경우엔 추후에 정리를 하겠습니답. 언제 할 진 모릅니다. 엘든링 해야하거든요.
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가 하나 이상의 다른 객체들을 만들 수 있는 것
personFactory.one({name: 'John}); => Person(name: 'John', age: 5}
personFactory.many(); => [Person{name: 'Bill', age: 7}, Person{name: 'Anna', age: 3}]
3. Singleton
- object를 만들지 않고, 직접 메소드를 호출하는 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에 감싸는 것. 예를 들어 API layer와 component 사이를 서비스로 구분하는 것
ui component - Facade service (complex state object) - API layer (Redux);
5. MVC, MVVM
- Model View Controller and Model View ViewModel
- React은 MVC
- state = model
- JSX = View
- actions = Controller (view와 섞일 수 있음)
- Angular는 MVVM (요거는 말이 좀 많군요. https://stackoverflow.com/questions/35762515/is-angular2-mvc)
- component = ViewModel
- template = View
- properties = Model
- 둘과의 전쟁 (https://medium.com/javascript-scene/angular-2-vs-react-the-ultimate-dance-off-60e7dfbc379c)
6. Server vs Client Side Rendering (https://hyothorhyo.tistory.com/m/19)
- SSR
- 사이트 정적이면 SSR을 사용
- 장점 : page load가 빠르다. (상호작용을 하진 못함) / 검색 엔진에서 찾기 좋다. (indexing이 빨라서) / 정적 컨텐츠를 많이 넣을 수 있어서 좋다.
- 단점 : 서버 request가 많다 / 상호작용을 위한 render가 느리다 / Full page reload이다.
- CSR
- 동적으로 개발된 site
- 장점 : initial load를 하면 빠르다. / web app에 좋다.
- 단점 : initial load 하는데 시간이 필요하다.
- 꼭 그렇다고 SSR만 SEO에 좋다고 표현할 수 없는게, 구글의 경우엔 JS를 지원하기 때문에 CSR에서도 SEO 최적화가 되어있다. 네이버는 아직 안되는지 SSR을 권장하는 중.
이상 프론트엔드 면접 때 꼭 알아야하는 것였습니다. ^_^
'개발 상식' 카테고리의 다른 글
스터디 첫 모임 (2) | 2021.10.02 |
---|---|
LIS / LIS 역추적 발표 자료(pdf) (0) | 2021.09.29 |
객체지향의 사실과 오해 (1) (2) | 2021.08.15 |
OOP (0) | 2021.03.14 |
Top Down vs Bottom Up (0) | 2020.06.02 |