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 Paint와 First 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
-
ng new
또는 Ignite UI CLIig new
명령을 사용합니다. - 라이브러리의 npm 패키지를 작업 공간에 설치하고 해당 라이브러리를 사용하도록 현재 작업 디렉터리의 프로젝트를 구성하는
ng add igniteui-angular
실행합니다. -
ng add @nguniversal/express-engine --clientProject ig-ssr-example
사용하여 Angular Universal을 추가합니다. "ig-ssr-example"은 프로젝트 이름입니다. - Ignite UI for Angular 추가(예: 그리드, 달력 등)
- "window", "document", "location" 등 필요한 모든 브라우저별 개체를 정의하려면 "server.ts" 파일을 구성하세요.
- install domino
npm install domino
- 서버 측 DOM 추상화용 - xmlhttprequest 설치
npm i xmlhttprequest
- IgxIconService를 사용하여 아이콘을 등록하는 경우
- install domino
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
에서isPlatformBrowser
및isPlatformServer
함수를 가져오고,PLATFORM_ID
토큰을 구성 요소에 삽입하고, 가져온 함수를 실행하여 현재 서버에 있는지 브라우저에 있는지 확인하면 됩니다. - HTML 요소 처리에 ElementRef를 사용하는 경우 요소의 속성을 조작하기 위해 NativeElement를 사용하지 마세요. 대신 Renderer2 메소드를 삽입하고 사용하세요.
- 서버 요청에 대한 모든 URL은 절대 URL이어야 합니다. 서버에서 실행할 때 상대 URL의 데이터 요청이 실패한다는 점을 명심하세요.
- 브라우저 이벤트를 처리하기 위해 Angular 팀은 사전 부팅 라이브러리를 제공합니다. 이 라이브러리는 이벤트를 버퍼링하고 클라이언트측 스크립트가 로드되면 이를 재생합니다.
- Angular Universal을 사용할 때 서버는 사용자에게 표시되는 페이지를 사전 렌더링하지만 상호 작용은 제한됩니다. 클라이언트 측 앱이 백그라운드에 로드되면 서버 렌더링 페이지 표시에서 클라이언트 측 앱으로 원활하게 전환됩니다.
Useful resources
- Angular 유니버설 가이드
- Ignite UI 스타터 키트
- 서버 사이드 렌더링 용어
- Ignite UI for Angular 시작하기
- Ignite UI CLI 가이드
- Ignite UI for Angular