내용으로 건너뛰기
Angular 앱의 성능을 개선하려면 어떻게 해야 하나요?

Angular 앱의 성능을 개선하려면 어떻게 해야 하나요?

Angular 앱의 성능을 향상시키는 방법은 무엇입니까? 이 블로그 게시물을 읽고 사용하지 않는 JavaScript 및 CSS를 줄이는 것부터 지연 로딩을 Angular 하는 것까지 방법을 알아보세요.

8min read

Angular는 최신 웹 응용 프로그램을 개발하기 위해 매우 인기 있고 널리 채택된 프레임워크가 되었습니다. 이 기술은 매우 강력하고 기능이 풍부합니다. 웹 개발자에게 필요한 모든 것이 즉시 제공되며 Angular 프레임워크를 기반으로 구축된 모든 애플리케이션을 쉽게 구성, 유지 관리 및 확장할 수 있습니다.

그리고 지금쯤이면 이미 하나 이상의 Angular 응용 프로그램을 구성했을 것이지만 최적입니까?

소프트웨어 성능 시리즈의 2부에서는 Angular 최적화에 대해 설명하면서 필자가 구축한 Angular 예제 앱을 사용하여 Angular 애플리케이션의 성능을 향상시키는 방법을 보여 주겠습니다. Chrome Dev Tools를 사용하여 초기 등대 점수를 도출하여 애플리케이션의 초기 위치를 결정합니다. 개선할 수 있는 점과 개선 방법을 살펴보겠습니다.

이 시리즈의 다른 블로그:

소프트웨어 성능[웹] 파트 I

Angular 응용 프로그램의 성능을 향상시키는 방법

이 기사에서는 필자가 준비한 샘플 Angular 응용 프로그램을 사용하겠습니다. 이 문서를 작성할 때 응용 프로그램은 다음과 같은 기능과 라이브러리를 사용합니다.

  • Angular 16
  • Ignite UI for Angular 16
  • RxJS 7
  • PWA (Angular service worker)
  • Server-side rendering (express server)
  • Angular localization

Angular Build

개발 환경에서 응용 프로그램을 실행할 때 모든 것이 잘 실행되는 것처럼 보이지만 초기 lighthouse 점수는 그리 높지 않습니다.

 Lighthouse score with development environment run

점수가 낮은 부분을 개선하기 위한 제안을 보면문제가 어디에서 왔는지 알 수 있습니다. 첫 번째 큰 문제는 클라이언트로 전송되는 리소스 (JavaScript, 스타일, 정적 리소스)의 크기입니다. 

Angular 앱의 성능을 개선할 수 있는 기회

T 그의 문제는 개발 응용 프로그램이 아닌 내 Angular 응용 프로그램의 프로덕션 빌드를 실행하여 쉽게 해결됩니다. 배포하기 전에 항상 프로덕션 구성으로 빌드하십시오. 이렇게 하면 경고가 해결되어 크기를 줄일 수 있습니다.자바스크립트그리고CSS (영어).하자 보세요에서angular.json우리의 루트에 있는 파일ANGULAR 리포지토리를 사용하여 프로덕션 빌드가 어떻게 다른지 확인할 수 있습니다. 

"configurations": {
  "production": {
    "budgets": [
      {
        "type": "initial",
        "maximumWarning": "2mb",
        "maximumError": "5mb"
      },
      {
        "type": "anyComponentStyle",
        "maximumWarning": "10kb"
      }
    ],
    "fileReplacements": [
      {
        "replace": "projects/common/src/environments/environment.ts",
        "with": "projects/common/src/environments/environment.prod.ts"
      }
    ],
    "localize": true,
    "optimization": true,
    "outputHashing": "all",
    "sourceMap": false,
    "namedChunks": false,
    "extractLicenses": true,
    "vendorChunk": false,
    "buildOptimizer": true,
    "serviceWorker": true,
    "i18nMissingTranslation": "error",
    "ngswConfigPath": "projects/bellumgens/src/ngsw-config.json"
  },
  "bg": {
    "localize": [
      "bg"
    ]
  }
}

여기에는꽤 많은구성이 있습니다. 경우 가장 중요한 것이"optimization": true 진 것입니다.프로덕션 구성으로 응용 프로그램을 실행하면 점수의 차이가로드 시간 성능 측면에서 중요합니다. 

개발 환경에서 프로덕션 빌드를 사용한 Lighthouse 점수

기회 목록을 다시 보면 제안 수가 훨씬 적습니다. 텍스트 압축에 대해 나열된 가장 큰 기회사용되지 않는 JavaScript 및 정적 리소스의 캐싱입니다.

성능 개선을 위한 나머지 기회

Angular Pre-Rendering and Server-Side Rendering 

Angular는 SPA(단일 페이지 애플리케이션) 프레임워크입니다. 기본적으로 앱의 수명 주기는 클라이언트의 요청에 따라 애플리케이션을 호스트하는 서버가 필요한 모든 스크립트 및 스타일 참조가 포함된 HTML 파일을 제공하는 방식입니다. 그러나 본문 내용이 비어 있습니다. 스크립트와 스타일이 요청되고 제공되면 응용 프로그램이 부트스트랩되고 지정된 응용 프로그램에 대한 JavaScript 논리를 기반으로 콘텐츠로 채워집니다. Angular는 초기 HTML 문서에서 실제 콘텐츠를 제공하여 이 수명 주기를 개선하는 두 가지 메커니즘을 제공합니다. 이렇게 하려면 문서를 제공하기 전에 애플리케이션의 JavaScript 논리를 실행해야 합니다. 그것을하는 방법 :

  • 빌드 시점(렌더링 전) – 대부분 정적 콘텐츠가 있는 페이지의 경우.
  • 또는 서버의 런타임(서버 쪽 렌더링) - 모든 요청에 대해 최신 콘텐츠를 제공해야 하는 더 동적인 콘텐츠가 있는 페이지의 경우.

Angular 예제 앱에 대해 서버 측 렌더링을 활성화했으며 익스프레스 엔진을 사용하여 텍스트 압축 및 정적 리소스 캐싱을 활성화하고 있습니다. 이것은 내 익스프레스 서버 로직에 다음을 추가하여 수행됩니다.

export const app = (lang: string) => {
  // server scaffolded by [ng add @nguniversal/express-engine]
...
  // enable compression [npm install compression]
  const compression = require('compression');
  server.use(compression());
...
  // Serve static files from /browser with 1y caching
  server.get('*.*', express.static(distFolder, {
    maxAge: '1y'
  }));
...
}

서버 측 렌더링으로 앱을 제공하고 등대 테스트를 다시 실행합니다. 초기 하중은 더욱 향상되어 첫 번째 콘텐츠가 포함된 페인트는 1초 미만으로 줄어들었고 속도 지수는 1.2초로 감소했습니다.

Angular 서버 측 렌더링을 통한 Lighthouse 점수

Angular 최적화를 위한 남은 기회는 사용되지 않는 JavaScript 및 CSS를 줄이는 것입니다.

성능 개선을 위한 남은 기회

이 문제를 해결하려면 몇 가지 응용 프로그램 리팩토링을 수행해야 합니다.

Angular Lazy-Loading 

사용하지 않는 JavaScript를 줄이기 위해 가장 좋은 방법은 지연 로드 경로를 만드는 것입니다. 이렇게 하면 Angular 프레임워크에 최상위 모듈에 필요하지 않은 구성 요소가 무엇인지 알려주고 JavaScript를 모듈로 분할하며, 해당 로직은 요청된 경로가 로드될 때만 로드됩니다.

이 블로그에서 사용하는 Angular 예제 앱은 홈 경로의 일부가 아닌 igx-grid와 같은 더 큰 구성 요소를 사용합니다. 이 구성 요소를 사용하여 경로를 별도의 모듈로 분리하고 있습니다. 이런 식으로, 구성 요소를 사용하는 경로가로드 된 후에 만 해당 구성 요소를로드하도록 할 것입니다. 모듈을 분리한 후 경로는 다음과 같습니다.

export const routes: Routes = [
  { path: '', component: HomeComponent },
  { path: 'register', component: RegistrationComponent },
  { path: 'unauthorized', redirectTo: 'unauthorized/', pathMatch: 'full' },
  { path: 'unauthorized/:message', component: UnauthorizedComponent },
  { path: 'emailconfirm', component: EmailconfirmComponent },
  { path: 'strategies', loadChildren: () => import('./strategies/strategies.module').then(m => m.StrategiesModule) },
  { path: 'emailconfirm/:error', component: EmailconfirmComponent },
  { path: 'players', loadChildren: () => import('./player-section/player.module').then(m => m.PlayerModule) },
  { path: 'team', loadChildren: () => import('./team-section/team.module').then(m => m.TeamModule) },
  { path: 'notifications', loadChildren: () => import('./notifications/notifications.module').then(m => m.NotificationsModule) },
  { path: 'search/teams/:query', component: TeamResultsComponent },
  { path: 'search/players/:query', component: PlayerResultsComponent },
  { path: '**', component: HomeComponent }
];

내가 team.module 사용하고있는 그리드를로드하는 것이므로 코드는 다음과 같습니다.

@NgModule({
  imports: [
    CommonModule,
    FormsModule,
    // ...
    IgxGridModule,
    // ...
    TeamComponent,
    // ...
  ]
})
export class TeamModule { }

빌드를 보면 이것은 초기 분할의 결과입니다.

Angular 앱을 지연 로드 모듈로 분리

Angular 응용 프로그램의 성능을 향상시키기 위해 수행해야 하는 또 다른 작업은 CSS의 크기를 사용되는 스타일로 제한하는 것입니다. Ignite UI for Angular UI 라이브러리로 사용하고 있으며 구성 요소 테마를 사용자 정의하고 최적화하는 방법에 대한 훌륭한 방법 기사가 있습니다.

Optimizing Images 

수행해야 하는 Angular 최적화의 또 다른 측면은 이미지를 최적화하는 것입니다. Lighthouse 검사는 유형 또는 크기별로 최적화되지 않은 이미지를 사용하고 있는지 알려줍니다. 로드하는 이미지가 해당 이미지가 들어가는 컨테이너보다 크지 않고 최적의 인코딩을 사용하는지 확인하십시오. 이제 이미지에 .webp 형식을 사용합니다. 품질이 약간 떨어지지만 여전히 응용 프로그램에는 최고 충실도의 이미지가 필요하지 않습니다.

이미지는 로드된 후 레이아웃 이동을 일으킵니다. 따라서 이미지에 width 및 height 속성을 설정하여 브라우저가 이미지를 로드하기 전에 치수를 알 수 있도록 하는 것이 좋습니다. 이미지에서 종횡비 설정(너비 및 높이)이 누락된 경우 Lighthouse에서 경고합니다. 이렇게 하면 레이아웃 이동이 줄어들거나 완전히 제거됩니다.

NgOptimizedImage to Enforce Image Best Practices 

Angular는 이미지 모범 사례를 적용하고 이미지 로드를 최적화하는 지시문을 노출합니다. NgOptimizedImage 라고 하며 사용하기가 다소 쉽습니다. 아직 NgModule 기반 Angular 응용 프로그램에 있는 경우 가져오 CommonModule 거나 사용하려는 구성 요소를 가져오기 NgOptimizedImage만 하면 됩니다. 그런 다음 를 사용하여 src 이미지 소스 속성을 설정하는 대신 사용합니다 ngSrc.

<img ngSrc="/assets/wallpapers/strat-editor.webp" width="600" height="347" class="preview-image" alt="Strategy Editor" />

마지막으로,각 이미지의 로딩 우선순위를 추가로 지정하고 중요하지 않은 모든 이미지를 지연 로드하도록 앱에 지시할 수 있습니다. width 및 height 속성을 제거하면 앱을 실행하는 것은 다음과 같습니다.

 NgOptimizedImage enforcing best practices

그리고 그게 다야.

싸다...

Angular 애플리케이션의 성능을 개선하려면 앱이 다양한 조건에서 효율적이고 안정적으로 작동하도록 하기 위해 지속적인 모니터링, 최적화 및 모범 사례가 필요할 수 있습니다. 그러나 결국 이것이 최고의 UX를 제공하고, 사용자를 유치 및 유지하고, 경쟁력을 유지하고, 비즈니스 성공을 달성하는 방법입니다.

Ignite UI for Angular

데모 요청