본문으로 건너뛰기

SSR 과 당시의 JSP, PHP 는 어떤 차이가 있는가?

무료2020-10-18#Mind#SSG#static site generation#静态渲染#预渲染#服务端渲染

프론트엔드와 백엔드 계층화 이전의 긴 기간 동안 서버 사이드 렌더링이 주류였다 (JSP, PHP). 이제 돌고 돌아 시작점으로 돌아온 것 같다

서문에

SSR(Server-Side Rendering) 은 새로운 개념이 아니며, 프론트엔드와 백엔드 계층화 이전의 긴 기간 동안 서버 사이드 렌더링이 주류였습니다 (JSP, PHP). 서버 측에서 완전한 HTML 페이지를 생성합니다

(프론트엔드 렌더링 모드 탐색 에서 발췌)

즉, SSR 에서 CSR 로의 대변혁을 겪은 후, 이제 다시 CSR 에서 출발하여 SSR 의 가능성을 탐색하고 있습니다……마치 돌고 돌아 시작점으로 돌아온 것 같습니다. 이 사이에 무슨 일이 있었을까요? 현재의 SSR 과 당시의 JSP, PHP 는 어떤 차이가 있을까요?

一.SSR 이 대행其道

포럼, 블로그, 채팅실이 여전히 활발했던 시대로 돌아가면, 업계의 베스트 프랙티스는 JSP, PHP, ASP/ASP.NET 기반의 동적 웹사이트가었습니다

PHP 를 예로 들면:

<?php if ( count( $_POST ) ): ?>
<?php include WTG_INCPATH . '/wechat_item_template.php' ?>
<div style="...">

  <div id="wechat-post" class="wechat-post" style="...">
    <div class="item" id="item-list">
    <?php
        $order = 1;
        foreach ( $_POST['posts'] as $wechat_item_id ) {
        echo generate_item_list( $wechat_item_id, $order );
            $order++;
        }
    ?>
    </div>
    <?php
    $order = 1;
    foreach ( $_POST['posts'] as $wechat_item_id ) {
    echo generate_item_html( $wechat_item_id, $order );
    $order++;
    }
    ?>
    <fieldset style="...">
      <section style="...">
        <p style="...">如果心中仍有疑问,请查看原文并留下评论噢。(<span style="font-size:0.8em; font-weight:600">特别要紧的问题,可以直接微信联系 ayqywx</span>)</p>
      </section>
    </fieldset>
</div>
<script>
    function refineStyle () {
        var post = document.getElementById('wechat-post');
        // ul ol li
        var uls = post.getElementsByTagName('ul');
        for (var i = uls.length - 1; i >= 0; i--) {
            uls[i].style.cssText = 'padding: 0; margin-left: 1.8em; margin-bottom: 1em; margin-top: -1em; list-style-type: disc;';
            uls[i].removeAttribute('class');
        };
    }

    document.addEventListener('DOMContentLoaded', function() {
        refineStyle();
    });
  </script>
</div>

<?php endif ?>

(ayqy/wechat_subscribers 에서 발췌. 微信公衆平台图文消息 자동 생성 에 사용하는 WordPress 플러그인)

이 시기 웹 페이지 내용은 완전히 서버 측에서 렌더링되었으며, 클라이언트 (브라우저) 가 수신하는 것은 서비스 데이터가 융합된 HTML 과 소량의 인라인 (폼) 인터랙션 로직 및 스타일 규칙이었습니다. 초기의 대량 동적 웹사이트를 지탱하던 것은 바로 이순수 SSR 모드였습니다

하지만 기술 실천의 심화에 따라, 이 모드는 점차 몇 가지 문제를 노출시켰습니다:

  • 성능이 나쁨: 모든 요청이 올 때마다 데이터 로직과 뷰 로직을 다시 실행하고 HTML 을 동적으로 생성해야 함. 그중很大一部分의 내용은 같은데도 불구하고

  • 머신 비용이 높음: Tomcat/Apache 등의 애플리케이션 서버의 병행 처리 능력은 [nginx](/articles/nginx-https 反向代理/) 등의 Web 서버에 훨씬 미치지 못함. 따라서 더 많은 머신을 배포해야 함

  • 개발/유지가 어려움: 프론트엔드와 백엔드 코드가 섞여 있어, 인원 협력이 문제가 되고, 수정 유지에 매우 신중해야 함 (태그 구조가 파괴되기 쉬움)

이러한 문제에 직면하여, 두 가지思路가 점차 명확해졌습니다.동정분리전후단 계층화입니다. 전자는 성능과 머신 비용 문제를 해결하고, 후자는 개발/유지 문제를 해결합니다

二.동정분리

Web 서버의 정적 리소스 처리 우위를 충분히 활용하고, 동시에 애플리케이션 서버의 부담을 덜기 위해, 리소스를 두 가지 유형으로 나눕니다:

  • 정적 리소스: 이미지, CSS, JS 등의 공용으로, 구체적 사용자와 무관한 리소스

  • 동적 리소스: 애플리케이션 로직, 데이터 조작 등 구체적 사용자와 밀접하게 관련된 리소스

두 리소스를 분리하여 배포하고, 정적 리소스는 Web 서버 또는 CDN 에 배포하고, 애플리케이션 서버에는 동적 리소스만 배포합니다. 이렇게 하면, 정적 리소스 응답이更快해지고 (브라우저 캐시, CDN 가속), 애플리케이션 서버 압력이 작아지며, 모두 기뻐합니다

하지만, 뷰 로직이 빠졌습니다. HTML 은 정적 리소스일까요 동적 리소스일까요?

전후단 계층화는 이 문제에 답하기 위한 것입니다

三.전후단 계층화

뷰 로직의 특수한 점은:

  • 데이터와 밀접하게 관련됨

  • 서버 측과 클라이언트 측 모두 뷰 로직을承载할 수 있음

즉, HTML 뷰 구조의 생성과 유지 작업은, 서버 측에서 완성할 수도 있고, 클라이언트 측에서 완성할 수도 있으며, 모두 서비스 데이터에 의존합니다. 하지만 서버 측과 비교하여, 클라이언트 측 환경에는 몇 가지 우위가 있습니다:

  • 새로고침 (페이지 재요청) 없이도 뷰 업데이트 가능

  • 무료 계산 리소스

따라서, 뷰 로직은 클라이언트 측에划分되었습니다 (즉 CSR). 데이터 인터페이스를 경계로, 전후단 두 층으로 나뉩니다:

  • 백엔드: 데이터 및 데이터 조작 지원 제공

  • 프론트엔드: 데이터의 제시와 인터랙션 기능 담당

自此, 전후단은 각기其职를 다하고, 프론트엔드는 사용자 체험 향상에 전념하고, 백엔드는 업무 영역에 전념하며, 병행 이터레이션하며, (인터페이스 변화를涉及하지 않을 때) 서로 영향을 주지 않습니다

四.CSR 이如日中天

전후단 계층화 후, CSR 의 황금 시대에 들어섰고, 기능 플러그인, UI 라이브러리, 프레임워크, 컴포넌트 등 여러 종류의 코드复用方案을 탐색해냈고, 최종적으로 번영한 컴포넌트 생태를 형성했습니다

컴포넌트화 개발 방식 아래에서, 순수 CSR 모드가日益盛行했습니다:

<!DOCTYPE html>
<html>
<head>
    <title>My Awesome Web App</title>
    <meta charset="utf-8">
</head>
<body>
    <div id="app"></div>
    <script src="bundle.js"></script>
</body>
</html>

이 모드에서는, 거의 모든 페이지 내용이 클라이언트 측에서 동적으로 렌더링됩니다. 뷰 생성, 데이터 요청, 데이터와 템플릿 융합, 인터랙션 기능을 포함한 모든 작업을, 한 세트의 데이터 구동형 컴포넌트 렌더링 메커니즘에 전권 관리시키고, 컴포넌트 이하의 DOM 구조 유지 등 작업에 주목할 필요가 없어져, 효과적으로 프론트엔드의 생산 효율을 향상시켰습니다. 하지만 몇 가지 문제도随之而来했습니다:

  • 컴포넌트 트리의 첫 렌더링 완료 전에, 페이지 상에는 loading 을 포함한 어떤 내용도 표시할 수 없음

  • 데이터 요청은 소속 컴포넌트가 렌더링을 시작한 후에야 보낼 수 있음

이러한 문제의 근원은 현재의컴포넌트 렌더링 플로우가 동기 블로킹이라는 것으로, 수屏 성능에 도전을 제기했습니다:

-低端 장비에서는 JS 실행 효율이 낮고, 백屏 시간이 김

-弱網 환경에서는 데이터返回이 느리고, loading 시간이 김

CSR 은 사용자 장비의 계산 리소스를 이용했지만, 동시에 그 성능, 네트워크 환경 등의 불가控 요인의 제약도 받았습니다. 그래서,大家는 다시目光을 SSR 에聚集시켰습니다

五.SSR 이東山再起

SSR 모드에서는, 수屏 내용은 서버 측에서 생성되고, 클라이언트는 응답 HTML 을 수신한 후, 컴포넌트 트리의 렌더링 완료를 기다리지 않고 직접 내용을呈現할 수 있습니다

핵심 사상은 모두 서버 측에서 페이지 렌더링 작업을 완성하는 것이지만, 현재의 SSR 은先前과 크게 다릅니다.体现在:

  • 출발점:更快, 더 안정적으로 수屏 내용을呈現하기 위해

  • 성숙도: 프론트엔드의 성숙한 컴포넌트 체계, 모듈 생태 위에建立되었고, Node.js 기반의 동구方案이 베스트 프랙티스가 됨

  • 독립성:仍然 olarak 전후단 계층화를 유지하고, 업무 영역의 애플리케이션 서비스와 강耦合하지 않음

즉, 현재의 SSR 은 프론트엔드 층의 문제를 해결하기 위해 있으며, CSR 과 결합하여 내용 로드 체험을 최적화하는 것으로, CSR 의 다년의 적전之上的 확장이며, 기존 프론트엔드 기술 생태와 양호한 상용성을 유지하고 있습니다. 반면, 당시의 SSR 은更多的是기능을 실현하고, 온饱 문제를 해결하기 위한 것이었습니다

再看 당시 SSR 이 직면한 몇 가지 문제:

  • 성능이 나쁨: 모든 요청이 올 때마다 데이터 로직과 뷰 로직을 다시 실행하고 HTML 을 동적으로 생성해야 함. 그중很大一部分의 내용은 같은데도 불구하고

  • 머신 비용이 높음: Tomcat/Apache 등의 애플리케이션 서버의 병행 처리 능력은 [nginx](/articles/nginx-https 反向代理/) 등의 Web 서버에 훨씬 미치지 못함. 따라서 더 많은 머신을 배포해야 함

  • 개��/유지가 어려움: 프론트엔드와 백엔드 코드가 섞여 있어, 인원 협력이 문제가 되고, 수정 유지에 매우 신중해야 함 (태그 구조가 파괴되기 쉬움)

SSR 을 도입한 후 이러한 문제들이卷土重来했습니다. 하지만 이러한 해의 기술 발전은 이러한 문제들을 해결하기 위한 새로운思路를 제공했습니다:

  • 실시간 렌더링의 성능 문제: 동정분리의思路仍然 olarak 적용 가능. 예를 들어 Static Generation

  • 서버 리소스 비용 문제: 클라우드 계산의 발전은 머신 비용을 대폭 낮출 전망. 예를 들어 Node FaaS

  • SSR 부분과 CSR 부분의 개발/유지 문제: 동구는 개발/유지 난제 해결에 새로운思路를 제공했습니다 (이전의思路는 전후단 계층화였지만, 이번에는 나눌 수 없습니다). 동일한 코드를 유지하고, 다른 실행 환경에서 실행하여 다른 형식의 목표 산출물을 출력합니다

그중, Static Generation(SSG, Static Site Generation 이라고도 함) 은 컴파일 시 정적 HTML 을 생성하고 (CDN 에 배포 가능), 실시간 렌더링의 성능开销를回避합니다:

Static Generation (Recommended): The HTML is generated at build time and will be reused on each request.

하지만, 모든 페이지가 컴파일 시 정적 생성할 수 있는 것은 아닙니다. 실행 가능한 실천方案은 SSR 과 Static Generation 을 결합하는 것으로, 내용이 개별화 데이터에 의존하거나, 빈번하게 업데이트되는 페이지만 SSR 을 수행하고,其余의 장면에서는 모두 Static Generation 을 수행합니다:

You should ask yourself: "Can I pre-render this page ahead of a user's request?" If the answer is yes, then you should choose Static Generation.

至此, 침적 다년의 SSR 은 다시 새로운 활력을焕発했습니다

참고 자료

댓글

아직 댓글이 없습니다

댓글 작성