Angular Universal을 사용한 서버 측 렌더링

    이 항목의 목표는 서버 측 렌더링이 무엇인지, 그리고 Ignite UI for Angular 내에서 이를 구성하는 방법을 설명하는 것입니다.

    Angular Universal

    모든 Angular 애플리케이션은 클라이언트 브라우저에서 실행되며 이로 인해 FMP(First Meaningful Paint)에서 성능 저하가 발생할 수 있습니다. 즉, 브라우저가 페이지의 기본 콘텐츠를 처음 렌더링할 때입니다. 이때 Angular Universal을 사용하면 서버의 페이지에 대한 전체 HTML을 생성할 수 있습니다. 나중에 클라이언트에서 부트스트랩되는 서버의 HTML로 클라이언트 측 페이지를 렌더링합니다. 좋아요, 그런데 어떻게 작동하나요?

    FMP는 페이지의 기본 콘텐츠가 사용자에게 표시되는 시기를 측정합니다. FCP 측정항목의 경우 사용자가 페이지를 탐색한 후 브라우저가 DOM 콘텐츠의 첫 번째 부분을 렌더링하는 데 걸리는 시간을 측정합니다. 자세한 내용은 Lighthouse 성능 점수를 참조하세요.

    How it works?

    Angular Universal을 사용하면 앱 랜딩 페이지의 정적 버전을 제공하는 동시에 전체 Angular 애플리케이션이 백그라운드에서 로드됩니다. 랜딩 페이지는 순수 HTML이며 JavaScript가 비활성화된 경우에도 표시됩니다. 서버 렌더링에 대한 자세한 내용은 여기에서 찾을 수 있습니다.

    Usage

    서버 측 렌더링은 웹에서 렌더링 지침의 많은 기술 중 하나이며 다음을 수행할 수 있습니다.

    • 웹 크롤러를 사용하면 검색에서 웹사이트의 색인을 더 많이 생성할 수 있어 검색 엔진 최적화(SEO)가 향상됩니다.
    • 첫 번째 페이지를 빠르게 표시 - 느린 초기 페이지 로드는 사용자의 관심을 끕니다(로드하는 데 3초 이상 걸리는 경우).
    • 앱 성능을 향상시키세요. First Meaningful PaintFirst Contentful Paint 모두에 긍정적인 영향을 미칠 것입니다.

    SEO 및 소셜 미디어 미리 보기를 완벽하게 제어할 수 있으며 사용자가 초기에 그려진 보기를 볼 수 있도록 하여 애플리케이션의 전반적인 인지 성능을 향상시킵니다.

    Add SSR to existing Ignite UI application

    Step 1 - Add @nguniversal

    Angular CLI 회로도를 사용하여 다음 명령을 실행할 수 있습니다.

    ng add @nguniversal/express-engine --clientProject ssr-example
    

    이 회로도는 앱 클라이언트 및 서버 구성에 대한 몇 가지 변경 사항은 물론 npm 명령 및 app.module 업데이트를 수행합니다.

    Step 2 - Define all browser-specific objects that are missing

    유니버설 앱은 브라우저가 아닌 서버에서 실행되므로 코드에서 주의해야 할 몇 가지 사항이 있습니다. window, document 또는 location과 같은 브라우저별 개체가 누락되었으므로 서버측 DOM 추상화를 위해 domino를 사용하는 것이 좋습니다. Domino는 Mozilla의 dom.js를 기반으로 하는 서버측 DOM 구현입니다.

    • install domino npm install domino- 서버 측 DOM 추상화용
    • xmlhttprequest 설치 npm i xmlhttprequest- IgxIconService를 사용하여 아이콘을 등록하는 경우
    • "server.ts" 구성
    // server.ts
    const domino = require('domino');
    const fs = require('fs');
    const path = require('path');
    const template = fs
      .readFileSync(path.join('dist/browser', 'index.html'))
      .toString();
    const window = domino.createWindow(template);
    
    // Ignite UI browser objects abstractions
    (global as any).window = window;
    (global as any).document = window.document;
    (global as any).Event = window.Event;
    (global as any).KeyboardEvent = window.KeyboardEvent;
    (global as any).MouseEvent = window.MouseEvent;
    (global as any).FocusEvent = window.FocusEvent;
    (global as any).PointerEvent = window.PointerEvent;
    (global as any).HTMLElement = window.HTMLElement;
    (global as any).HTMLElement.prototype.getBoundingClientRect = () => {
        return {
          left: '',
          right: '',
          top: '',
          bottom: ''
      };
    };
    
    // If using IgxIconService to register icons
    (global as any).XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest;
    
    // Other optional depending on your application configuration
    (global as any).object = window.object;
    (global as any).navigator = window.navigator;
    (global as any).localStorage = window.localStorage;
    (global as any).DOMTokenList = window.DOMTokenList;
    

    Step 3 - Start your universal app

    다음 명령을 실행하십시오.

    npm run build:ssr && npm run serve:ssr
    

    Angular Express 엔진 대신 서버 측 렌더링으로 Angular 앱을 실행하기 위해 ASP.NET Core 엔진을 사용할 수 있습니다.

    Build a new application from scratch

    1. ng new 또는 Ignite UI CLI ig new 명령을 사용합니다.
    2. 라이브러리의 npm 패키지를 작업 공간에 설치하고 해당 라이브러리를 사용하도록 현재 작업 디렉터리의 프로젝트를 구성하는 ng add igniteui-angular 실행합니다.
    3. ng add @nguniversal/express-engine --clientProject ig-ssr-example 사용하여 Angular Universal을 추가합니다. "ig-ssr-example"은 프로젝트 이름입니다.
    4. Ignite UI for Angular 추가(예: 그리드, 달력 등)
    5. "window", "document", "location" 등 필요한 모든 브라우저별 개체를 정의하려면 "server.ts" 파일을 구성하세요.
      • install domino npm install domino- 서버 측 DOM 추상화용
      • xmlhttprequest 설치 npm i xmlhttprequest- IgxIconService를 사용하여 아이콘을 등록하는 경우

    Use starter project

    Ignite UI for Angular 포함된 시작 프로젝트를 사용하세요. 이 프로젝트는 Angular CLI를 사용하여 Angular Universal로 간단한 애플리케이션을 빠르게 구축합니다.

    Step 1 - Clone the starter repository

    git clone https://github.com/IgniteUI/ng-universal-example.git
    

    Step 2 - Use NPM to install the needed dependencies

    npm install
    

    Step 3 - Build and start the application by using:

    npm run build:ssr && npm run serve:ssr
    

    Other considerations

    • 애플리케이션이 다른 브라우저별 개체를 사용하는 경우 조건문으로 해당 개체의 사용법을 래핑하여 브라우저의 Angular 에서만 사용할 수 있도록 합니다. @angular/common에서 isPlatformBrowserisPlatformServer 함수를 가져오고, PLATFORM_ID 토큰을 구성 요소에 삽입하고, 가져온 함수를 실행하여 현재 서버에 있는지 브라우저에 있는지 확인하면 됩니다.
    • HTML 요소 처리에 ElementRef를 사용하는 경우 요소의 속성을 조작하기 위해 NativeElement를 사용하지 마세요. 대신 Renderer2 메소드를 삽입하고 사용하세요.
    • 서버 요청에 대한 모든 URL은 절대 URL이어야 합니다. 서버에서 실행할 때 상대 URL의 데이터 요청이 실패한다는 점을 명심하세요.
    • 브라우저 이벤트를 처리하기 위해 Angular 팀은 사전 부팅 라이브러리를 제공합니다. 이 라이브러리는 이벤트를 버퍼링하고 클라이언트측 스크립트가 로드되면 이를 재생합니다.
    • Angular Universal을 사용할 때 서버는 사용자에게 표시되는 페이지를 사전 렌더링하지만 상호 작용은 제한됩니다. 클라이언트 측 앱이 백그라운드에 로드되면 서버 렌더링 페이지 표시에서 클라이언트 측 앱으로 원활하게 전환됩니다.

    Useful resources