티스토리 뷰
- node.js는 v8 엔진을 빌드 된 런타임 환경이다. 서버, ssr서버 등 으로 활용가능하다. 하지만, javascript가 가장 많이 사용되는 분야는 역시 client side(브라우저)다.
- 대부분 프로그래밍 언어는 운영체제나 가상머신 위에서 실행되지만, 웹 어플리케이션은 브라우저에서 실행된다. 브라우저 환경을 잘 알고 개발을 해야 좋은 프로그램을 개발할 수 있다.
- 파싱: 문자열을 토큰화 하고, 의미와 구조를 반영하여 파스트리를 생성하는 일련의 과정을 말한다. 일반적으로 파싱이 완료되면, 코드는 바이트 코드로 바뀐다. 그리고 엔진이 또는 운영체제가 실행한다.
- 렌더링: 렌더링은 html css 자바스크립트로 작성된 문서를 브라우저가 파싱 ~ 시각화까지 하는 일련의 작업을 말한다.
*브라우저 렌더링 과정*
- 브라우저는 html, css, js, image, font 등 웹서버(webpack dev server, nginx, next.js 등..)에 리소스를 요청하여 응답받는다.
- 브라우저의 렌더링 엔진은 서버로부터 응답된 html을 파싱하여 dom을만들고 css를 파싱해서 cssom을 만든다. 그 둘을 결합하여, 렌더 트리를 만든다.
- 자바스크립트엔진은 자바스크립트를 파싱해서 abstract syntax tree를 생성하고, 바이트 코드로 변환하여 실행한다. 실행중인 자바스크립트는 DOM API를 통해 dom이나 cssom을 변경할 수있다. dom과 cssom이 변경되면 렌더트리가 새로고침된다.
- 렌더트리를 기반으로 html의 레이아웃을 다시 계산하고 브라우저화면에 html요소를 페인팅한다.
38.1 요청과 응답
- 브라우저의 가장 핵심 기능은 리소스를 서버에서 응답받아 시각적으로 렌더링하는 것이다.
- 주소창을 통해 url을 입력하면 dns 서버를 통해 domain이 호스트 ip로 변환되고, 호스트의 80(http)또는 443(https)포트에 요청이 전달된다.
- bomsbro.com을 입력하면, bomsbro.com/index.html을 요청하는 것과 같은 것이다.리액트의 public 폴더에는 index.html이 들어있다. index.html이 아닌 다른 자료를 요청하려면 path를 작성해주면 된다.
- 주소창이 아닌 자바스크립트도 xhr을 통해 api서버 등에 리소스 요청을 전송할 수 있다.
- 그런데, index.html을 요청했는데, css 자바스크립트 이미지 등을 엄청 또 가져온다. 왜냐하면, index.html에 link태크, img태그, script 태그 등등이 들어있어서 이러한 태그들을 만나면 브라우저가 파싱을 일시중지?하고 리소스파일을 서버로 요청하기 때문이다.
38.2 HTTP 1.1과 HTTP 2.0
- HTTP는1989년 팀 버너스리(IBM)가 고안하고 91년에 HTML URL과 함께 문서화 되었다. 96은 1.0이 99년에 1.1이 발표되었다. 그리고 2015년이 되어서야 2.0이 발표된 것이다.
- 1.1은 기본적으로 커넥션 당 하나의 요청과 응답만 처리한다. 여러개의 요청을 동시에 처리할 수 없었다.
- 2는 커넥션당 여러개의 요청이 가능하다. 그리고 여러 리소스의 동시 전송도 가능하다.
**http 1.1과 2의 차이는 더 딥하게 봐야한다. **
38.3 HTML 파싱과 DOM 생성
- 서버가 응답한 html 문서는 string에 불과하다. 해당 string을 브라우저가 이해할 수 있는 object로 변환해야만 브라우저 메모리에 올라갈 수 있다.
- 바이트(네트워크에서 받은 직후) -> string(바이트 역직렬화 이후) -> 토큰(파싱 이후) -> 노드 -> dom
** html 문서는 head태그 안 meta 태그의 charset attribute에 의해 지정된 incoding으로 바이트코드에서 문자열로 변환된다. UTF-8등..
** 변환된 html string은 최소 의미를 가지는 토큰들..? 로 분해된다. startTag, conntents, endTag구조의 object 자료구조에 담긴다. 이게 실제 객체화되면서 태그별 특성을 가진 node들이 생성되고 이들을 조합하여 dom tree가 생성된다.
38.4 CSS 파싱과 CSSOM 생성
- 렌더링 엔진은 css를 로드하는 link태그나 style 태그를 만나면 dom 생성을 일시 중단한다.
- 그리고 link태그의 href의 url에서 css파일을 서버에 요청을 로드하고, 바이트 문자 토큰 노트 cssom 과정으로 처리한다.
- 그 후 렌더링 엔진은 dom 생성을 재개한다.
* cssom은 상속을 반영하여 생성된다. 예를들어 ul태그에 list-style-none 스타일은 하위 li태그에게 상속된다.
38.5 렌더 트리 생성
- dom과 cssom은 노드로 결합된 후 각 노드는 렌더트리에 포함된다.
- meta script 태그 등은 화면에 렌더되지 않는다. 렌더트리는 렌더링 되는 노드들만 포함한다.
** 여기서 display: none은 렌더트리에 포함되지 않는다. **
**렌더 트리생성과정은 노드 추가 삭제, 창 리사이징에 의한 뷰포트 변경, html 요소의 레이아웃을 변경하는 스타일 속성 변경 width height margin padding border display position top right bottom left 등의 변경..
** 리렌더링은 비용이 많이 드는 작업이므로 이를 최소화해야한다. **
38.6 자바스크립트 파싱과 실행
- 자바스크립트는 DOM API를 통해 DOM을 조작할 수 있다.
- 렌더링엔진은 script태그를 만나면 dom생성을 일시 중단한다.
- 요청하여 자바스크립트 파일을 받은 뒤, 자바스크립트 엔진에게 제어권을 넘긴다. 자바스크립트의 파싱과 실행이 엔진에 의해 종료된 이후에 제어권을 받아 dom 생성을 재개한다..?
- 자바스크립트 엔진은 자바스크립트를 저수준 언어(compile language)로 변환하고 실행한다. 모든 자바스크립트는 ECMA 사양을 준수한다.
** AST-abstract syntax tree: 추상 구문 트라라는 의미로, v8엔진은 자바스크립트 코드를 AST로 변환하고, 이를 인터프리터가 실행할 수 있는 중간코드(바이트 코드)로 변환 한다. 그리고 인터프리터는 해당 바이트코드를 실행한다.
** v8 엔진에는 터보팬이라는 컴파일러가 자주사용되는 코드를 최적화한다. 자주사용되지 않으면 디옵티마이징한다.**
38.7 리플로우와 페인트
**리플로우: dom+css rendertree layout paint 처음부터 다시 거치는걸 말한다.
**리페인트: rendertree layout 이후 paint작업만 다시하는 것을 말한다.
38.8 자바스크립트 파싱에 의한 HTML 파싱 중단
- 렌더링 엔진과 자바스크립트 엔진은 병렬적으로 실행되지않고 직렬적으로 실행된다.
- css와 javascript를 파싱할때 dom생성이 중단된다.
- 브라우저는 html을 동기적으로 파싱및 실행을 하는 것이다.
- script 태그를 만나면 렌더링 엔진이 중단되고, 또 script의 javascript가 dom 조작을 할 경우 dom이 없으면 문제가 발생한다. 그래서 script 태그의 경우 body 안쪽 가장 하단에 놓는게 좋다.
38.9 script 태그의 async/defer 어트리뷰트
- async와 defer 어트리뷰트를 사용하면 js파일이 비동기적으로 load된다.
- async: 자바스크립트 파일의 로드가 완료된 직후 파싱과 실행이 진행된다.
- defer: html파싱이 완료되어야 파싱과 실행이 진행된다. 좀더 확실하게 dom이 아직 생성되지 않는 오류없이 동작하게 할 수 있는데, ie10이상에서 지원한다.
궁금한점
- https://bomsbro.com/api/swagger-ui/index.html 은 왜 idex.html을 써줘야 하는지?? 스프링부트에서 설정을 변경해줘야겠다.
- HTTP 96은 1.0이 99년에 1.1이 발표되었다. 그리고 2015년이 되어서야 2.0이 발표된 것이다. 2015년은 ES6의 해이기도 하다. 서로 무슨 연관이 있는지? 2015년은 웹 역사적으로 매우 중요한 해인 것 같다.
- v8 자바스크립트 컴파일과정 알아야할 듯.
** v8엔진 내부 동작 글 좀 봐야할듯.**
**fetch load ...?? 자바스크립트를 다운받는거랑 load하는거랑 동작 좀 알아야할듯??**