Angular를 활용한 싱글 페이지 어플리케이션(SPA) 구축하기: 실질적인 코드로 이해하는 로딩 시간 최적화 전략

Angular 이해

Angular는 웹 어플리케이션을 생성하기 위한 플랫폼이며, TypeScript를 기반으로 한 프레임워크입니다. 모듈로 구성된 구조로 대규모 프로젝트에도 적합하며, 라이브러리와 툴들, 테스팅을 위한 기능으로 다양한 웹 어플리케이션 개발에 사용됩니다.

 
  import { Component } from '@angular/core';

  @Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
  })
  export class AppComponent {
    title = 'Hello, Angular!';
  }

싱글 페이지 어플리케이션(SPA) 개념

SPA는 Single Page Application의 약자로, 모든 내용이 한 페이지 내에서 이루어지는 웹 어플리케이션입니다. 사용자의 액션에 따라 동적으로 현재 페이지를 재작성하므로, 사용자는 페이지 간 네비게이션이 부드럽고 빠르다는 느낌을 받을 수 있습니다.

 
  import { NgModule } from '@angular/core';
  import { RouterModule, Routes } from '@angular/router';
  import { PageComponent } from './page.component';

  const routes: Routes = [
    {path: '', redirectTo: '/page', pathMatch: 'full'},
    {path: 'page', component: PageComponent}
  ];

  @NgModule({
    imports: [RouterModule.forRoot(routes)],
    exports: [RouterModule]
  })
  export class AppRoutingModule { }

개발 환경 설정

Angular 설치

먼저, Node.js와 npm이 설치되어 있는지 확인해야 합니다. 아래의 명령어를 통해 둘의 버전을 확인할 수 있습니다.

 
  node -v
  npm -v

Angular CLI를 설치하기 위해선 npm을 통해 전역에 설치를 진행합니다. 아래의 명령어로 설치할 수 있습니다.

 
  npm install -g @angular/cli

프로젝트 설정

Angular CLI를 사용하여 새로운 프로젝트를 생성해봅시다. 아래의 명령어로 새 프로젝트를 생성할 수 있습니다.

 
  ng new my-app

생성된 프로젝트로 이동 후, 서버를 실행해봅시다.

 
  cd my-app
  ng serve

이후 브라우저에서 localhost:4200으로 접속하면, Angular로 만들어진 첫 페이지를 볼 수 있습니다.


싱글 페이지 어플리케이션 구조와 흐름

SPA 구조

싱글 페이지 어플리케이션(SPA)은 이름에서 알 수 있듯이 단 하나의 페이지로 구성된 어플리케이션입니다. 우선적으로 전체 페이지를 불러온 후, 사용자와의 상호작용에 따라 필요한 부분만 업데이트합니다. 이러한 구조는 페이지를 새로로드하지 않고도 인터페이스를 빠르게 업데이트 할 수 있게 해줍니다.

Angular 라우팅의 이해

Angular의 라우팅은 SPA의 핵심 기능 중 하나입니다. 라우팅은 사용자가 특정 URL을 방문할 때 어떤 View가 표시될지를 정의합니다. Angular에서는 RouterModule을 사용하여 라우트를 정의하고 관리합니다.

아래 예제처럼 라우팅 모듈을 생성하고, 이 모듈 내에서 라우트 경로와 각 경로에 대응하는 컴포넌트를 정의합니다.

 
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

// Components
import { HomeComponent } from './home/home.component';
import { AboutComponent } from './about/about.component';

const routes: Routes = [
    { path: '', redirectTo: '/home', pathMatch: 'full' },
    { path: 'home', component: HomeComponent },
    { path: 'about', component: AboutComponent }
];

@NgModule({
    imports: [RouterModule.forRoot(routes)],
    exports: [RouterModule]
})
export class AppRoutingModule { }

위 코드에서는 두 개의 라우트를 정의했습니다. 첫번째 라우트는 기본 URL(‘/’ 또는 빈 경로)에 접속했을 때 ‘home’으로 리다이렉트하도록 설정되었습니다. 두번째와 세번째 라우트는 각각 ‘/home’, ‘/about’ 경로에 접속했을 때 HomeComponent, AboutComponent를 보여줍니다.


Angular 코드 작성과 실행

기본 코드 작성

Angular 어플리케이션은 컴포넌트와 모듈로 구성되어 있습니다. 컴포넌트는 화면에 보여질 부분의 상태와 로직을 담당하고, 모듈은 여러 컴포넌트들을 하나로 묶는 역할을 합니다.

아래는 기본적인 Angular 컴포넌트 코드입니다:

 
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'My first Angular App!';
}

컴포넌트 세분화

Angular에서는 컴포넌트 세분화를 통해 코드를 재사용하고 관리성을 높일 수 있습니다. 예를 들어, ‘header’, ‘main’, ‘footer’의 세 부분으로 화면을 분할하여 각각 다른 컴포넌트로 만들 수 있습니다.

다음은 ‘header’ 컴포넌트의 예입니다:

 
import { Component } from '@angular/core';

@Component({
  selector: 'app-header',
  templateUrl: './header.component.html',
  styleUrls: ['./header.component.css']
})
export class HeaderComponent {
  title = 'My Application';
}

위와 같이 여러 컴포넌트를 세분화하면 각 컴포넌트가 자신의 역할에만 집중하면서 코드의 재사용성과 유지보수성이 향상됩니다.


로딩 시간 최적화 개념

로딩 최적화의 필요성

웹 사이트나 웹 어플리케이션에 방문하는 사용자들은 대부분 빠른 로딩 시간을 기대합니다.따라서 빠르게 페이지를 로딩하는 것은 사용자 경험을 향상시키는 중요한 요소입니다.특히 Angular와 같은 싱글 페이지 애플리케이션에서는 초기 로딩 시간이 길 수 있으므로 최적화가 필요합니다.

최적화 기법 소개

Angular에서는 여러 가지 최적화 기법인 Lazy Loading, Ahead-of-Time Compilation 등을 제공합니다.

Lazy Loading은 특정 모듈이 필요할 때까지 로딩을 늦추는 기법으로, 애플리케이션의 초기 로딩 시간을 대폭 줄일 수 있습니다. 아래는 라우터를 사용해서 Lazy Loading을 적용하는 예제입니다:


const routes: Routes = [
  {
    path: 'lazy',
    loadChildren: () => import('./lazy/lazy.module').then(m => m.LazyModule)
  },
  { path: '**', component: NotFoundComponent }, 
];

Ahead-of-Time (AOT) Compilation은 브라우저에서 코드를 효율적으로 실행하도록 애플리케이션을 미리 컴파일하는 기법입니다. AOT 컴파일을 사용하면 런타임 중에 컴파일 할 필요가 없으므로 로딩 시간이 획기적으로 감소합니다.

이외에도 코드 분할, 트리 쉐이킹 등 다양한 최적화 기법을 사용하여 애플리케이션의 퍼포먼스를 향상시킬 수 있습니다.


Angular Lazy Loading

Lazy Loading의 원리

Lazy Loading은 특정 컴포넌트 혹은 모듈이 실제로 필요할 때까지 그 로딩을 지연하는 방식입니다. 이 기법은 초기 애플리케이션 로딩 속도를 빠르게 하고, 메모리 사용량을 최적화하는 데 유용합니다.

Angular에서의 Lazy Loading 구현

Angular에서 Lazy Loading은 라우팅 모듈을 통해 구현할 수 있습니다. 필요한 모듈만 불러오도록 라우트 설정을 하면, 애플리케이션 초기 로딩 시 구성 요소의 불필요한 로딩을 방지할 수 있습니다.

다음은 Angular에서 Lazy Loading을 구현한 코드 예시입니다:


import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

const routes: Routes = [
  {
    path: 'users',
    loadChildren: () => import('./users/users.module').then(m => m.UsersModule)
  },
  // more routes...
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

위 예시에서는 ‘users’ 경로에 접근했을 때 ‘UsersModule’을 로드하도록 설정하였습니다. 이렇게하면, 사용자가 ‘users’ 경로를 방문하기 전까지는 ‘UsersModule’ 코드가 로드되지 않습니다. 결과적으로 애플리케이션의 초기 로딩 시간이 단축됩니다.


성능 측정 방법

성능 측정 툴 소개

성능 최적화를 위해 측정을 반복하고 다양한 방법을 시도해야합니다. 이때 사용할 수 있는 여러 무료 툴들이 존재합니다. 대표적인 성능 측정 툴로는 Google에서 제공하는 Lighthouse, WebPageTest, Chrome DevTools Performance Panel 등이 있습니다.

측정 및 분석 방법

이 섹션에서는 Lighthouse를 가지고 어떻게 성능 측정을 하는지 설명합니다.
Lighthouse는 웹 앱의 품질을 분석하는 오픈 소스 툴입니다. 성능, 접근성, Progressive Web Apps, SEO 등 다양한 측면에서 웹 앱을 분석하고, 각 항목에 대한 점수를 제공하며 문제를 발견하면 개선 방안을 제시해줍니다.

Chrome DevTools를 사용하여 Lighthouse를 실행하는 방법은 다음과 같습니다:


1. Chrome DevTools를 엽니다 (F12 키 또는 Ctrl + Shift + I).
2. 상단 메뉴에서 'Lighthouse' 탭을 클릭합니다.
3. 'Generate report' 버튼을 클릭합니다.

성능 측정을 위해 필요로 하는 항목을 선택하고, 보고서 생성을 클릭하면 해당 페이지에 대한 성능 분석이 이루어집니다. 분석이 끝나면 점수와 개선 사항을 보여줍니다.


최적화 전후 성능 비교

비교 대상 선정

성능 최적화를 진행하기 전 웹사이트의 성능 지표를 측정합니다. 이때 필요한 지표는 시나리오에 따라 달라질 수 있지만, 로딩 시간(First Contentful Paint, Largest Contentful Paint), 인터렉션 지연 시간(Time to Interactive) 등이 일반적입니다. 향후 최적화를 진행한 후, 이 지표들을 기준으로 웹사이트의 성능이 어떻게 변화했는지를 비교 분석하게 됩니다.

결과 분석

최적화 전 후에 수행한 성능 측정 결과를 비교하여 최적화가 성능에 어떤 영향을 미쳤는지를 분석합니다. 이때, 특정 페이지 단위가 아닌 전체 시스템의 성능 변화를 파악하는 것이 중요합니다. 또한, 결과가 예상과 다르게 나왔을 경우 원인을 찾아 개선 방안을 모색해야 합니다.

결론적으로, 성능 측정은 웹사이트 최적화의 중요한 요소로서, 지속적인 모니터링과 분석을 통해 서비스 품질을 높이는데 이용됩니다.


Lazy Loading 장단점 및 주의사항

Lazy Loading 이란?

Lazy Loading은 지연 로딩 또는 게으른 로딩이라고도 불리며, 웹페이지에서 사용자가 필요로 할 때만 리소스(보통 이미지나 비디오)를 로딩하는 기법입니다. 이 기법을 사용하면 페이지 로딩 시간을 크게 단축시킬 수 있습니다. 아래는 이미지에 Lazy Loading을 적용하는 일반적인 방법을 보여주는 코드입니다.


// 예시 이미지
<img data-src="image.jpg" alt="image" />

// 자바스크립트로 이미지에 Lazy Loading 적용
const images = document.querySelectorAll('[data-src]');
const config = {
    rootMargin: '0px 0px 50px 0px',
    threshold: 0
};
let observer = new IntersectionObserver(function(entries, self) {
    entries.forEach(entry => {
        if (entry.isIntersecting) {
            preloadImage(entry.target);
            self.unobserve(entry.target);
        }
    });
}, config);
images.forEach(image => {
    observer.observe(image);
});

function preloadImage(img) {
    const src = img.getAttribute('data-src');
    if (!src) {
        return;
    }
    img.src = src;
}

장점

  • 페이지 초기 로딩 속도를 향상시킵니다. 사용자가 페이지를 방문할 때 모든 리소스를 로딩하지 않기 때문에 로딩 시간이 훨씬 짧아집니다.
  • 사용자가 페이지의 모든 부분을 방문하지 않는 경우, 불필요한 리소스 로딩을 방지하여 트래픽을 절약할 수 있습니다.

단점

  • 스크롤링 도중에 이미지 로딩이 이루어져서 사용자 경험에 방해가 될 수 있습니다.
  • 웹 크롤러가 Lazy Loading을 지원하지 않는 경우, 해당 리소스를 인식하지 못하고 넘어갈 수 있습니다.

주의사항

  • Lazy Loading을 적용하더라도, 사용자에게 한눈에 보일 수 있는 핵심적인 이미지들은 페이지 로딩과 동시에 로딩되도록 해야 합니다.
  • Lazy Loading을 적용할 때 서버의 트래픽을 효율적으로 관리하기 위해, 적절한 크기의 리소스를 로딩하도록 고려해야 합니다.

프로젝트 마무리와 정리

프로젝트 마무리

프로젝트가 마무리 단계에 이르렀을 때, 남은 작업을 정리하고 필요한 기능들이 모두 구현되었는지 확인하는 과정이 필요합니다. 이를 위해 사용하는 방법 중 하나는 ‘체크리스트’를 만드는 것입니다. 체크리스트에는 프로젝트의 목표, 구현할 기능들, 테스트해야 할 사항 등이 포함됩니다. 프로젝트의 주요 기능이 모두 구현되었으면, 이를 확인할 수 있는 코드를 작성해야 합니다.


# 기능 체크 코드 예시:
def test_all_features():
    assert feature1() == True
    assert feature2() == True
    assert feature3() == True

test_all_features()  # 모든 기능이 정상적으로 작동하면 아무런 메세지가 출력되지 않음.

프로젝트 정리

프로젝트의 마지막 단계는 코드 정리입니다. 이 단계에서는 주석을 작성하고, 불필요한 코드를 제거하며, 코드의 가독성을 향상시킵니다. 테스트 코드를 작성하여 프로그램이 예상대로 작동하는지 확인하는 것도 중요합니다.


# 코드 정리 예시:
def function_example():
    """
    이런 식으로 주석을 작성하여 함수의 기능을 설명합니다.
    """
    # 불필요한 코드 제거
    necessary_code...

코드 정리가 완료되면, 작성한 코드와 프로젝트 문서를 검토하여 마무리합니다. 들여쓰기, 주석, 변수명 등 코드 스타일 가이드라인을 준수했는지 확인하고, 모든 문서가 완성되었는지 확인해 보세요.


Leave a Comment