브라우저 렌더링

H Kim·2022년 3월 4일
0

TIL

목록 보기
7/72
post-thumbnail

브라우저란?


  • 개념
    -

    • 웹 브라우저 또는 웹 탐색기라고 불린다.
    • 웹 서버에서 쌍방향으로 통신하며 HTML 문서 및 그림, 멀티미디어(ex. 동영상) 등의 컨텐츠를 열람하기 위한 GUI 기반의 소프트웨어 프로그램이다.
    • 웹 브라우저는 페이지를 다운로드하기 위해 HTTP를 통해 송수신한다.
  • 주요기능

    • 사용자가 선택한 자원(resource)을 서버에 요청(request)하고 서버가 보내온 것(response)을 브라우저에 표시하는 것(rendering)
    • PDF, 멀티미디어 일 수도 있지만 대가 HTML 문서이다.
    • 자원의 주소: URI(Uniform Resource Identifier)
  • 기본 구조 및 간략한 설명

  • 브라우저 엔진 (렌더링 엔진)
    • 브라우저를 화면에 표시하기 위해서 반드시 필요한 부분이다.
    • HTML 및 XML 문서와 이미지를 표시할 수 있다. (플러그인이나 브라우저 확장 기능을 이용해 PDF와 같은 다른 유형도 표시할 수 있다.)
    • Chrome의 V8 엔진, 파이어폭스의 게코(Gecko)엔진과 같이 각 브라우저마자 다른 엔진을 가지고 있다.

브라우저 렌더링 방식


  1. URI에 접속
  2. 브라우저가 서버로부터 HTML 문서를 모두 전달 받아 읽어들인다.
    • 브라우저가 아는 언어는 HTML, CSS, JS, Web Assembly 뿐.
    • 따라서 php, jsp, asp 같은 서버 템플릿 언어도 기본적으로는 HTML으로 내려주게 된다.
    • link: 외부 리소스와 연결시켜주는 태그. 보통 CSS 파일에서 많이 쓰며 해당 태그도 만나면 연결된 주소를 통해 외부 리소스를 다운 받는다.
    • script: JS 파일과 연결시켜주는 태그. 해당 태그를 만나면 잠시 렌더링을 멈추고 다운로드를 받기 시작한다. JS 파일이 크면 클수록 렌더링이 느려지는 이유이다.
    • img : Link와 마찬가지로 외부 리소스와 연결시켜주는 태그. 해당하는 외부 리소스를 다운로드 받는다. (이 과정은 mp4, 비디오, 오디오 요소도 마찬가지)
  3. 렌더링 엔진은 전달받은 HTML 문서를 파싱하여 DOM 객체 모델을 만든다
    • 파싱: 브라우저의 렌더링 엔진이 HTML 파일을 위에서 아래로 한 줄씩 읽어내려가는 것.
  4. 다운 받았던 외부 CSS 파일과 함께 포함된 스타일 요소를 파싱해 CSSOM 객체 모델을 만든다.
  5. 3에서 만든 DOM 트리와 4에서 만든 CSSOM 트리를 합쳐 렌더 트리를 구축한다.
    • 모든 HTML은 기본적으로 다 스타일을 가지고 있기 때문에 CSS가 없는 HTML은 없다.
    • 반드시 둘이 결합이 되어야만 렌더 트리가 생성된다.
  6. Layout이 진행된다.
    • 렌더 트리의 각 노드에 대해서 화면 상에서 어디에 배치할지 결정한다.
    • 이 과정을 Reflow라고도 한다.
  7. Paint를 한다.
    • UI백엔드에서 렌더 트리를 그린다.
    • 실질적으로 브라우저 화면을 그리는 과정으로 여기까지 해야 유저에 눈에 보이게 된다.

이 과정을 RENDER라고 한다.


  • DOM
    • DOM이 변경되면 렌더 트리를 만들고, 레이아웃(조금이라도 배치가 바뀌어도 레이아웃 과정이 일어남)을 하고, 페인트를 하는 과정이 다시 일어난다.
    • Layout은 실제로 컴퓨터의 CPU를 많이 먹고, Paint는 GPU를 많이 먹는다.
      • 유저의 눈에 일련의 과정이 부드럽게 처리되기 위해서는 초당 60프레임은 유지시켜야 한다. (1프레임 당 0.024초 정도)
      • 1 프레임 안에 레이아웃과 페인트 과정이 동시에 이루어져야 한다.그렇기 때문에 프레임 드랍(초당 유지시키던 프레임의 수가 줄어드는 현상, 유저가 "화면이 멈춘다, 버벅이다"라고 느끼게 됨) 현상과 직접적인 연관이 있다.
  • 불필요한 Layout을 줄여 렌더링 퍼포먼스를 최적화 할 수 있어야 한다.
    • DOM의 CSS 속성 중에 레이아웃을 발생시키는 속성들이 있어 이 속성을 사용하게 되면 DOM은 그때마다 변경이 되어 렌더 트리를 만들고, 레이아웃을 발생시키고, 페인트를 하는 과정이 연속적으로 일어난다. 때문에 이런 레이아웃을 발생시키는 속성을 피한다면 해당 과정이 발생하는 횟수를 줄일 수 있고 렌더링 퍼포먼스를 높이는 효과가 있다.
    • CSS에 이러한 속성들이 많다.
      • left 속성 중 left-top, left-bottom 속성을 사용하면 위치가 변경된다. (position 속성과 같이 씀) 이 left 속성은 레이아웃을 발생시키는 속성이다. 따라서 이 속성을 가지고 애니메이션을 만들 때는 프레임 유지를 보장하기 어려워진다.
        • 그래서 이 속성을 피해 transform이라는 속성을 사용한다. transform에 있는 translate를 사용하면 좌표 값을 사용해 위치를 이동하지만, 레이아웃을 발생시키지 않기 때문에 페인트만 다시 발생시키는 쪽으로 렌더링 과정이 일어나기 때문에 유지하고자 하는 프레임 수를 기대할 수 있다.
        • 또는 will-change 속성을 사용해서 구현할 수도 있다.
    • 레이아웃 과정은 줄일 수 있지만, 페인트는 최적화시킬 수 있는 방법이 존재하지 않는다. 페인트는 유저에게 화면을 보여주기 위해 그리는 과정이라서 필수적인 과정이다. 따라서 프론트엔드 개발자가 되어 브라우저 렌더링의 최적화 과정을 수행하고자 한다면 레이아웃이 일어나는 상황을 최대한 피하는 것이 좋기 때문에 해당 과정은 굉장히 중요하다.

  • 파싱
    • 문서 파싱은 브라우저가 코드를 이해하고 사용할 수 있는 구조로 변환하는 것을 의미한다.
    • 파싱 결과는 보통 문서 구조를 나타내는 노드 트리가 되는데, 파싱 트리(parse tree) 또는 문법 트리(syntax tree)라고 부른다.
    • 렌더링 과정에서는 HTML 파일을 바탕으로 DOM 트리를 만드는 것을 파싱한다고 표현한다.
    • 파싱은 문서에 작성된 언어 또는 형식의 규칙에 따르는데 파싱할 수 있는 모든 형식은 정해진 용어와 구문 규칙에 따라야 한다. 이것을 문맥 자유 문법이라고 한다. 인간의 언어는 이런 모습과는 다르기 때문에 기계적으로 파싱이 불가능하다.

브라우저 렌더링 방법 CSR (Client Side Rendering)


  • 클라이언트에서 HTML을 DOM을 이용해서 만들어 화면에 그리는 것이다.

  • 여기서 클라이언트란 브라우저를 뜻한다.

  • 기존에 파싱할 HTML을 가장 기초적인 것만 가져가고, 나머지는 JS를 이용해서 DOM을 만들고, 만들어진 DOM을 HTML에 덧붙여주면 어떨까? 라는 생각에서부터 시작했다. 나머지 HTML을 모두 DOM을 이용해 그리기 때문에 실제 HTML 파일 자체의 용량은 낮아지게 된다. 최초에 사이트에 접근해 다운 받는 HTML 자체의 용량은 적어지기 때문에, 페이지를 로딩하는 데에 드는 시간이 비약적으로 줄어든다는 장점이 있다.

  • 단점으로는 HTML을 기본적인 것만 가져가고 나머지는 전부 DOM을 이용해 그리기 때문에 JS 파일이 그만큼 커지게 된다다. 따라서 script 태그를 통해 JS 파일을 다운로드 해오는 데에 드는 시간이 상대적으로 늘어나게 됐다. 그러나 JS를 사용해 DOM을 직접 만들어 그려주고 있기 때문에, 어떻게 보면 필요한 DOM만 그때 그때 만들어서 쓴다는 것은 HTML을 다시 불러오지 않고 JS에서 그때마다 DOM을 새로 만들어서 구현한다는 것에 집중할 수 있다.

  • CSR 개념을 기반으로 한 React, Angular, Vue와 같은 라이브러리들이 있다.

    • 브라우저에서 컴포넌트를 만들어, 그 컴포넌트를 브라우저 화면에 그리는 것 (렌더링) 을 최우선 목표로 한다.
    • 위의 라이브러리들은 일일히 DOM을 생성하고, 붙이고, 그리는 과정을 대신 해 준다.
    • React에서는 JSX 문법은 HTML를 사용하듯 컴포넌트를 만들 수 있어 문법적 편의성 덕분에 React가 현재 개발 생태계에서 가장 큰 점유율을 차지할 수 있게 되었다.
  • 과거에는 데이터를 갱신할 때마다 새로고침을 해주어 화면을 완전히 새로 그려주는 것이 필요했다. 이러한 부분은 UX에 큰 손실을 가져왔고 CSR은 UX를 위해 나왔다고 해도 과언이 아니다.

  • 그러나 기본적으로 HTML을 그리는 것 외에는 모든 것을 JavaScript의 언어로 해결을 하려다 보니 피치 못하게 JS 번들 사이즈가 많이 커지게 됐다. 이것은 브라우저가 가지고 있는 파워를 많이 쓰게 되었고, 결국 렌더링 퍼포먼스는 조금 저하될 수밖에 없었다.

  • 그럼에도 클라이언트 사이드 렌더링을 이용해 한 번 렌더링을 시키고 나면 그 다음에는 필요한 부분만 렌더링을 시키면 되기 때문에 반드시 느리다고 볼 수 없다. 렌더링 최적화를 잘 시켜준다면 유저 경험 측면에서는 분명히 긍정적인 영향을 줄 수 있기 때문에 클라이언트 사이드 렌더링은 아직까지도 선호되는 렌더링 방법 중 하나이다.

  • article 위주의 정적인 렌더링을 하는 사이트는 굳이 CSR을 선택할 필요가 없이 서버 사이드 렌더링을 이용해도 충분할 수 있다.

  • 클라이언트 사이드 렌더링을 하면 좋은 사이트는, 실시간성이 보장되어야 하는 사이트들이다. 지메일이나 구글 Docs 같이 실시간으로 데이터를 전송 받아야 하는 사이트들, 트위터나 인스타그램, 페이스북 같이 유저 간 교류가 실시간으로 일어나는 SNS 사이트들이 클라이언트 사이드 렌더링을 하면 좋은 사이트이다.

  • 클라이언트 사이드 렌더링으로 한 번 웹을 구현했다고 해서 꼭 다른 부분도 그렇게 만들어야 할 필요는 없다. 클라이언트 사이드 렌더링으로 웹을 구현했더라도, 클라이언트 사이드 렌더링이 필요하지 않은 부분도 있다면 적합한 환경을 섞어서 사용해도 무방하다.


브라우저 렌더링 방법 SSR (Server Side Rendering)


  • 서버에서 HTML을 만들어서 내려보내주는 방식이다.

  • 서버 사이드 렌더링은 보통 웹 콘텐츠가 많을 때 많이 쓰이는 렌더링 방식으로, 서버에서 콘텐츠를 만들어서 웹으로 내려보내 렌더링을 하는 방식이다. 여기서 서버에서 콘텐츠를 만들어서 웹으로 내려보낸다는 의미는, 서버에 존재하는 데이터베이스(DB)에서 마련된 API를 받아와 그 API에서 필요한 데이터를 받고, 그 데이터를 통해서 HTML을 만드는 것이 모두 서버에서 이뤄진다는 뜻이다.

  • 서버가 가진 컴퓨팅 파워, 즉 자체적인 성능이 브라우저가 가진 성능보다 훨씬 우월하기 때문에 클라이언트 사이드 렌더링보다 훨씬 빠른 속도를 보인다는 장점이 있다.

  • 검색 엔진에서 서버 사이드 렌더링으로 만든 웹사이트를 우선적으로 노출시킬 수 있다. 이것은 검색 엔진 최적화(SEO)라고 한다. 서버 사이드 렌더링을 사용하면 콘텐츠가 뜨는 속도가 클라이언트 사이드 렌더링보다 빠르기 때문에, 훨씬 빠르게 웹사이트가 뜰 것이고, 그렇기 때문에 상위 노출이 가능해져 최적화에 훨씬 유리하다.

  • SSR은 때마다 클라이언트가 서버를 통해서 데이터를 요청하고, 서버가 HTML을 그려서 내려보내주는 방식을 취하기에 서버의 부하를 고려하지 않는 경우에는 초기 렌더링 자체는 SSR이 빠르다. 그러나 서버와 클라이언트 간의 채널이 느려 클라이언트가 요청한 데이터를 처리해 HTML을 생성하는 로직이 지연되는 상황이라면, 만들어진 HTML의 크기가 크면 클수록 최초 로딩 속도가 조금 느릴 수 있다는 점도 생각해야 한다.

  • 서버 사이드 렌더링 방식은 페이지 전환이 일어날 때마다 클라이언트가 데이터를 요청하고, 요청을 받은 서버는 HTML을 만들어 다시금 클라이언트로 만든 HTML을 보내는 시간이 필요하다. 따라서 이 과정이 느려지면 느려질수록 UX는 저하가 될 수밖에 없다. 그래서 서버 사이드 렌더링이 클라이언트 사이드 렌더링보다 렌더링 속도가 훨씬 빠르다 해도 서버 사이드 렌더링 방식만이 정답은 아닐 수 있다.

  • SSR은 Next.js를 사용하는 방법과 Node.js에서 템플릿 엔진을 활용하는 방법이 있다.

  • Next.js를 사용하면 API로 받아온 데이터를 바탕으로 화면에 HTML을 만들어서 내려주는 방법이 가능하다. 또한 이미지나 렌더링 최적화 등의 기능도 수행하기 때문에 훨씬 좋은 서버 사이드 렌더링을 하는 웹 앱을 만들 수 있다.

  • Node.js를 사용하게 되면 DB에 있는 데이터를 실시간으로 연동해서 템플릿화 시키는 것이 가능하다.

  • 리액트 Hydrate를 사용해서 서버 사이드 렌더링처럼 동작시키는 방법도 있다. Hydrate는 서버단에서 렌더링 된 정적 페이지와 번들링된 JS파일을 클라이언트에게 보낸 뒤, 클라이언트 단에서 HTML 코드와 React인 JS코드를 서로 매칭 시키는 과정을 말한다.

  • 물론 오늘날의 SSR은 예전과는 또 달라 새로고침을 했을 때 거의 1초도 안 되는 시간에 기존 화면에서 새로운 화면으로 순차적인 렌더링을 하기 때문에 SSR로 렌더링을 시켜도 싱글 애플리케이션 앱처럼 동작하는 데에 무리가 없어졌다. 따라서 UX 경험을 기반으로 해 렌더링 방식을 선택하는 것이 아니라, 구현하고자 하는 웹 앱의 기능에 맞춰 렌더링 방식을 선택하는 것도 하나의 개발 방식이 되었다.

0개의 댓글