(면접준비) 브라우저/ 네트워크/ 보안

devAnderson·2022년 3월 14일
0

TIL

목록 보기
72/103
  • 브라우저의 랜더링 과정
  1. UI 프로세스에서 해당 URI를 분석해 이것이 검색어인지 아니면 DNS 주소인지 파악한 후, 검색요청이라면 해당 서버의 검색쿼리를, DNS 주소라면 브라우저캐시 -> 라우터 캐시 -> IP CDN 서버 캐시 등을 타고올라가 해당 DNS 네임과 연동되는 IP 주소를 찾아낸다. 이후 해당 서버에 요청을 진행한다.

  2. Backend Time에서 http요청을 통해 index.html 문서와 같은 리소스들을 받아온다. ( TCP 3 hand shake로 미리 연결되어 있는 상태. Http 2.0부터는 html 문서의 파싱이 완료되어 문서 내의 필요한 리소스 요소들을 다 받아오기 전까지는 해당 연결이 끊어지지 않고 유지된 상태다)

  3. 초기 html은 바이트 형태로 변환되어 전송된다. ( 10101011110 ). 이 바이트 내용은 초기 http 요청에서 해당 요청객체가 가지고 있던 헤더부분의 "content-type" 를 기반으로 이진수에서 => 텍스트로 변환된다.

  4. 변환된 텍스트는 파싱되어 의미론적 단위인 토큰으로 분리가 되고, 이 분리된 토큰을 결합하여 노드를 형성한다. 각 노드들이 결합되면 DOM 트리를 만들게 된다.

  5. 만약 텍스트를 노드트리로 파싱하는 중간에 link 태그의 href 어트리뷰트를 통한 요청내용을 전달받게 된다면, DOM 파싱을 멈추고 해당 css 파일을 받아온 후, content-type에 따라 내용을 텍스트로 변환해 파싱하여 CSSOM 트리를 제작한다. (css의 내용들은 상속관계에 따라 부모에 있던 스타일 프로퍼티가 자식에도 역시 전달되어 적용된다)

참고로, css 파싱을 진행하여 CSSOM을 만드는 와중에 transform과 같이 gpu를 이용하여 새로운 레이어 층을 만드는 스타일 프로퍼티가 존재할 경우, Graphic 레이어를 따로 형성하게 된다.

  1. 해당 DOM 트리와 CSSOM 트리를 결합하여 랜더링을 위한 렌더 트리 를 형성한다. 이때 렌더 트리에는 브라우저의 렌더링에는 필요하지 않는 노드들(주석, 텍스트, meta, script, display:none 등)을 모두 제거한 상태로 최적화된다. 이렇게 만들어진 랜더트리를 기반으로 각 노드의 스타일(block인지 inline인지 등을) 확인하여 박스 모델을 기반으로 한 픽셀 좌표 계산인 Layout을 형성한다.

  2. 해당 Layout을 뷰포트 화면에 표현하는 Paint과정을 진행한다. 이후 페인트된 내용에 Graphic Layer들을 결합하는 Composite 과정을 거쳐 최종적으로 브라우저에 송출한다.


  • 브라우저의 랜더링 이전 작업과정 ( 크롬기준 )

일단 도입전, 크롬 브라우저가 OS에서 자원을 받아 실행되는 브라우저 프로세스는 기본적으로 브라우저의 전체적인 작동을 관리하는 역할을 한다. 그 이후 각 Tab마다 랜더링 프로세스가 새롭게 추가되면서 각각의 환경을 관리한다.

탭마다 랜더링 프로세스가 존재하는 이유는 각 탭을 독립적으로 관리하여 메모리 보안을 강화하고, 특정 탭에 발생하는 오류를 다른 탭들에 전파하지 않도록 하기 위함이다. 만약, 한 탭이 주소창을 해석완료한 후 받아온 html을 뷰포트에 반영할 때 내부에 Iframe과 같이 다른 주소에서 받아와지는 html 문서가 존재하게 된다면 또다른 랜더 프로세서를 형성해 관리되게 된다. 즉, 완전 별개의 프로세스가 되기 때문에 서로의 랜더링 내용에 관여가 제한적이게 된다.

만약 주소창에 입력된 내용을 엔터하게 된다면, Browser process에 내부에 존재하는 UI thread가 이를 받아온 후 이것이 search query인지 아니면 URI 인지를 확인한다. 만약 search query라면 구글 search engine을 기반으로 query를 날릴 준비를, URI라면 해당 주소로 요청을 날릴 준비를 한다.

UI thread는 Network thread에게 주소창의 내용을 판단해 만든 네트워크 URI 내용을 전달하고, 탭의 옆에 Loading spinner을 보여준다. Network thread는 해당 주소를 전달받은 후 DNS 연결을 통한 IP 패킷 형성 => TCP 를 통한 세그먼트 형성 => (https일 경우) TLS를 통한 인증서 기반 보안과정을 거친 후 네트워크 요청을 보낸다.

네트워크 주소를 전달한 UI thread는 이때 렌더링 프로세스를 미리 준비하고 있다.

이후 받아온 응답내용의 헤더를 확인하여 content-type이 무엇인지 파악한다.
이후 타입에 따라 랜더링을 위한 데이터가 준비가 되면, 이것을 UI thread에 전달하고, UI thread는 Network thread가 요청을 전달해서 받아오는 도중에 미리 준비해놨던 Rendering process에 해당 이진수 데이터(html) 을 전달한다.(정확히 말하면 Browser process와 Rendering process간의 데이터 전달) 이후 랜더링 프로세스는 위의 1에 해당하는 리플로우, 리페인트 과정까지를 완료한다. 이게 완료가 된다면 UI thread는

  1. security indicator(자물쇠 표시 / https요청이었을 경우)
  2. loading spinner 제거
  3. session history 업데이트(히스토리 스텍에 기존 내용을 저장)

  • CSR vs SSR
  1. CSR = 웹페이지의 랜더링이 브라우저에서 일어나는 것으로, html 자체 내부에 내용이 존재하지 않고 받아오는 JS 파일을 파싱하여 실행시켜 DOM을 조작해 추가적으로 랜더링을 하는 과정을 뜻한다. 이를 통해 서버와 클라이언트간에 불필요하게 html을 요청하고 응답받을 필요가 없으므로 트래픽적으로 문제가 덜어지지만 SEO에는 불리하다는 단점이 있었다. 다만 크롬의 크롤링 봇이 업데이트되면서 해당 JS 파일 역시 분석하여 평가에 반영하게 되어서 해당 단점은 사라져가는 추새이다.

2 . SSR = html 내부에 표시될 내용을 먼저 서버측에서 모두 파싱하여 저장해둔 후, 브라우저의 요청에 따라 해당 랜더링된 페이지와 함께 필요한 리소스들을 같이 전달하는 방식이다. html 내부에 모든 페이지 구성요소가 존재하므로 검색엔진에 최적화할 수 있고, 초기화면이 빠르게 나온다는 장점이 있지만 페이지를 이동할 때마다 서버에 요청을 하게 되어 서버부담이 늘어난다는 단점이 존재한다.


  • SPA 의 장점
    SPA은 서버에서 전달하는 한번의 리소스를 받아 브라우저 측에서 랜더링을 마친 후, 필요한 내용만 효율적으로 AJAX를 통해 서버에 요청하는 방식이다. 이를 통해 얻을 수 있는 장점은 페이지 전환 처리를 브라우저에서 js를 통해 담당하고 있으므로 자연스럽고 빠른 사용자 경험을 제공할 수 있다. 또한 js를 모듈화하여 분리작업할 수 있다는 장점이 존재한다.

-lazy loading이란
페이지를 읽어들일 때 해당 페이지에 랜더링하기 위한 리소스가 아니라면 패칭을 받는 우선순위를 뒤로 두어 불필요한 서버요청을 줄이는 방법이다. 예를들어, 페이지네이션에서 모든 페이지를 위한 데이터를 전부 다 서버에서 요청으로 받아들이는 것이 아니라, 특정 페이지에 필요한 자료만 받고 페이지가 이동하는 경우 다시 서버에 해당 페이지에 대한 요청을 하는 기법을 예로 들 수 있다.

// 예를들어, 해당 어트리뷰트를 통해 lazy loading을 요청할 수 있다.
<img src="example.jpg" loading="lazy" alt="..." />

-redirect의 방법
1. 서버에서 300번대의 요청을 전달할 경우 브라우저는 자동으로 전달받은 redirect 요청을 수행한다.
2. window.location을 통해 설정하면 해당 주소로 이동하게 된다.
3. react-router-dom을 사용한다면 useNavigation을 통해 조건부로 이동시킬 수 있다.


-reflow가 일어나는 상황과 최적화 방법
reflow란 이미 만들어진 랜더 트리로 계산된 레이아웃이 스타일 변경이나 노드 요소가 사라지는 등을 통해 변경될 경우, 새롭게 노드들의 위치들을 계산(recalculate)하여 좌표를 설정해주어야 하기 때문에 생겨난다. 구체적인 상황은 아래와 같다

  1. 노드 추가와 변경
  2. 노드의 위치 변경
  3. 노드의 크기 변경
  4. 윈도우 리사이징

이를 최적하기 위한 방법은 아래와 같다.

초기 랜더트리를 발생시킨 이후, 주기적인 변동( 예를들어 애니메이션 ) 이 일어나는 노드가 존재한다면 해당 노드를 position:absolute를 통해 graphic layer로 분리하여 작업한다. 또한 top과 left와 같이 레이아웃 배치가 변동될 사항을 피하고 transform 스타일 옵션을 사용하도록 한다.


  • OSI 7계층이란

네트워크 통신 과정을 7단계로 정의한 표준 규약이다. 구체적인 단계별 내용은 아래와 같다.
1. 물리계층 : 직접적인 케이블 연결을 통한 물리적 접속을 의미한다
2. 데이터링크 계층 : 필요한 데이터들을 네트워크 혼잡을 피하여 전송하는 작업이 진행되는 곳이다. (Mac address)
3. 네트워크 계층 : IP 패킷을 기반으로 데이터가 전송될 위치를 결정한다
4. 전송 계층 : TCP 세그먼트 기반으로 데이터의 분할, 및 포트번호와 검증부분이 이에 해당한다
5. 세션 계층 : 통신 시스템의 사용자간 연결을 유지하는 장소이다
6. 표현 계층 : 단순 데이터를 효율적인 방식으로 전달하도록 jpeg등의 확장자로 압축, 변형하는 단계이다
7. 응용 계층 : 전달받은 데이터를 최종적으로 유저가 확인하는 단계이다.(http 프로토콜 응답 등)


-TCP vs UDP
TCP는 ip 패킷을 작은 단위의 세그먼트로 분류한 뒤, 해당 내부에 검증부, 포트번호, 데이터순서 등과 같은 정보를 함께 담아 ip 주소에 해당하는 목적지로 전달한다. 이때 전달받은 측은 해당 TCP의 데이터 순서대로 결합 후 전달받지 못한 내용이 있다면 재요청을 하는 방식등을 이용하여 데이터를 온전하게 결합한다. 그러나 해당 TCP 연결을 위해서 매번 3way hand shake 과정을 거치기 때문에 UDP 에 비해서는 느리다

UDP는 Http 3.0 버전을 기반으로 하며, 3way hand shake를 하지 않고 포트정보와 체크섬 정보를 기본으로 가지는 정도이기 때문에 TCP에 비해 속도가 빠르다. 이는 스트리밍 서비스에 큰 장점을 보인다. 또한 요청 내용을 커스터마이징하기 어려운 TCP와 달리 UDP는 개발자가 원하는대로 해당 내부 구조를 추가할 수 있다는 자유도 역시 존재한다.


-TCP의 3 way handshake와 4 way handshake
3way handshake는 TCP 연결을 할 때에 실행하는 단계로, 초기에 클라이언트 측에서 서버를 향해 SYN 패킷을 보낸 뒤 서버 쪽에서 이것을 받아 ACK + SYN응답을 전달한다. 클라이언트가 이것까지 받아 ACK 패킷을 다시 서버에 전송한다면 그때부터 ESTABLISH 상태가 되어 서로의 연결이 유지된다.

4way handshake는 클라이언트와 서버가 서로 접속을 끊을 때에 사용하는 방식이다. 클라이언트는 FIN 플래그를 전송하고 자신은 FIN-WAIT 상태가 된다. 서버는 ACK를 보낸다. 이때 서버는 CLOSE-WAIT 상태가 된다. 그 후 서버 자신의 연결을 끊으면 클라이언트에게 FIN 플래그를전송하고 클라이언트는 ACK를 보낸 뒤 자신의 상태를 TIME-WAIT으로 변경한다.


  • DNS란
    Host에 있는 도메인 네임을 ip로 변환하는 서비스를 의미한다. 예를들어, www.naver.com은 사람이 읽을 수 있는 이름으로 변경되어 있는 네이밍이고, 이것을 실제 서버 컴퓨터의 주소인 ip와 연결하여 관리하는 시스템을 뜻한다.

DNS 서비스 과정은 아래와 같다
1. 브라우저의 캐싱 내용에서 해당 ip 주소를 확인합니다
2. 존재하지 않으면 라우터의 캐싱 내용을 확인합니다
3. 존재하지 않는다면 루트 DNS 서버로 이동하여 최상위 도메인 네임서버에 해당 ip address를 전달합니다. 이후 차례대로 네임서버를 거쳐가며 최종적인 ip 주소를 확인하게 된다면 이 내용을 로컬 DNS 서버에 전달받는다. 이 과정을 recursive query라고 한다.


-proxy server가 필요한 이유
프록시 서버가 필요한 대표적인 이유는 캐싱 때문이다. 모든 요청에 대해서 서버가 계속해서 응답한다면 서버의 부담이 몹시 클 수밖에 없다. 하지만, 자주 빈번하게 요청되는 내용에 대해서 따로 가까운 프록시 서버에 캐시형태로 저장한 후 이것을 돌려주면 되기 때문에 전송 시간을 아끼고 서버의 외부 트래픽을 줄일 수 있다. 또한 프록시 서버를 경유하면 요청대상의 ip를 숨길 수 있기 때문에 보안을 높일 수 있고, 우회 접속이 가능해진다.


  • http와 https의 차이
    http는 hyper text transfer protocol의 약자로, 네트워크 통신을 위한 기초 프로토콜이다.
    주로 HTML문서와 같은 리소스를 가져올 수 있도록 설계되어 있다. 클라이언트에서 보내지는 http 메세지를 request라고 부르며, 서버에서 응답할때 사용되는 http 메세지를 response라고 부른다. http는 기본적으로 stateless 즉, 요청에 대해 응답을 전달할 뿐 요청 당사자의 정보를 기억하지 않는 형식으로 되어 있기 때문에 로그인 서비스와 같이 특정 클라이언트를 기억해야 하는 서비스라면 쿠키나 세션과 같은 데이터 정보를 저장한 후 이것을 서버에 날려 인증을 진행한다. 구조는 크게 start line, headers, body로 이루어져 있다.

http 내용으로 네트워크 요청을 날릴 경우, http 내부에 있는 내용들이 web shark와 같은 프로그램을 이용해 손쉽게 탈취가 가능하기 때문에 보안에 취약하다. 이를 위해 보내지는 http를 암호화하여 전달하는 방식이 https이다. https는 SSL이라는 보안 레이어를 거쳐 인증서를 기반으로 해당 내용을 암호화하기 때문에 보안성이 높아진다.


  • local storage vs cookie

브라우저의 데이터 저장소는 로컬스토리지와 쿠키로 나눌 수 있다.
쿠키와 같은 경우, 매 서버에 요청을 날릴 때마다 기본적으로 해당 쿠키의 정보내용을 첨부하여 전달한다. 쿠키의 옵션에 따라 same-site가 strict일 경우, 동일한 사이트가 아닐 경우라면 쿠키 내용을 전송하지 않는다. 쿠키의 크기는 4096바이트로 제한되어 있다.

로컬 스토리지는 브라우저에 해당 서버 주소와 연결되어 데이터를 저장하는 방식으로, 기본 5mb 정도의 데이터를 저장할 수 있으며 데이터가 영구적으로 저장되고 직접적으로 처리하지 않으면 사라지지 않는다.
session storage는 이와 다르게 해당 탭 세션이 끝나서 프로세스가 종료되는 순간 데이터가 사라지게 된다.

profile
자라나라 프론트엔드 개발새싹!

0개의 댓글