브라우저의 동작 원리

브라우저가 하나의 화면을 그려내는 과정을 Critical Rendering Path 라고 한다. 주소창에 url을 입력하고 엔터를 치면 브라우저는 서버에 request를 보낸다. 서버에서는 응답으로 HTML 데이터를 내려주는데, 이를 화면으로 그리기까지 다음 단계를 거쳐 작업을 진행한다.

  1. 서버에서 응답으로 받은 HTML 데이터를 파싱한다
  2. HTML을 파싱한 결과로 DOM Tree를 만든다
  3. 파싱하는 중 CSS 파일 링크를 만나면 CSS 파일을 요청해서 받아온다
  4. CSS 파일을 읽어서 CSSOM (CSS Object Model)을 만든다
  5. DOM Tree와 CSSOM이 모두 만들어지면 이 둘을 사용해 Render Tree를 만든다
  6. Render Tree에 있는 각각의 노드들이 화면의 어디에 어떻게 위치할지를 계산하는 Layout 과정을 거쳐서
  7. 화면에 실제 픽셀을 Paint 한다.

서버에서 응답으로 받은 HTML 데이터를 파싱한다

HTML에서 DOM Tree로

브라우저는 읽어들인 HTML 바이트 데이터를 해당 파일에 지정된 인코딩에 따라 문자열로 바꿈.
바뀐 문자열을 다시 읽어, 문자열을 토큰으로 변환.
이렇게 만든 토큰을 다시 노드로 바꿈. 토큰들이 HTML 노드의 자식 노드로 넣는 식으로 변환이 이러우지기 때문에, 과정이 끝나면 Tree 모양의 DOM(Document Object Model)이 완성됨.

CSS에서 CSSOM으로

HTML을 파싱하다 CSS 링크를 만나면, CSS 파일을 요청해서 받아오게 됨.
받아온 파일은 HTML을 파싱한 것과 유사한 과정으로 Tree형태의 CSSOM으로 만들어짐.

DOM(Content) + CSSOM(Style) = Render Tree

DOM과 CSSOM을 합쳐 Render Tree를 만든다. Render Tree는 DOM Tree에 있는 것들 중 화면에 실제로 보이는 것들로만 이루어진다.
Render Object의 속성에 따라 필요한 경우 Render Layer가 만들어짐. 여기서 GPU에서 처리되는 부분이 있으면 다시 Graphic Layer로 분리됨. 다음과 같은 속성을 가졌을 때.

  • CSS 3D Transform이나 perspective 속성이 적용된 경우
  • video 또는 canvas 요소
  • CSS3 애니메이션 함수나 CSS 필터 함수를 사용하는 경우
  • 자식 요소가 레이어로 구성된 경우
  • z-index 값이 낮은 형제 요소가 레이어로 구성된 경우

Layout (reflow)

Render Tree에 있는 각각의 노드들이 화면의 어디에 위치할 지를 계산하는 Layout 과정을 거침. 여기에서 CSS box model이 쓰이며 position, width, height 등 틀과 위치에 관련된 부분이 계산됨.
브라우저를 리사이저하면 Render Tree는 그대로인 상태에서 layout 단계만 다시 거쳐 위치를 계산해서 그림.

Paint (repaint)

Render Tree의 각 노드들을 실제로 화면에 그림.

CORS

HTTP 요청은 기본적으로 Cross-Site HTTP Request가 가능하다.
그러나 script에서 생성된 request는 Same Origin Policy를 적용받기 때문에 동일 도메인, 동일 포트, 동일 프로토콜 내에서만 요쳥이 가능하다.
그러다 HTML5에서 다른 도메인 간 통신이 가능한 스펙이 추가되었는데, 그것이 바로 CORS이다.

CORS 요청의 종류

Simple/Preflight, Credential/Non-Credential의 조합으로 4가지가 존재한다.

Simple Request

아래 3가지 조건을 모두 만족하면 Simple Request

  • GET, HEAD, POST 중의 한 가지 방식을 사용해야 한다
  • POST 방식일 경우 Content-type이 아래 셋 중 하나여야 한다
    • application/x-www.-form=urlencoded
    • multipart/form-data
    • text/plain
  • 커스텀 헤더를 전송하지 말아야 한다 Simple Request는 서버에 1번 요청하고, 서버도 1번 회신하는 것으로 처리가 종료된다

Preflight Request

Simple Request 조건에 해당하지 않으면 브라우저는 Preflight 방식으로 요청.
따라서 preflight는

  • GET, HEAD, POST 외의 다른 방식으로도 요청을 보낼 수 있고
  • application/xml 처럼 다른 Content-type으로 요청을 보낼 수도 있으며
  • 커스텀 헤더도 사용할 수 있다

Request with Credential

HTTP Cookie와 HTTP Authentication 정보를 인식할 수 있게 해주는 요청

크로스 브라우징

웹 표준에 따라 개발하여 서로 다른 OS 또는 플랫폼에 대응하는 것. 웹 사이트를 서로 비슷하게 만들어 어떤 환경에서도 이상없이 작동되게 하는데 그 목적이 있다.

서버 사이드 렌더링 vs 클라이언트 사이드 렌더링

모바일의 시대가 도래하면서 모바일 웹에 대한 수요가 폭증, 새로운 웹 출력 방식인 SPA(Single Page web Application)이 등장한다.
SPA는 브라우저에 로드되고 난 뒤 페이지 전체를 서버에 요청하는 것이 아니라, 최초로 한 번 페이지를 로딩한 후부터는 데이터만 변경하여 사용할 수 있는 웹 어플리케이션이다.
서버는 단지 JSON 파일을 보내주는 역할을 하고, html을 그리는 역할을 클라이언트 측에서 자바스크립트가 수행하게 된다. 이것이 바로 클라이언트 사이드 렌더링이다.
Angular JS와 Backbone JS 같이 single page를 생성하기 쉬운 JS 프레임워크가 등장한다. 또한 클라이언트 쪽이 점점 무거워지자 view만 관리하자는 철학으로 React가 등장한다.

각 렌더링의 장단점 비교

클라이언트 사이드 렌더링은 사용자 행동에 따라 필요한 부분만 다시 읽어들인다. 때문에 서버측에서 렌더링하는 것보다 빠른 인터랙션을 기대할 수 있다.
하지만 렌더링할 때 페이지를 읽어들이는 시간, 자바스크립트를 읽어들이는 시간, 자바스크립트가 화면을 그리는 시간까지 모두 마쳐야 콘텐츠가 사용자에게 보여진다. 즉 초기 구동 속도가 느리다는 단점이 있다.
또한 검색 엔진 최적화의 문제가 존재한다. 웹 크롤러, 봇들이 자바스크립트 파일을 실행시키지 못하기 때문.
여기에 추가적으로 보안문제가 발생한다. 서버 사이드 렌더링에서는 사용자 정보를 서버 측에서 세션으로 관리를 했다. 그러나 클라이언트 측에는 쿠키말고는 정보를 저장할 공간이 마땅치 않다.

서버 사이드 렌더링은 반대이다.
유저가 처음으로 컨텐츠를 접하는 시점을 당길 수 있다. 보안, 검색 엔진 최적화 등도 장점.
문제점은 사용자와 인터랙션 하는 부분. 매번 서버에 request 요청을 통해서 해결해야 함. DOM 조작에 있어서도 요청하는 과정과 엄청난 탐색 비용이 요구됨.

참조

  • https://asfirstalways.tistory.com/244