Image Optimization และ Lazy Loading ใน Angular

Image Optimization คือการลดขนาดและควบคุมการโหลดรูปภาพให้เหมาะกับหน้าจอ ส่วน Lazy Loading คือการโหลด resource หรือ route เมื่อต้องใช้จริง เพื่อลด Initial Bundle Size และปรับปรุงประสบการณ์ผู้ใช้

Timeline/ประวัติศาสตร์

%%{init: {"theme": "base", "themeVariables": {"primaryColor": "#fabd2f", "primaryTextColor": "#282828", "primaryBorderColor": "#b57614", "lineColor": "#7c6f64", "secondaryColor": "#83a598", "tertiaryColor": "#b8bb26", "background": "#fbf1c7", "mainBkg": "#ebdbb2", "fontFamily": "Tahoma, sans-serif"}}}%%
flowchart LR
  subgraph Era1["ยุคโหลดทุกอย่าง / Eager Loading"]
    A["img src ใหญ่
โหลดทันทีทุกภาพ"] end subgraph Era2["ยุค Lazy Loading / Performance"] B["loading=lazy
โหลดเมื่อใกล้เห็น"] C["Lazy Routes
แยก bundle"] end subgraph Era3["ยุค Angular Optimization"] D["NgOptimizedImage
ngSrc"] E["@defer
โหลด component เมื่อจำเป็น"] end A --> B --> C --> D --> E

แนวคิดสำคัญ

ตารางเทคนิค Performance

เทคนิค ช่วยเรื่อง ตัวอย่าง
NgOptimizedImage รูปภาพโหลดเหมาะสม [ngSrc]
priority LCP image hero image
Lazy Route ลด initial bundle loadChildren
@defer เลื่อนโหลด UI dashboard widget
preconnect ลด latency CDN image host

Mermaid Diagram: Loading Strategy

%%{init: {"theme": "base", "themeVariables": {"primaryColor": "#fabd2f", "primaryTextColor": "#282828", "primaryBorderColor": "#b57614", "lineColor": "#7c6f64", "secondaryColor": "#83a598", "tertiaryColor": "#b8bb26", "background": "#fbf1c7", "mainBkg": "#ebdbb2", "fontFamily": "Tahoma, sans-serif"}}}%%
flowchart TD
  A["Page Load
โหลดหน้า"] --> B["Priority Image
โหลดก่อน"] A --> C["Lazy Route Bundle
โหลดเมื่อเข้า route"] A --> D["@defer Component
โหลดเมื่อเห็น"] B --> E["Better LCP
แสดงผลสำคัญเร็ว"] C --> F["Smaller Initial Bundle
bundle แรกเล็กลง"] D --> G["Less Main-thread Work
งานเริ่มต้นลดลง"]

Code Example

// app.config.ts หรือ module ที่เกี่ยวข้อง
// import NgOptimizedImage เพื่อใช้งาน ngSrc
import { NgOptimizedImage } from '@angular/common';

@Component({
  selector: 'app-hero',
  standalone: true,
  imports: [NgOptimizedImage],
  templateUrl: './hero.component.html'
})
export class HeroComponent {
  imageUrl = '/assets/hero.webp';
}
<!-- hero.component.html -->
<!-- priority เหมาะกับภาพหลักที่เป็น LCP -->
<img
  [ngSrc]="imageUrl"
  width="1200"
  height="630"
  priority
  alt="ภาพหน้าหลักของบทเรียน">
// app.routes.ts
// Lazy loading route เพื่อลด initial bundle
export const routes = [
  {
    path: 'admin',
    loadChildren: () =>
      import('./admin/admin.routes').then(m => m.ADMIN_ROUTES)
  }
];

// ตัวอย่างการใช้งาน:
// เมื่อผู้ใช้เข้า /admin เท่านั้น Angular จึงโหลด bundle ของ admin
<!-- Angular 17+ defer block -->
@defer (on viewport) {
  <app-heavy-chart />
} @placeholder {
  <p>กำลังเตรียมกราฟ...</p>
}

วิดีโอแนะนำ

กิจกรรมท้ายบท

  1. เปลี่ยน <img src> เป็น [ngSrc]
  2. กำหนด width และ height ให้รูปภาพ
  3. ตั้ง priority ให้ภาพ hero
  4. สร้าง lazy route หนึ่งหน้า
  5. ทดลองใช้ @defer กับ component ที่โหลดช้า

กลับสัปดาห์ที่ 13