Starbucks Caramel Frappuccino
본문 바로가기
  • 그래 그렇게 조금씩
Frontend/React

Page Routing / DOM

by Toughie 2024. 6. 2.

 

페이지 라우팅

페이지 라우팅은 사용자가 요청한 경로에 따라 알맞은 페이지를 렌더링하는 과정을 의미한다.

사용자가 브라우저에서 /blog와 같은 경로를 요청하면, 서버는 해당 경로에 맞는 페이지 파일을 클라이언트로 전달하고,

클라이언트는 해당 페이지를 렌더링해서 사용자에게 보여준다.(전통적 방식)


MPA(Multi Page Application)

여러 개의 HTML 페이지로 구성된 전통적인 웹 애플리케이션 방식을 의미한다.

(과거에 만들어진 웹페이지에서 쉽게 적용된 것을 발견할 수 있다.)

 

SSR(Server Side Rendering)

서버 사이드 렌더링은 서버에서 HTML 파일을 생성해서 클라이언트에 전달하는 방식이다.

사용자가 특정 경로를 요청할 떄마다 서버가 해당 경로에 맞는 HTML 파일을 찾아 반환하는 방식을 말한다.

쉽게 말하면 서버가 모든 페이지에 대한 HTML을 가지고 있고,

요청 받을 때마다 찾아서 해당 HTML 파일을 클라이언트에 전달하는 것이다.

 

MPA의 장점

- 이미 완성된 HTML을 받아오기 때문에 빠르게 화면을 볼 수 있다.

- SEO(검색 엔진 최적화)에 유리하다.

 

MPA의 단점

- 페이지를 이동할 때마다 전체 페이지를 새로 로드하기 때문에 화면이 깜빡여서 UX적으로 좋지 않다.

- 꼭 변경이 필요한 부분만 리렌더링 되는 것이 아니라, 화면 요소가 전부 리렌더링 되기 때문에 비효율적이다.

- 요청이 많아질 경우 서버에 부하가 많이 걸릴 수 있다.


SPA(Single Page Application)

이름에서 알 수 있듯, 하나의 HTML 페이지로 구성된 웹 애플리케이션 방식이다.

초기 로드 시 단 하나의 HTML 파일만 받아오고,

이후 페이지 이동이나 데이터 변경이 필요할 때마다 필요한 부분만 동적으로 업데이트한다.

 

React는 SPA 방식이다.

 

CSR(Client Side Rendering)

서버 사이드 렌더링에서는 서버가 완성된 HTML 파일을 클라이언트에 전달해줬다면,

CSR 방식은 클라이언트(브라우저)에서 JavaScript를 실행시켜 화면을 동적으로 렌더링 하는 방식이다.

 

사용자가 브라우저를 통해 페이지를 요청하면

서버는 하나의 HTML 파일과, 페이지 렌더링과 동작에 필요한 파일묶음을 함께 전달한다.(*번들 파일)

브라우저가 번들파일에 있는 JS파일을 실행하면 페이지의 로드와 업데이트가 수행된다.

 

SPA의 장점

- 화면 깜빡임 없이 부드럽고 빠른 페이지 이동을 통해 좋은 사용자 경험을 제공할 수 있다.

- 서버의 부담을 줄여줄 수 있다.

 

SPA의 단점

- 초기 로드 시 JavaScript 파일을 모두 받아와야 하기 때문에 초기 로딩 속도가 느릴 수 있다.

- SEO(검색 엔진 최적화)에 불리할 수 있다.


Bundling(번들링)

여러 개의 JavaScript 파일을 하나로 묶는 과정을 말한다. 

여러 파일을 하나로 묶어서 클라이언트에 전달함으로써 네트워크 요청 수를 줄이고, 효율적인 로딩을 가능하게 할 수 있다.

리액트 앱에서는 보통 vite와 같은 번들러를 사용해서 이런 번들링 과정을 자동으로 처리한다.


리액트 렌더링 과정

1. 브라우저가 index.html을 로드한다.

 

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>React App</title>
  </head>
  <body>
    <div id="root"></div>
    <script src="/path/to/your/bundle.js"></script>
  </body>
</html>

 

리액트 컴포넌트들이 렌더링될 기본 HTML 파일이다.(흰 도화지로 비유할 수 있다.)

 

 

2. index.html에서 번들 파일을 로드한다.

 

 

3. 번들 파일은 *main.jsx를 실행해서 App 컴포넌트를 div#root에 렌더링 한다. 

*리액트 앱의 entry point로 ReactDOM.render 메서드를 통해 App 컴포넌트를 특정 *DOM 요소에 렌더링 한다.

 

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render(<App />, document.getElementById('root'));

 

4. 이후 페이지 이동이나 데이터 변경 시 필요한 부분만 동적으로 업데이트 된다.

 

브라우저가 JavaScript 파일을 직접 실행해서 렌더링을 담당하는 CSR 방식을 통해

페이지 이동 시 필요한 컴포넌트만 동적으로 교체함으로써 효율적인 렌더링, 좋은 사용자 경험을 제공할 수 있다.


DOM(Document Object Model)

HTML, XML 등의 문서의 구조를 표현하는 프로그래밍 인터페이스이다.

DOM은 문서의 각 요소를 객체로 나타내며, 이를 통해 스크립트나 프로그래밍 언어로 문서의 구조, 스타일, 콘텐츠를

동적으로 접근하고 변경할 수 있다.

 

브라우저는 HTML문서를 로드할 때 DOM을 생성하고,

자바스크립트는 이 DOM을 통해 웹 페이지의 요소를 선택하고 조작할 수 있다.

 

<!DOCTYPE html>
<html>
<head>
    <title>My HomePage</title>
</head>
<body>
    <h1 id="title">Hello, World!</h1>
    <p>This is a paragraph.</p>
</body>
</html>

 

위와 같이 기본적인 html 코드가 있을 때, 이것은 아래와 같은 DOM 트리 구조를 가진다.

Document
 └── html
      ├── head
      │    └── title
      └── body
           ├── h1#title
           └── p

 

DOM을 활용해서 자바스크립트로 문서의 요소를 간단하게 조작할 수 있다.

document.getElementById('title').innerText = 'Use DOM';

 

(물론 리액트에서는 위와 같은 방식 대신 state와 props을 주로 사용한다.)


Virtual DOM(가상 돔)

https://webperf.tips/tip/browser-rendering-pipeline/

 

위 이미지는 웹페이지가 렌더링 되는 흐름을 설명하고 있다.

실제로 DOM을 조작하는 것은 비용이 많이 드는 작업이다.

React와 같은 프레임워크에서는 가상 돔이라는 개념을 활용해 DOM 조작을 최적화 한다.

 

가상 DOM은 실제 DOM을 조작하기 전에, 가상의 DOM을 사용해서 변경 사항을 관리하는 방식이다.

가상 DOM은 실제 DOM의 가벼운 카피본으로, 메모리에 존재한다.

(메모리에 실제 DOM의 복사본을 가지고 있다)

 

리액트에서 가상 DOM의 동작 방식은 아래와 같다.

1. 리액트 컴포넌트가 처음 렌더링될 때 가상 DOM 트리가 생성된다.

2. 상태(state)나 속성(props)가 변경되면(업데이트가 발생하면) 리액트는 새로운 가상 DOM트리를 생성한다.

3. 기존 가상 DOM 트리와 새로운 가상 DOM 트리의 차이(Diff)를 계산한다.

4. 차이가 있는 부분만 실제 DOM에 적용해서 최소한의 변경만 수행한다.

 

위와 같은 가상 DOM 방식을 통해 모든 변경사항에 실제 DOM을 조작하지 않고, 가상 DOM 비교를 통해 

필요한 변경사항을 미리 계산해 필요한 부분만 업데이트 함으로써 성능을 크게 향상시킬 수 있다.

 

import React, { useState } from 'react';

function App() {
	const [count, setCount] = useState(0);
    
    return (
    <div>
    	<h1>{count}</h1>
        <button 
        onclick = {() => setCount(count + 1)}>
        + </button>
    </div>
    );
}

export default App;

 

위 코드는 화면에 숫자 0부터 시작해서, 버튼을 누를 때마다 1씩 증가하는 간단한 카운터 앱이다.

 

1. 초기 렌더링 시에 리액트는 가상 DOM 트리를 생성하고 실제 DOM에 렌더링 한다.

2. 버튼을 클릭하면 setCount메서드를 통해 count 상태가 변경되고, 리액트는 새로운 가상 DOM 트리를 생성한다.

3. 리액트는 기존 가상 DOM 트리와 새로운 가상 DOM 트리의 차이를 계산한다. (h1 요소의 텍스트가 변경됨)

4. 리액트가 변경된 부분만 실제 DOM에 반영하고 화면이 리렌더링 된다.

 

 

 

'Frontend > React' 카테고리의 다른 글

Vite 프로젝트 세팅  (0) 2024.06.02