Các tính năng mới trong chỉ thị Angular NgOptimizedImage

Lâu đài Alex
Alex Castle

Hơn một năm trước, nhóm Chrome Aurora đã ra mắt lệnh Angular NgOptimizedImage. Chỉ thị này tập trung chủ yếu vào việc cải thiện hiệu suất, được đo bằng các chỉ số Các chỉ số quan trọng về trang web. API này kết hợp các phương pháp tối ưu hoá hình ảnh phổ biến và các phương pháp hay nhất vào một API dành cho người dùng. API này không phức tạp hơn nhiều so với phần tử <img> tiêu chuẩn.

Trong năm 2023, chúng tôi đã nâng cấp chỉ thị này bằng nhiều tính năng mới. Bài đăng này mô tả thông tin quan trọng nhất về các tính năng mới đó, nhấn mạnh lý do chúng tôi chọn ưu tiên từng tính năng cũng như cách điều này có thể giúp cải thiện hiệu suất của ứng dụng Angular.

Tính năng mới

NgOptimizedImage đã cải thiện đáng kể theo thời gian, bao gồm các tính năng mới sau đây.

Chế độ tô màu nền

Việc định kích thước hình ảnh bằng cách cung cấp thuộc tính widthheight là một cách tối ưu hoá cực kỳ quan trọng để giảm sự thay đổi bố cục, vì trình duyệt cần biết tỷ lệ khung hình của hình ảnh để có thể tiết kiệm không gian. Tuy nhiên, việc định cỡ hình ảnh là một công việc bổ sung cho các nhà phát triển ứng dụng và không phù hợp với một số trường hợp sử dụng hình ảnh.

Giúp giải quyết căng thẳng này là tính năng chính đầu tiên được thêm vào bản xem trước sau khi nhà phát triển của thành phần hình ảnh: chế độ điền. Đây là cách để các nhà phát triển thêm hình ảnh mà không cần định kích thước rõ ràng cũng như không làm thay đổi bố cục.

Ở chế độ tô màu nền, yêu cầu về kích thước hình ảnh sẽ bị tắt và hình ảnh sẽ tự động được tạo kiểu để lấp đầy phần tử chứa hình ảnh. Thao tác này sẽ tách riêng tỷ lệ khung hình của hình ảnh khỏi không gian hình ảnh chiếm trên trang và giúp bạn kiểm soát tốt hơn việc hình ảnh có vừa với bố cục trang của bạn hay không.

Chế độ lấp đầy sử dụng NgOptimizedImage làm giải pháp thay thế tốt hơn cho thuộc tính css background-image. Đặt một hình ảnh vào bên trong <div> hoặc phần tử khác lẽ ra đã có kiểu background-image, sau đó bật chế độ tô màu nền, như minh hoạ trong ví dụ về mã trước đó. Sử dụng các thuộc tính CSS object-fitobject-position trên <div> để kiểm soát cách định vị hình ảnh trong nền.

// Height and width are required
<img ngSrc="example.com" height="300" width="400">

// Unless you use fill mode!
<div style="width: 100vw; height: 50em; position: relative">
  <img ngSrc="example.com" fill>
</div>

Tạo srcset

Một trong những kỹ thuật tối ưu hoá hình ảnh hiệu quả nhất là sử dụng thuộc tính srcset để đảm bảo tải những hình ảnh có kích thước phù hợp xuống cho mọi thiết bị truy cập vào ứng dụng của bạn. Việc sử dụng srcset trên toàn bộ ứng dụng có thể giúp bạn không lãng phí băng thông và cải thiện đáng kể Chỉ số quan trọng chính của web LCP.

Nhược điểm của thuộc tính srcset là việc triển khai có thể rườm rà. Việc viết các giá trị srcset theo cách thủ công nghĩa là thêm nhiều dòng đánh dấu vào từng thành phần hình ảnh trong ứng dụng, hoàn chỉnh với nhiều URL tuỳ chỉnh cho mỗi srcset. Bạn cũng phải quyết định một tập hợp các điểm ngắt phức tạp, vì chúng có thể đại diện cho cả mật độ màn hình và kích thước khung nhìn của các thiết bị phổ biến.

Đó là lý do tại sao việc thêm tính năng tạo srcset tự động vào lệnh NgOptimizedImage là một cột mốc quan trọng sau khi ra mắt. Với việc bổ sung này, mọi ứng dụng sử dụng CDN hỗ trợ đổi kích thước hình ảnh đều có thể nhận được các srcset đầy đủ, có thể tuỳ chỉnh và tự động thêm vào mọi hình ảnh được tạo bằng lệnh NgOptimizedImage.

Chúng tôi đã bao gồm một API đơn giản để đặt thuộc tính sizes. API này dùng để đảm bảo rằng mỗi hình ảnh đều nhận đúng loại srcset. Nếu bạn không thêm thuộc tính sizes, chúng ta sẽ hiểu rằng hình ảnh có kích thước cố định và phải nhận được một srcset phụ thuộc vào mật độ, như sau:

<img src="www.example.com/image.png" srcset="www.example.com/image.png?w=400 1x, www.example.com/image.png?w=800 2x" >

Loại srcset này đảm bảo rằng hình ảnh được phân phát ở kích thước có tính đến mật độ pixel trên thiết bị của người dùng.

Mặt khác, nếu bạn đưa thuộc tính sizes vào, NgOptimizedImage sẽ tạo một srcset thích ứng bao gồm các điểm ngắt cho nhiều kích thước hình ảnh và thiết bị phổ biến, bằng cách sử dụng danh sách các điểm ngắt mặc định sau đây:

[16, 32, 48, 64, 96, 128, 256, 384, 640, 750, 828, 1080, 1200, 1920, 2048, 3840]

Tạo kết nối trước

Để cải thiện LCP, bạn cần phải giảm thời gian người dùng tải hình ảnh LCP xuống. Trong phần trước, bạn đã thấy cách srcset có thể hỗ trợ bằng cách chuyển các tệp hình ảnh nhỏ hơn, nhưng một cách tối ưu hoá cũng quan trọng không kém là bắt đầu chuyển càng sớm càng tốt. Một cách để thực hiện việc đó là sử dụng thẻ link rel="preconnect" để bắt đầu kết nối với miền hình ảnh của bạn.

Ngay từ đầu, NgOptimizedImage đã cảnh báo nếu bạn không kết nối trước được với miền của hình ảnh LCP, nhưng cảnh báo này không phải là giải pháp lý tưởng – chúng tôi chỉ muốn khắc phục vấn đề cho bạn. Và đó chính xác là những gì NgOptimizedImage làm được hiện nay, với tính năng tạo kết nối trước tự động.

Để hỗ trợ tính năng này, chúng tôi sử dụng phương pháp phân tích mã tĩnh để cố gắng phát hiện các miền hình ảnh trong trình tải NgOptimizedImage và tự động tạo các thẻ liên kết kết nối trước cho các miền đó. Vẫn có thể có trường hợp bắt buộc phải có các đường liên kết kết nối trước thủ công, nhưng đối với hầu hết người dùng, tính năng tự động kết nối trước chỉ cần thực hiện một bước để đạt hiệu suất hình ảnh tốt.

Hỗ trợ nâng cao cho trình tải tuỳ chỉnh

Một yếu tố chính của NgOptimizedImage là cấu trúc trình tải, cho phép lệnh tự động tạo URL được điều chỉnh cho phù hợp với CDN hình ảnh của ứng dụng. Chúng tôi cung cấp một bộ trình tải tích hợp sẵn cho những CDN được sử dụng rộng rãi. Chúng tôi cũng cho phép bạn sử dụng trình tải tuỳ chỉnh, cho phép bạn tích hợp NgOptimizedImage với hầu hết mọi giải pháp lưu trữ hình ảnh.

Khi khởi chạy, những trình tải tuỳ chỉnh này bị giới hạn về phạm vi và chỉ có thể đọc thuộc tính width trong phần tử hình ảnh. Để đáp ứng phản hồi của người dùng, chúng tôi đã hỗ trợ thêm cấu trúc dữ liệu loaderParams có thể tuỳ chỉnh, cho phép truyền dữ liệu tuỳ ý từ phần tử hình ảnh đến trình tải tuỳ chỉnh. Với việc mở rộng này, trình tải tuỳ chỉnh có thể đơn giản hoặc phức tạp theo yêu cầu của cơ sở hạ tầng hình ảnh của ứng dụng.

Ví dụ sau đây cho thấy cách một trình tải tuỳ chỉnh đơn giản có thể sử dụng API loaderParams để chọn giữa hai miền hình ảnh thay thế:

const myCustomLoader = (config: ImageLoaderConfig) => {
  if (config.loaderParams?.alternateDomain) {
    return `https://alternate.domain.com/images/${config.src}`
  }
  return `https://primary.domain.com/images/${config.src}`;
};

Bạn có thể xem ví dụ về một trình tải tuỳ chỉnh phức tạp hơn trong tài liệu về Angular.

Hướng dẫn mở rộng về hiệu suất của hình ảnh

Cho đến nay, mọi cảnh báo về hiệu suất của hình ảnh mà chúng tôi thêm vào Angular đều là một phần của lệnh NgOptimizedImage. Nếu không sử dụng lệnh này trong ứng dụng, thì bạn sẽ không nhận được hướng dẫn nào về các vấn đề liên quan đến hiệu suất của hình ảnh.

Trong Angular 17, chúng tôi sẽ mở rộng phạm vi hướng dẫn về hiệu suất hình ảnh để đưa vào tất cả các ứng dụng Angular. Hiện tại, nếu chúng tôi phát hiện các mẫu hình ảnh mà chúng tôi biết là lỗi gây ảnh hưởng đến hiệu suất, chẳng hạn như tải từng phần hình ảnh LCP xuống hoặc tải xuống một tệp quá lớn so với trang, chúng tôi sẽ thông báo cho bạn ngay cả khi bạn không sử dụng NgOptimizedImage.

Hiệu suất của hình ảnh rất quan trọng đối với tất cả ứng dụng và chúng tôi rất vui mừng được tiếp tục xây dựng các biện pháp giúp ngăn chặn các lỗi thường gặp trong ứng dụng Angular.

Hướng đến tương lai

Chúng tôi đang nỗ lực phát triển bộ tính năng tiếp theo cho NgOptimizedImage. Mặc dù hiệu suất hình ảnh vẫn là mối quan tâm chính của chúng tôi, nhưng chúng tôi cũng muốn thêm các tính năng giúp cải thiện trải nghiệm của nhà phát triển, để đảm bảo rằng NgOptimizedImage vẫn là một lựa chọn hấp dẫn để đưa hình ảnh vào các ứng dụng Angular.

Phần giữ chỗ hình ảnh được ưu tiên một tính năng. Các lệnh này thường được dùng để giúp hình ảnh tải trông đẹp hơn trên các ứng dụng web, nhưng có thể làm giảm hiệu suất nếu được triển khai không đúng cách. Chúng tôi hy vọng sẽ xây dựng được một hệ thống phần giữ chỗ hình ảnh ưu tiên hiệu suất vào NgOptimizedImage. Hãy theo dõi blog của chúng tôi để biết thêm thông báo!