0

5 cách sử dụng lazy load image

Mở đầu

Hình ảnh là một trong những loại nội dung phổ biến nhất trên web, thời gian tải các trang web chứa nhiều hình ảnh có thể dễ dàng trở thành một vấn đề lớn. Ngay cả khi được tối ưu hóa đúng cách , hình ảnh có thể vẫn hơi nặng, vẫn cần 1 khoảng thời gian đủ dài để tải được toàn bộ hình ảnh trên 1 trang. Điều này có tác động tiêu cực đến người dùng khi họ phải mất 1 thời gian chờ khi họ truy cập trang web của chúng ta, trước khi họ có thể thấy được nội dung cần thiết. Rất có thể, họ sẽ trở nên thiếu kiên nhẫn và bye bye trang web của chúng ta để để đến với một trang nào đó nhanh hơn, trừ khi chúng ta đưa ra được một giải pháp cho việc tải hình ảnh mà không can thiệp vào nhận thức về tốc độ của người dùng.

Sau đây là 5 cách để sử dụng lazy load, làm cho việc tải hình ảnh (tổng thời gian tải thì vẫn như vậy thôi) khiến cho người dùng có cảm giác "nhanh hơn" 😄

Lazy load là gì?

Lazy load là việc tải hình ảnh một cách không đồng bộ. Những ảnh nào nằm trên viewport (phần nhìn thấy từ màn hình) sẽ được tải trước, những phần "bị lấp" sẽ được tải sau, nếu hình ảnh chỉ được tải khi người dùng cuộn trang, thì có khi những hình ảnh cuối cùng sẽ không được tải nếu người dùng không cuộn trang.

Cần thiết để dùng lazy load?

  • Nếu trang web của chúng ta sử dụng JavaScript để hiển thị nội dung hoặc cung cấp một số loại chức năng nào đó cho người dùng, việc tải DOM nhanh chóng trở nên quan trọng. Các function trong js thường đợi cho đến khi DOM được tải hoàn toàn rồi chúng mới bắt đầu chạy. Trên một trang web có số lượng hình ảnh đáng kể, việc tải hình ảnh không đồng bộ - có thể tạo ra sự khác biệt để người dùng ở lại hoặc rời khỏi trang web.
  • Vì hầu hết các giải pháp lazy load hoạt động bằng cách tải hình ảnh nếu người dùng đã cuộn đến vị trí có thể nhìn thấy hình ảnh bên trong viewport, có những hình ảnh sẽ không bao giờ được tải nếu người dùng không cuộn đến điểm đó. Điều này sẽ tiết kiệm đáng kể về băng thông, khá là tốt cho người dùng điện thoại hoặc có mạng chậm.

1. Native lazy loading

Từ chrome 76 trở đi, chúng ta có thể sử dụng thuộc tính loading để lazy việc tải hình ảnh hay iframe:

<img src="myimage.jpg" loading="lazy" alt="..." />
<iframe src="content.html" loading="lazy"></iframe>

Không có gì tuyệt vời hơn việc chỉ sử dụng các thẻ html, không cần một chút js nào, và việc còn lại là để trình duyệt làm nốt, rất đơn giản. Thuộc tính loading cho phép chúng ta dừng tải hình ảnh cho đến khi người dùng cuộn trang đến vị trí chứa hình ảnh đó. Giá trị của loading bao gồm:

  • auto: Hành vi lazy load mặc định của trình duyệt (nếu đặt giá trị này thì coi như không cần đặt loading).
  • lazy: Bật chế độ lazy loading
  • eager: Tải nội dung thẻ chứa giá trị này ngay lập tức

Cách này đơn giản, tuyệt vời, nhẹ nhàng, không tốn công sức. Nhưng không phải trình duyệt nào cũng hỗ trợ thuộc tính loading. Chỉ có Chrome 76, Mozilla Firefox 75 và các trình duyệt dựa trên nhân Chromium 76 trở lên thì mới sử dụng được thuộc tính này.

2. Sử dụng Intersection Observer API

Định nghĩa Intersection Observer API:

Intersection Observer API cung cấp một cách để quan sát không đồng bộ các thay đổi trong giao diện với các ancestor element hay với các document’s viewport cấp cao.

Nói cách khác, những gì đang được xem không đồng bộ là sự thay đổi của yếu tố này so với yếu tố khác.

Để ví dụ cho cách hoạt động của việc lazy load bằng phương pháp này, ta có ví dụ :

<img data-src="image.jpg" alt="test image">

Lưu ý, các đường dẫn đến hình ảnh được chứa trong một thuộc tính data-src, không phải thuộc tính src. Lý do là nếu sử dụng src thì hình ảnh sẽ được tải ngay lập tức, đó không phải là điều chúng ta muốn.

Tiếp theo trong CSS, chúng ta cho mỗi hình ảnh một giá trị min-height, giả sử là 100px. Điều này cho phép mỗi hình ảnh giữ cho mình 1 chỗ có độ cao 100px theo chiều dọc (do thẻ img không có thuộc tính src không có chiều dài):

img {
  min-height: 100px;
  /* more styles here */
}

Trong file Js, tạo một instance IntersectionObserver:

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);

Cuối cùng là duyệt qua một lượt các hình ảnh:

const imgs = document.querySelectorAll('[data-src]');
imgs.forEach(img => {
  observer.observe(img);
});

Cách này khá dễ dàng và hỗ trợ với hầu hết các trình duyệt (trừ IE). Nếu mà trình duyệt không hỗ trợ thì chúng ta có thể sử dụng Polyfill IntersectionObserver

3. Lozad.js

Lozad là một lazy loader hiệu năng cao, nhẹ và có thể cấu hình trong JavaScript thuần mà không cần phụ thuộc. Chúng ta có thể sử dụng nó để lazy load hình ảnh, video, iframe và nhiều thứ khác nữa. Nó sử dụng Intersection Observer API.

Cài Lozad bằng npm hoặc yarn:

npm install --save lozad
yarn add lozad

Hoặc sử dụng luôn CDN:

<script src="https://cdn.jsdelivr.net/npm/lozad/dist/lozad.min.js"></script>

Để sử dụng, chúng ta chỉ cần đặt tên lớp là lozad:

<img class="lozad" data-src="img.jpg">

Sau đó thì khởi tạo Lozad trong js:

const observer = lozad();
observer.observe();

Tìm hiểu thêm tại Lozad.js

4. Lazy load với hiệu ứng làm mờ hình ảnh

Phương pháp này hoạt động theo cách: đầu tiên bạn nhìn thấy là một bản sao mờ, độ phân giải thấp của hình ảnh, trong khi phiên bản độ phân giải cao của nó đang được tải bằng lazy load.

Chúng ta có thể sử dụng progressive-image.js để xử lý vấn đề này. Ưu điểm:

  • Hiệu suất tốt: chỉ 463 byte CSS và 1.007 byte JavaScript sau khi được rút gọn
  • Hỗ trợ màn hình retina
  • Không phụ thuộc: không yêu cầu jQuery hoặc các thư viện và framework khác.
  • Hỗ trợ các trình duyệt cũ hơn.

5. Yall.js

Yall là một feature-packed được dùng để lazy load hình ảnh, video và iframe. Nó cũng sử dụng Intersection Observer API và có khả năng trả về những sự kiện cơ bản nếu cần thiết. Cài đặt:

npm install yall-js

Sau đó thêm vào file của chúng ta:

<script src="yall.min.js"></script>
<script>
  document.addEventListener("DOMContentLoaded", yall);
</script>

Để lazy load hình ảnh, chúng ta làm tiếp như thế này:

<img class="lazy" src="placeholder.jpg" data-src="image-to-lazy-load.jpg" alt="Alternative text to describe image.">
  • Thêm class lazy vào phần tử
  • Giá trị của src chỉ là ảnh giữ chỗ (hình ảnh default khi chưa load được ảnh chính)
  • Đường dẫn tới hình ảnh chính muốn lazy load nằm trong thẻ data-src

Kết luận


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí