[REAL Deep Dive into JS] 38. 브라우저의 렌더링 과정

young_pallete·2022년 10월 21일
0

REAL JavaScript Deep Dive

목록 보기
39/46

🚦 본론

요청과 응답

요청과 응답에서는... URL을 가지고 응답을 받는다는 내용을 서술했군요.
맞습니다. 브라우저에 URL을 입력한다는 것은, 자원에 접근하도록 요청하는 행위입니다.
반대로, 브라우저에서 출력된 화면을 본다는 것은, 자원 요청에 응답을 받은 행위입니다.

결국, 우리는 알게 모르게, 서버와 소통하고 있는 것이죠.

DNS에 관한 내용도 서술했군요! 이는 브라우저에 google.com을 검색하면...이라는 글에서 이미 다루었으니, 이것을 참고하시길 바랍니다!

결과적으로 우리는

  • URL을 통해 서버에 접속하게 되는 것이고,
  • 서버에서는 이 URL을 루트라 생각하고, 자원에 접근하게 됩니다.
  • 반대로 말하자면, 소스의 자원의 정확한 path만 알 수 있다면, 우리도 이를 접근할 수 있다는 것이죠.

HTTP 1.1과 HTTP 2.0, 이후 등장한 HTTP 3.0

책의 출간 날짜가 1년 전 것을 쓰고 있어서, 아직 HTTP 3.0에 관한 내용은 잘 서술되어 있지 않군요. 이 역시 이참에 다뤄보고자 합니다.

HTTP의 필요성

저는 항상 글을 쓸 때마다 뭔가 애매하다! 싶을 때 가장 먼저 찾아보는 것이 바로 '왜 필요한가'입니다. 필요가 없으면 당장 공부하지 않아도 되고, 필요하면 지금이라도 알아서 행복하기 때문에, 필요성을 따지는 것은 효율적인 공부 방식이라 생각합니다.

💡 그렇다면, HTTP는 왜 필요할까요?

리소스를 가져온다는 것은 우리에게 정보를 준다는 측면에서 좋지만, 제공하는 입장에선 엄청난 부담이 옵니다.
바로, 보안적 문제 때문이죠.

그렇다고 내가 갖고 있는 문서를 남들에게 제공하지 못한다면, 문서로써 공유 기능이 떨어지게 되죠.
따라서, 팀 버너스 리는 문서 공유를 위한 인터넷을 고안해냈습니다.
결국 문서를 주고받기 위한 하나의 거대한 웹(WWW: Would Wide Web)이 탄생했고, 이에 따라 여러 규칙이 생겼습니다.

  • 문서 기술 언어를 표준화하자! (HTML)
  • 주소를 지정하자! (URL)
  • 문서를 전송하자! (HTTP)

여기서 문서를 전송하기 위한 규칙, 그것이 바로 HTTP에요.
TCP나 TLS를 통해 수신자에게 문서를 전달하기에 믿을 수 있는 프로토콜이 생겨나게 된 것이죠.

사실, 좀 더 심취해서 HTTP의 특성을 다 적을까 하다가... 이 글의 요점인 1.0, 1.1, 2.0, 3.0을 정리하는 데 초점을 맞추려 합니다. 이 여정은, 다음에 기획해볼게요!

HTTP 1.0

💡 알고 있으신가요?
원래 HTTP는 버전 번호가 없었다고 합니다!

그래서 무명의 버전에서의 HTTP는 0.9버전이라고 불렀어요.
이때에는 정말 단순했어요.
요청은 라인 한 줄로만 했고, GET 메서드로만 해당 URL 요청이 가능했다고 합니다.

무엇보다 크리티컬한 것은 바로 오류 코드를 보낼 수 없다는 것과 HTTP 헤더가 없었다는 것이에요.
오류 코드는 일단 이해가 되겠는데(실패 했는지는 알아야 하니), 헤더가 없다는 게 문제가 되는 이유가 무엇일까요?

우리는 일반적으로 HTTP 헤더에 Content-Type을 명시하게 되어 있어요.
따라서, 헤더가 없다는 것은 순수하게 HTML 문서만 주고받을 수 있다는 것입니다.

🔥 윽, 기껏 받았더니 글만 딱! 나오다니, 우리 프론트엔드 입장에서는 최악이네요 😖

따라서 확장성을 위해 1.0 버전은 1996년부터 사용되기 시작했어요.

✅ 이때부터 버전 넘버링을 시작했다고 합니다.

1.0버전은 확장성을 위해, 다음과 같은 기능이 추가되었다고 합니다!

  • 상태의 성공 여부를 알려주는 코드 역시 전송되었어요!
  • HTTP 헤더가 도입되었어요!

바로 이런식으로 말이죠!

또한, 실제로는 HTTP의 버전 정보 역시 전송된다고 합니다.

GET /myimage.gif HTTP/1.0

하지만 이때까지도 문제는 많이 일어났고,
HTTP는 표준화 절차가 진행 중이었고 프로토콜이 되지 않았답니다.

당시에 고안되었던 1.0버전을 생생하게 느끼려면, 이 링크를 참조하시길 바랍니다 😉

HTTP 1.1

그러던 와중, HTTP 1.1 버전이 공개 되었어요.
1.1 버전은 인터넷이 좀 더 빠르고, 안정적으로 돌아가기 위해 다음과 같은 표준 기능들을 추가했어요.

  • 우리, 통신할 때 TCP 커넥션으로 주고받잖아요? 이 커넥션을 재사용할 수 있게 했어요.
  • 파이프라이닝을 통해 요청이 완전히 응답 전송되기 전에 다른 요청을 할 수 있어요.
  • 청크(쉽게 말하면 코드들을 한데 묶어둔 것이라고 생각 하면 돼요!)에 대한 응답도 지원해줍니다.
  • 캐시를 제어하는 메커니즘을 고안해냈습니다.
  • 최적의 컨텐츠 교환을 위한 동의를 가능케 했습니다.
  • Host 헤더를 통해, 서버 코로케이션(IDC 업체에게 서버를 위탁하여 관리하는 것)이 가능해졌어요!

하지만, 한 커넥션이 여러 요청을 처리할 수 없다는 한계에 봉착합니다.
HTTP 1.1은 순서의 보장을 지향하기 때문이었는데요.
자바스크립트를 통한 리소스의 양은 방대해짐에 따라, 리소스의 동시 전송은 힘들다는 한계점은 문제에 봉착하게 됩니다.

그렇게, HTTP 2.0이 대두되기 시작했어요!

HTTP 2

2010 초반, Google은 느린 HTTP 프로토콜에 대해 고민하게 됩니다.

💡 "어떻게 하면, 우리 데이터를 더 빠르게 전달할 수 있을까?"

이러한 실험 끝에, 응답성 증가는 높이되, 데이터 중복성은 낮추는 방법을 고안했는데요.
이것이 곧 HTTP 2.0에 큰 영향을 주었어요.

주요 변경 사항은 다음과 같아요!

  • 더이상 텍스트 프로토콜이 아닌 이진 프로토콜로, 최적화가 가능해졌습니다.
  • 이제, 데이터 순서에 유연해졌어요. 한 커넥션에서, 여러 병렬 요청이 가능해졌어요!
  • 중복된 헤더를 압축해줌으로써 효율성을 높였어요.
  • 데이터의 중복을 통한 오버헤드를 개선했어요!
  • 클라이언트 캐시를 서버 푸쉬 메커니즘을 통해 필요한 데이터를 채워넣습니다!

HTTP 2.0 버전은 점차 발전했는데요.
이에 따라 2버전에서는 다음과 같은 기능들이 추가되었다고 합니다.

  • 쿠키의 안전성 보장을 통해, 이제 쿠키에 대한 보안을 강화했어요!
  • 클라이언트와 서버의 요청, 제약 사항을 서로 주고받을 수 있게 됐어요!
  • CDN 매커니즘을 기반으로, Alt-Svc를 도입해 좀 더 인증과 관련한 신뢰성 검증을 유연하게 했어요!

HTTP 3.0

2022 6월 6일 후로 표준화는 되어 있지만 아직은 실험적인 버전이에요.
정말 특이한 게, 3.0버전에서는 QUIC 프로토콜을 통해 통신한다는 점이에요!
이게 왜 특이하냐면, 통신에 대한 커넥션을 TCP가 아닌 UDP 기반으로 사용하기 때문이에요.

🔥 잠깐! 이거 TCP가 안전하다면서요? 왜 UDP를 쓰게 된 거죠?!

TCP는 안전하기는 하지만 다음과 같은 단점이 있었어요.

  • UDP에 비해 느리다는 것과
  • HOL 블로킹에 대한 문제였는데요!

우리가 결국 패킷을 받게 되고, 패킷을 통해 하나의 리소스를 가져오게 되는 건데 TCP에서는, 이 처음 패킷이 오~래 걸려버리면,, 처리 속도가 현저히 떨어지는 현상이 발생하게 돼요.
심지어는, 손실 복구 메커니즘을 인식하지 못할 경우 아예 모든 활성 중인 트랜잭션을 셧다운시키는 문제가 발생합니다.

따라서 3.0은 이 두 가지에 대한 개선을 목표를 두고 진행되었어요.

빠르다

HTTP 3.0 버전에서는 UDP의 사용자 공간 혼잡 제어를 사용하게 되었어요.
이는 곧, 핸드셰이크를 하는 데 있어 효율적인 성능을 갖게 되었다고 합니다!
또한, FEC를 제공하기 때문에, 이제는 오류가 발생하면, 수신 측에서 실시간적으로 문제를 개선할 수 있는 여건이 높아지겠어요!

HOL 블로킹

QUIC에서는 데이터 패킷에 대한 내결함성을 제공한다고 해요.
이것이 의미하는 것은, "이 패킷이 문제지, 다른 패킷은 문제가 없어!"라고 말해주는 거에요.
따라서 다른 데이터 스트림들이 모두 종단점을 경유하게 되기 때문에, HOL 블로킹을 개선해준다고 합니다.

단점

그러나, 아직은 좀 더 지켜봐야 하기는 해요.
UDP의 단점이 뭐죠? 보안이죠!

따라서, 이를 위해서는 암호화가 분명히 존재해야 하는데...
QUIC에서는 패킷별로 암호화를 하는 전략을 택하게 돼요.
그렇다면 암호화가 있다는 것은

  1. 패킷별로 또 다시 신뢰성 검증을 해야 하는 로직이 필연적으로 발생하게 될 것이고,
  2. 패킷이 많아질 수록 부하는 증가하게 된다는 또다른 문제에 직면하게 되겠죠.

또한, 헤더 필드 역시 암호화시키기 때문에, 이 정보가 필요한 ISP 등에서는 도입이 어려울 수 있다고 합니다. 따라서, 아직은 주시하고만 있자구요! 🙆🏻

HTTP만 썼는데도 이정도인데, 글을 예전에 썼던 게 없다면 참 길어졌겠군요!

HTML 파싱과 DOM 생성 ~ script 태그의 async/defer 어트리뷰트

이 부분이 궁금하시다면, 이미 쓴 글을 읽어주세요!

제 글 시리즈를 읽으셨다면, 결국 어떤 언어가 동작하기 위해서는 파싱이라는 것을 꼭 거쳐야 한다는 것을 이해할 거에요.

브라우저의 렌더링 과정에서도 마찬가지에요.
토크나이징(렉싱) -> 파싱을 거치는 것은 변하지 않습니다.

이는 HTML, CSS, JS 모두 공통에 해당되는 사항입니다.

이 과정이 궁금하실텐데요, 이는 리플로우와 리페인트를 알아보자!라는 글로 이미 써두었습니다. 따라서 브라우저에서 렌더링되는 상세 과정은 여기서 보시기를 바랍니다!

또한, script를 파싱하는 과정은 script vs script defer vs script async라고 이전에 쓴 글을 읽어주시면 좋을 것 같아요.

🚦다시 쓸까 고민을 해봤는데 아무래도, 똑같은 내용을 반복해서 쓰는 건 자제하려구요.
그건 좋은 문서 보관 방식이 아닌 것 같습니다.

🎉 마치며

뭔가 책을 토대로 지식을 정립하는 이번 과정이 굉장히 웃겼어요.
이름은 브라우저 렌더링 과정인데, 기승전 HTML의 변화같은 느낌으로 전개되는 것 같은 이 문서 구조...

그만큼 이 파트에는 정말 핵심들이 엄~청 많이 녹아들어 있네요.
저도 다시 또 복습하면서 많이 배워가요!

그럼, 다들 즐거운 공부하시길 바라며. 이상! 🌈


📁 참고자료

MDN - HTTP
MDN - HTTP의 진화
1.2 웹과 HTTP 탄생 배경
blog - QUIC (Quick UDP Internet Connection)
Wikipedia - QUIC
FEC
HTTP3, 사실 진짜로 바뀐건 TCP 였다.

profile
People are scared of falling to the bottom but born from there. What they've lost is nth. 😉

0개의 댓글