Hướng dẫn nấu món "Lazy loading image" theo chuẩn 5 sao Google
https://viblo.asia/p/huong-dan-nau-mon-lazy-loading-image-theo-chuan-5-sao-google-maGK7qJMlj2?fbclid=IwAR1iMSW2bbw1DvAPZeLc3bxZbtwSnX3Yv3HnQWavMH6x665nLFV4df4_FHA
Last updated
https://viblo.asia/p/huong-dan-nau-mon-lazy-loading-image-theo-chuan-5-sao-google-maGK7qJMlj2?fbclid=IwAR1iMSW2bbw1DvAPZeLc3bxZbtwSnX3Yv3HnQWavMH6x665nLFV4df4_FHA
Last updated
Mỵ là một người con gái nết na thùy mị. Vào ngày Tết cuối năm, bạn trai mời Mỵ sang ra mắt bố mẹ chồng. Đây, cơ hội ngàn năm có một, ngày mà Mỵ đã chờ bấy lâu nay, đây là dịp để cô trổ hết tài công dung ngôn hạnh mà đã mất bao tiền của thời gian luyện tập và chuẩn bị. Đề thi mẹ chồng cho nàng dâu như sau "Con hãy làm món lazy load image cho bộ sưu tập của mẹ nhé!". Lúc bấy giờ Mỵ mới giật thót, bấy lâu nay toàn học chế biến những sơn hào hải vị, nhưng giờ gặp món ăn dân giã như này phải làm sao. Quen mà lạ!
Nào giờ ta hãy cùng giúp Mỵ hoàn thành món ăn này một cách xuất sắc nhé.
Để giữ bài toán ở mức đơn giản, ở đây mình sẽ tạo ra một danh sách, bên trong là các thẻ img. Nguồn dữ liệu mình sẽ lẩy từ API của unsplash.com.
API sẽ có thể lấy theo page. Mỗi page sẽ trả về 10 ảnh. Mỗi một bức ảnh thì sẽ có các kích thước như thumbnail, small, medium, large.
Là một thư viện ảnh, có nhiều cách để trưng bày chúng. Ở đây mình lựa chọn là một vertical list, ảnh sẽ xếp lần lượt từ trên xuống dưới. Cuộn xuống gần đáy trang, ảnh sẽ được load thêm cho đến mãi mãi
Ở đây mình đã làm những điều như sau
Khi vào trang, gọi đến API unsplash và kéo ảnh về, sau đó set vào list
Mỗi khi user cuộn xuống gần đáy trang, update trang page hiện tại lên 1 đơn vị
Thấy sự thay đổi về trang API sẽ được gọi lại và tiếp tục đẩy vào danh sách
Hàm scroll được thottle, một khi đã được gọi thì sẽ phải chờ ít nhất 300ms tiếp theo thì mới có thể được gọi
Event listener sẽ được release khi out khỏi page
Với phần infiinty scroll, nhìn chung như thế đã là ổn
Trước khi bước vào công đoạn chính, ta sẽ điểm qua một vài vẫn đề trước. Vậy tại sao phải cần lazy load ở đây
Không ai muốn phải chờ đợi. Một user khi vào một trang web sẽ luôn muốn mình có thể xem được các nội dung một cách nhanh nhất. Mà thứ tốn thời gian tải của trang web nhất lại thường là các tài nguyên media.
Nếu các hình ảnh ở phía dưới, user không có cơ hội hay nhu cầu xem ảnh, cơ sao bắt họ phải tải xuống hết rồi mới cho xem nội dung
Không dùng đến mà mình vẫn yều cầu server trả response về thì là lãng phí tài nguyên server
Để có thể biến món ăn, ta có 3 cách như sau:
Intersection Observer API
Đây là một API có sẵn của WebAPI, giúp bạn có thể đặt một callback mỗi khi mà có một element nào đó đi vào viewport màn hình hay một vùng nào đó bạn quy định. Nhờ vào cơ chế này, bạn có thể để một callback cho các hình ảnh sẽ được load khi chúng được user cuộn và xuất hiện trên màn hình.
IntersectionObserver có thể lắng nghe được nhiều element cùng một lúc
Mỗi khi một element vào viewport thì chúng sẽ được update data-src vào src và bỏ observe của chúng đi
Ở mỗi image sẽ nhận prop lazyImageObserver
trên và gắn observe tương ứng.
Đây là một API không phải trình duyệt nào cũng hỗ trợ, chính vì thế bạn sẽ có thể cần dùng đến polyfill hay sử dụng các cách khác phía bên dưới
Đây là cách rất thông thuộc với các bạn và có thể support trên mọi trình duyệt rồi
Ta sẽ add một event mỗi khi user scroll
. Lúc đó các image sẽ được check xem đã được vào viewport chưa và load hình ảnh
Khác với cách trên, cách này sẽ phải cận thận để check với đủ các case scroll
resize
orientationchange
để tránh bị mẹ chồng bắt BUG nhé
Trong khi với hầu hết các trường hợp, ta sẽ sử dụng thẻ img
để có thể show ra ảnh. Mình còn có một cách khác đó là dùng đến thuộc tính background-image
.
Không giống với cách hoạt động của img
là luôn được load và hiện thị cho dù có được xem thấy hay không, background-image
hoạt động một cách đặc biệt hơn. Khi document và CSS object modal đã được build, browser lúc đó mới apply các CSS đó trước rồi mới quyết định gọi đến các request bên ngoài. Chính vì vậy để link ảnh vào thuộc tính background-image
có thể tăng tốc first loading cho user.
Cùng kết hợp với 2 cách trên, ta có thể ra được một phong cách lazy load khác tương tự
Đúng như cách gọi của nó, ở cách này hầu như bạn chẳng phải làm gì cả, chỉ cần nằm và tận hưởng
Ở version Chrome76, Google đã giới thiệu một hàm native mới support hoàn toàn những công việc này. Bạn có thể enable và trải nghiệm tính năng này khi nhập dòng này vào URL chrome://flags/#enable-lazy-image-loading
Cụ thể bạn có thể đọc và tìm hiểu thêm ở đây nhé https://web.dev/native-lazy-loading/
Đây chính là công đoạn cuối cùng cho tác phầm này rồi. Từ bước này trở đi, bạn có thể thoải mái và sáng tạo sao cho hợp mắt.
Với mỗi mình image, mình có thể tạo một place holder hiệu ứng loading chẳng hạn Hy vọng với các hướng dẫn step by step như trên, Mỵ đã có thể ghi điểm tuyệt đối trong mắt mẹ chồng. Nếu không được hoàn hảo, hoàng tử kia cũng sẽ tha thứ cho người con gái đã cố gắng nỗ lực hết mình rồi.
References