본문 바로가기
최신 뉴스

Angular 애플리케이션의 로드 시간을 개선하는 5가지 팁

by 이스코 2023. 3. 3.

Angular는 소프트웨어 개발자들 사이에서 구조적으로 복잡하고 콘텐츠가 많은 애플리케이션을 구축하는 데 인기가 있습니다. Angular는 본질적으로 강력한 프레임워크이지만 향상된 사용자 경험을 제공할 때 성능 최적화가 문제가 될 수 있습니다. 그러나 이러한 성능 문제를 최소화하기 위해 개발자로서 시도할 수 있는 다양한 기술이 있습니다. 이 글에서는 Angular 애플리케이션에서 로드 시간을 개선하기 위한 5가지 팁과 요령을 공유합니다.

 

출처 - [https://www.syncfusion.com/blogs/post/improve-load-time-angular-app.aspx]


 

 

1. 지연 로딩 모듈 및 이미지

지연 로딩은 실제로 필요할 때까지 항목 초기화를 보류하는 설계 방식입니다. 사용하지 않을 수도 있는 개체를 로드하고 초기화하는 데 소요되는 시간과 리소스를 줄임으로써 프로그램의 성능을 향상하는 데 사용할 수 있습니다.

지연 로딩의 주요 목적은 사용자가 처음에 확인해야 하는 항목만 로드하여 Angular 애플리케이션의 주요 번들 크기를 줄이는 것입니다. Angular 앱의 초기 로드 시간이 단축됩니다.

지연 로딩 모듈

애플리케이션을 모듈화하고 레이지 로딩을 달성하기 위한 경로를 계획해야 합니다. 먼저 간단한 예를 살펴보겠습니다.

다음 예에는 3개의 모듈과 경로가 있습니다.

홈 구성 요소  초기 로드 시 사용자에게 표시되므로 즉시 로드되어야 합니다. 고객  주문 구성 요소에 대해 지연 로딩을 구현할 수 있습니다.라우팅 파일의 다음 코드 스니펫은 구성 방법을 보여줍니다. 라우팅 파일은 하위 모듈 또는 app-routing.module.ts 파일에 있을 수 있습니다.

import { NgModule } from '@angular/core' ; import { Routes , RouterModule } from '@angular/router' ; import { HomeComponent } from './home/home.component' ; import { CustomPreloadingService } from './shared/custom-preloading.service' ;     
      
     
     

const route : Routes = [ { 
    path : 'customers' , 
    loadChildren : () => import ( './customers/customers.module' ). then (( m ) => m . CustomersModule ), }, { 
    path : 'orders' , 
    loadChildren : () => import ( './orders/orders.module' ). 그러면 (( m ) => m   
     
       
  
     
       . OrdersModule ), }, { 
    경로 : '' , 
    구성 요소 : HomeComponent , }, ];
  
    
  


@NgModule ({ 
  가져오기 : [ RouterModule . forRoot ( 경로 )], 
  내보내기 : [ RouterModule ], 
  공급자 : [], }) AppRoutingModule 클래스 내보내기 {}   

   

이 코드를 사용하면 Angular는 초기 로드가 아닌 경로에 도달했을 때만 모듈 및 관련 리소스를 로드하므로 성능이 향상됩니다.

 
 

지연 로딩 이미지

뷰포트에 있을 때만 이미지를 로드하면 애플리케이션의 로드 시간을 줄이는 데 도움이 됩니다. 네이티브 지연 로딩을 구현하는 것은 간단합니다.

<img src = "testImage.png" 로딩 = "게으른" />  

loading 속성  auto , eager , lazy 를 지원합니다 . loading 속성이 lazy 로 설정되면 브라우저는 리소스가 뷰포트에 있을 때까지 리소스를 로드하지 않습니다. 불행히도 이것은 구현하기가 매우 쉽지만 Safari 브라우저에서는 지원되지

실제 이미지가 로드될 때까지 자리 표시자 이미지를 기본 이미지로 사용하여 이를 처리할 수 있습니다. 모든 브라우저와 호환되는 이미지 지연 로드를 구현하는 다른 방법도 있습니다. ng -lazyload-image는 지연 로딩 이미지에 사용할 수 있는 경량 라이브러리입니다. 리스너를 스크롤하기 위해 Intersection Observer API를 내부적으로 사용합니다.라이브러리를 설정하면 다음과 같이 사용할 수 있습니다.

<img [ defaultImage ] = "defaultImage" [ lazyLoad ] = "testImage" />

자리 표시자 이미지를 사용할 때 이미지 외부 컨테이너의 너비와 높이를 지정하여 콘텐츠 이동을 방지할 수 있습니다. 콘텐츠 이동은 나쁜 사용자 경험을 제공하기 때문입니다.

2. OnPush 변경 감지 사용

Angular 프레임워크에는 변경 감지를 위한 두 가지 전략이 있습니다.

  • 기본
  • 온푸시

기본값은 클릭 이벤트 또는 약속과 같이 애플리케이션에서 무언가가 변경될 때마다 모든 구성 요소에서 변경 감지를 트리거합니다. 더티 검사를 통해 Angular는 표현식의 이전 값과 새 값을 비교하고 보기를 업데이트해야 하는지 여부를 결정합니다. 이 기본 동작은 프로젝트가 커질 때까지 우리에게 중요하지 않습니다.

import { ChangeDetectionStrategy , Component , OnInit } from '@angular/core' ;       

@Component ({ 
  selector : 'app-orders' , 
  templateUrl : './orders.component.html' , 
  styleUrls : [ './orders.component.css' ], 
  changeDetection : ChangeDetectionStrategy . OnPush , })    


내보내기 클래스 OrdersComponent 구현 OnInit { constructor () {}     
   

  ngOnInit () {} } 

orders.component.ts 에 표시된 대로 OnPush 를 설정한 후 변경 사항을 확인할 시기를 Angular에 지정할 수 있습니다.그렇다면 변경 감지는 언제 발생합니까?

  • 입력 참조가 변경될 때.
    • 앱이 예상대로 작동하려면 데이터를 구성 요소에 @Inputs() 로 전달할 때마다 불변 객체를 사용해야 한다는 점을 기억하는 것이 중요합니다 . 모든 기본 데이터 유형은 변경할 수 없습니다. 객체 및 배열과 같은 참조 유형을 사용할 때 기존 인스턴스를 변경 하지 말고 새 인스턴스를 만드십시오.
  • 이벤트 핸들러가 트리거될 때.
    • 입력 변수의 변경 여부와 관계없이 컴포넌트 내부에서 이벤트 핸들러가 트리거되면 변경 감지가 트리거됩니다.
  • 템플릿의 비동기 파이프 링크를 사용하여 관찰 가능 항목에서 새 값을 내보낼 때.
    • Angular의 반응적 접근 방식을 따르는 것은 OnPush 변경 감지를 위한 효과적인 방법입니다.
    • 관찰 가능 항목을 @Inputs() 로 전달하거나 생성자 에서 직접 서비스(관측 가능 항목을 노출)를 주입 하고 비동기 파이프를 사용하여 템플릿에서 구독 할 수 있습니다 . 새 값이 방출되면 변경 감지가 트리거됩니다.
 
 

3. 웹팩의 번들 크기 분석

앱의 성능에 대해 우려할 때 번들의 크기는 확실히 중요합니다. webpack-bundle-analyzer 와 같은 도구를 사용하여 Angular 애플리케이션의 로드 시간에 어떤 영향을 미치는지 확인할 수 있습니다.

외부 라이브러리를 사용해야 할 때 필요한 경우가 아니면 index.html 파일에 포함하지 않고 필요할 때 라이브러리를 느리게 로드할 수 있습니다.공유 서비스를 사용하여 외부 라이브러리를 지연 로드할 수 있습니다.

import { 주입 가능 , 주입 } from '@angular/core' ; import { ReplaySubject , Observable } from 'rxjs' ; '@angular/common' 에서 { 문서 } 가져오기 ;      
      
   

@Injectable () 내보내기 클래스 ScriptLoaderService { 
  loader : { [ url : string ]: ReplaySubject <void> } = {};
          

  생성자 ( @Inject ( DOCUMENT ) 비공개 읽기 전용 문서 : 문서 ) {}    

  loadScript ( url : string ): Observable <void> { if ( this . loader [ url ]) { return this . 로더 [ URL ]. asObservable (); }   
      
       
    

    이 . 로더 [ url ] = new ReplaySubject ();   

    const 스크립트 = this . 문서 . createElement ( '스크립트' ); 
    스크립트 . type = '텍스트/자바스크립트' ; 
    스크립트 . 소스 = URL ; 
    스크립트 . 온로드 = () => { 이 . 로더 [ URL ]. 다음 (); 이 . 로더 [ URL ]. 완료 (); };     
      
      
    

    이 . 문서 . 몸 . appendChild ( 스크립트 );

    이것을 반환합니다 . 로더 [ URL ]. asObservable (); } } 
  

4. 모듈 사전 로드

지연 로딩 모듈을 구현하면 다음 단계로 넘어갈 수 있습니다. 논의한 바와 같이 지연 로드 모듈은 요청 시 리소스를 로드하므로 앱의 초기 로드 시간을 줄이는 데 도움이 됩니다. 반대로 모듈을 미리 로드하면 지연 로드된 모듈의 로드 시간을 줄이는 데 도움이 됩니다. 이렇게 하면 UI를 차단하지 않고 백그라운드에서 비동기적으로 지연 로드할 모듈을 로드하기 때문입니다.

NoPreloading은 Angular 애플리케이션의 기본 동작입니다. PreloadAllModules를 사용하여 지연 로드할 모든 모듈을 미리 로드할 수 있습니다.그러나 응용 프로그램에 많은 모듈이 있는 경우에는 그다지 효과적이지 않을 수 있습니다. 가장 좋은 방법은 다음과 같습니다.

  • 즉시 로드: 로그인 및 홈과 같은 초기에 필요한 리소스가 있는 모듈의 경우.
  • 사전 로드: 애플리케이션에서 자주 사용되는 모듈용입니다. 지연을 통한 사전 로드 및 네트워크 품질에 기반한 사전 로드와 같이 이를 구현하는 다양한 방법이 있습니다.
  • 지연 로드: 다른 모든 모듈.

자주 사용하는 모듈을 지연으로 미리 로드하기 위해 다음과 같이 PreloadingStrategy 를 구현하는 서비스를 작성할 수 있습니다.

'@angular/core' 에서 { 주입 가능 } 가져오기 ; import { PreloadingStrategy , Route } from '@angular/router' ; import { Observable , of , timer } from 'rxjs' ; import { map } from 'rxjs/operators' ;     
      
     
   

@Injectable ({ 
  providedIn : '루트' , }) 


export class CustomPreloadingService implements PreloadingStrategy { 
  preload ( route : Route , load : () => Observable <any> ): Observable <any> { const loadRoute = ( delay : number ) => 
      delay > 0 ? 타이머 ( 지연 * 1000 ). 파이프 ( 지도 (() => 로드 ())) :           
           로드 (); if ( route . data && route . data . preload ) { const 지연 = route . 데이터 . loadAfterSeconds
         ? 경로 . 데이터 . loadAfterSeconds
         : 0 ; return loadRoute ( 지연 ); } ( null ) 반환 ; } }
      
       
      
    
     
  
 
 
 

 

5. 메서드 대신 순수 파이프 사용

일부 계산을 수행하기 위해 템플릿의 메서드를 사용하면 구성 요소를 더 자주 다시 렌더링 하기 위해 변경 감지가 트리거 됩니다.이는 템플릿에 많은 상호 작용이 있고 처리량이 많을 때 성능에 영향을 미칩니다.

이 간단한 예에서 알 수 있듯이 고객 추가 버튼을 클릭한 직후 메서드가 6번 호출됩니다.

순수 파이프는 함수 매개변수가 변경될 때만 호출되기 때문에 이 문제에 대한 좋은 해결책입니다.다음에서 차이점을 볼 수 있습니다. 파이프는 고객 추가 버튼을 클릭한 후에 한 번만 호출됩니다.

다음은 add-title.pipe.ts의 샘플 코드입니다.

import { Pipe , PipeTransform } from '@angular/core' ;      

@Pipe ({ 
  이름 : 'addTitle' , }) 


내보내기 클래스 TitlePipe 구현 PipeTransform { 
  transform ( value : string ): any { 
    console . 로그 ( 'addTitle 파이프' );      

    if ( 값 === 'M' ) { 'Mr.' 반환 ; } else { 'Ms.'를 반환합니다. ; } } }    
       
      
       
    
  

결론

Angular 애플리케이션의 성능을 개선하기 위한 5가지 팁을 공유했습니다. 이 외에도 더 많은 방법을 사용하여 성능을 향상할 수 있습니다. 그러나 이러한 팁이 귀하의 탐구에 도움이 되기를 바랍니다.

읽어 주셔서 감사합니다!

Syncfusion의 Angular UI 구성요소 라이브러리는 앱을 빌드하는 데 필요한 유일한 제품군입니다. 단일 패키지에 75개 이상의 고성능, 경량, 모듈식 반응형 UI 구성 요소가 포함되어 있습니다.

기존 고객의 경우 라이선스 및 다운로드 페이지 에서 최신 Essential Studio 버전을 다운로드할 수 있습니다.아직 Syncfusion 고객이 아닌 경우 30일  무료 평가판을 사용하여  사용 가능한 기능을 확인할 수 있습니다. 또한  GitHub 에서 데모를 확인하십시오.

 

출처 - [https://www.syncfusion.com/blogs/post/improve-load-time-angular-app.aspx]