>  기사  >  웹 프론트엔드  >  SSR, SSG 및 SPA에 대한 주니어 개발자의 전체 가이드

SSR, SSG 및 SPA에 대한 주니어 개발자의 전체 가이드

王林
王林원래의
2024-08-21 06:12:06703검색

The Junior Developer

모든 개발 도구 회사와 팀은 주니어 개발자가 이러한 용어에 익숙하다고 가정하는 것 같습니다.

코딩을 시작했을 때 Nuxt는 SSR 프레임워크이고, SSG용 Gatsby를 사용할 수 있으며, next.config.js에서 이 플래그 또는 저 플래그를 설정하면 SPA 모드를 활성화할 수 있다는 점을 어디에서나 보았습니다.

대체 뭐야?

첫 번째 단계로, 용어집은 다음과 같습니다. 하지만 세부 사항을 이해하는 데는 도움이 되지 않습니다.

  • CSR = 클라이언트측 렌더링
  • SPA = 단일 페이지 신청
  • SSR = 서버사이드 렌더링
  • SSG = 정적 사이트 생성

다음으로 어둠에 빛을 비춰보겠습니다.

정적 웹 서버

처음에는 웹사이트가 서버에서 요청한 HTML 파일이었습니다.

브라우저가 서버에 "/about 페이지를 건네주실 수 있나요?"라고 묻습니다. 그러면 서버는 about.html 파일로 응답합니다. 귀하의 브라우저는 해당 파일을 구문 분석하고 이와 같은 아름다운 웹사이트를 렌더링하는 방법을 알고 있습니다.

우리는 이러한 서버를 정적 웹 서버라고 부릅니다. 개발자가 직접 HTML과 CSS(그리고 약간의 JS)를 작성하고 이를 파일로 저장한 후 폴더에 저장하면 요청 시 서버가 이를 전달합니다. 사용자별 콘텐츠는 없었고 누구나 접근할 수 있는 일반적인 정적(불변) 콘텐츠만 있었습니다.

app.get('/about', async (_, res) => {
  const file = fs.readFileSync('./about.html').toString();
  res.set('Content-Type', 'text/html');
  res.status(200).send(file);
})

대화형 웹 앱 및 요청별 콘텐츠

그러나 정적인 웹사이트는 지루합니다.

사용자가 웹사이트와 상호작용할 수 있다면 훨씬 더 재미있습니다. 그래서 개발자들은 이를 가능하게 만들었습니다. JS를 터치하여 버튼을 클릭하고 탐색 모음을 확장하거나 검색 결과를 필터링할 수 있었습니다. 웹이 대화형으로 바뀌었습니다.

이는 사용자가 검색 매개변수로 보낸 내용에 따라 /search-results.html 페이지에 다른 요소가 포함된다는 의미이기도 합니다.

따라서 사용자는 검색창에 입력하고 Enter 키를 누른 다음 검색 매개변수와 함께 요청을 서버에 보냅니다. 다음으로 서버는 데이터베이스에서 검색 결과를 가져와 유효한 HTML로 변환하고 완전한 /search-results.html 파일을 생성합니다. 사용자는 응답으로 결과 파일을 받았습니다.

(요청별 HTML 생성을 단순화하기 위해 개발자는 핸들바와 같은 HTML 템플릿 언어를 개발했습니다.)

app.get('/search-results', async (req, res) => {
  const searchParams = req.query.q;
  const results = await search(searchParams);

  let htmlList = '<ul>';
  for (const result of results) {
    htmlList += `<li>${result.title}</li>`;
  }
  htmlList += '</ul>';

  const template = fs.readFileSync('./search-results.html').toString();
  const fullPage = embedIntoTemplate(htmlList, template);

  res.set('Content-Type', 'text/html');
  res.status(200).send(fullPage);
});

"렌더링"에 대한 짧은 우회

저는 오랫동안 렌더링이라는 용어를 매우 혼란스럽게 생각했습니다.

원래 의미에서 렌더링은 인간이 처리할 수 있는 이미지를 생성하는 컴퓨터를 의미합니다. 예를 들어 비디오 게임에서 렌더링은 사용자가 매력적인 3D 경험으로 사용할 수 있는 초당 60개의 이미지를 생성하는 프로세스를 의미합니다. 서버 측 렌더링에 대해 이미 들어본 적이 있는데, 그것이 어떻게 작동할 수 있는지 궁금했습니다. 서버가 사용자가 볼 수 있도록 이미지를 어떻게 렌더링할 수 있을까요?

그러나 서버측 또는 클라이언트측 렌더링의 맥락에서 "렌더링"은 다른 의미를 갖는다는 사실이 너무 늦게 밝혀졌습니다.

브라우저의 맥락에서 '렌더링'은 원래 의미를 유지합니다. 브라우저는 사용자가 (웹사이트) 볼 수 있도록 이미지를 렌더링합니다. 그러기 위해서는 최종 결과가 어떤 모습이어야 하는지에 대한 청사진이 필요합니다. 이 청사진은 HTML 및 CSS 파일 형식으로 제공됩니다. 브라우저는 해당 파일을 해석하고 이로부터 모델 표현인 DOM(문서 개체 모델)을 파생시켜 렌더링하고 조작할 수 있습니다.

좀 더 잘 이해할 수 있도록 이를 건물과 건축에 매핑해 보겠습니다. 집의 청사진(HTML 및 CSS)이 있고 건축가는 이를 책상 위의 소규모 물리적 모델(DOM)로 변환합니다. 조작할 수 있다고 생각하고 모두가 결과에 동의하면 건설 작업자는 모델을 보고 이를 실제 건물(사용자가 보는 이미지)로 "렌더링"합니다.

그러나 서버의 맥락에서 "렌더링"에 관해 이야기할 때는 구문 분석이 아닌 HTML 및 CSS 파일 생성에 대해 이야기합니다. 이 작업은 브라우저가 해석할 파일을 수신할 수 있도록 먼저 수행됩니다.

클라이언트 측 렌더링으로 넘어가서 "렌더링"에 관해 이야기할 때 DOM(브라우저가 HTML 및 CSS 파일을 해석하여 생성하는 모델)을 조작하는 것을 의미합니다. 그런 다음 브라우저는 DOM을 사람이 볼 수 있는 이미지로 변환합니다.

클라이언트 측 렌더링 및 단일 페이지 애플리케이션(SPA)

Facebook과 같은 플랫폼의 등장으로 개발자에게는 더 많고 빠른 상호작용이 필요했습니다.

대화형 웹 앱에서 버튼 클릭을 처리하는 데는 시간이 걸렸습니다. HTML 파일을 생성하고 네트워크를 통해 전송해야 했으며 사용자의 브라우저에서 이를 렌더링해야 했습니다.

All that hassle while the browser could already manipulate the website without requesting anything from the server. It just needed the proper instructions — in the form of JavaScript.

So that's where devs placed their chips.

Large JavaScript files were written and sent to the users. If the user clicked on a button, the browser would insert an HTML component; if the user clicked a "show more" button below a post, the text would be expanded — without fetching anything.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <div id="root"></div>
    <script>
      document.addEventListener('DOMContentLoaded', () => {
        const root = document.getElementById('root');

        root.innerHTML = `
            <h1>Home</h1>
            <button>About</button>
        `;

        const btn = document.querySelector('button');
        btn.addEventListener('click', () => {
          root.innerHTML = `
            <h1>About</h1>
        `;
        });
      });
    </script>
  </body>
</html>

Though the code snippet suggests the opposite, developers didn't write vanilla JavaScript.

Ginormous web apps like Facebook had so much interactivity and duplicate components (such as the infamous Like-button) that writing plain JS became cumbersome. Developers needed tools that made it simpler to deal with all the rendering, so around 2010, frameworks like Ember.js, Backbone.js, and Angular.js were born.

Of them, Angular.js was the one that brought Single Page Applications (SPAs) into the mainstream.

An SPA is the same as Client-Side Rendering, but it is taken a step further. The conventional page navigation, where a click on a link would fetch and render another HTML document, was taken over by JavaScript. A click on a link would now fire a JS function that replaced the page's contents with other, already preloaded content.

For this to work properly, devs needed to bypass existing browser mechanisms.

For example, if you click on a