Cách trì hoãn tải ảnh giúp tăng tốc độ website

Ảnh trì hoãn (deferred image) là ảnh chỉ được tải xuống sau khi nội dung thuộc màn hình đầu tiên (initial page) tải xong.

Các hình ảnh không nằm trong màn hình đầu tiên (below the fold) có thể được trì hoãn, điều đó cho phép nội dung website tải nhanh hơn.

Trì hoãn tải hình ảnh giúp trang tải nhanh hơn

Bài viết này sẽ hướng dẫn bạn cách đơn giản để áp dụng trì hoãn tải ảnh mà không cần đến jQuery hoặc lazy loading (tải lười biếng).

Một trong những lý do chính khiến trang web bị tải chậm là do trang có nhiều ảnh. Người dùng ở khắp nơi trên thế giới đều thấy một hiện tượng phổ biến là các ảnh được tải xuống chậm chạp từ trên xuống dưới.

Thậm chí ngay cả khi người dùng thấy các ảnh được tải chậm từ từ, thường vẫn có nhiều ảnh ở sâu bên dưới trang không cần hiển thị cho người dùng ngay lúc đó, trong khi chúng cũng vẫn đang được tải ngay khi người dùng truy cập web.

Tất cả những ảnh này cạnh tranh với nhau cho lượng băng thông giới hạn cũng như cạnh tranh với các nguồn tài nguyên khác chẳng hạn như CSS và JavaScript. Điều đó nghĩa là các ảnh đang cản trở việc hiển thị phần nội dung thuộc màn hình đầu tiên của trang web cho người dùng trong khả năng nhanh nhất có thể của nó.

Đây là vấn đề đã được biết đến lâu rồi

Cách chính mà nhà phát triển và người quản trị web giải quyết vấn đề này là thông qua một phương thức gọi là lazy loading (tải lười biếng).

Các ảnh tải lười là một giải pháp trong đó khi người dùng cuộn chuột xuống bên dưới, các ảnh trong khung nhìn mới được tải, các ảnh bên dưới thì không (tải ảnh theo nhu cầu của người dùng). Có rất nhiều điều thú vị về phương thức tải lười và tôi sử dụng nó thường xuyên, nhưng nó có một số vấn đề…

Trì hoãn tải ảnh mà không cần lazy loading hoặc jQuery

Sự thật thì lazy loading ảnh là cách thức phức tạp hơn của phương thức trì hoãn tải ảnh mà thôi.

Để quay lại vấn đề cơ bản, chúng ta sẽ thảo luận về trì hoãn tải ảnh mà không có lazy loading. Nhưng trước hết hãy xem những việc mà lazy loading thực sự làm là gì đã:

  1. Quan sát (Observing) vị trí cuộn chuột
  2. Giám sát (Monitoring) vị trí cuộn chuột
  3. Phản ứng (Reacting) với vị trí cuộn
  4. Trì hoãn (Deferring) tải ảnh

Trong bốn bước kể trên, chỉ có một cái trong số chúng là trì hoãn tải ảnh.

Chúng ta hãy thảo luận về phần trì hoãn ảnh

Khi một trang web được render (hiển thị) trên trình duyệt, trình duyệt sẽ cố gắng tải tất cả ảnh nó có thể tìm thấy trên trang. Nếu có hai ảnh trên trang, nó sẽ tải cả hai ảnh. Nếu có một trăm ảnh trên trang, nó sẽ tải cả một trăm ảnh.

Đấy là hành vi mặc định của trình duyệt. Nó phải yêu cầu và tải về tất cả các ảnh.

Cách đáng tin cậy nhất quanh vấn đề này (với tất cả các trình duyệt) là đánh lừa trình duyệt để nó nghĩ rằng những ảnh này không có ở đó.

Cách thức này được thực hiện trong lazy loading, cũng như bất cứ vị trí nào khác nhằm cung cấp một ảnh nhỏ mặc định trong mã HTML của chúng ta, và sau đó chuyển ảnh mặc định sang ảnh chúng ta thực sự muốn hiển thị thông qua JavaScript.

Điều này có nghĩa là các ảnh sẽ được đánh dấu trong mã giống như dưới đây…

<img src="anh-gia.png" data-src="anh-that.png"

Khi trang đã thực hiện tải nội dung thuộc màn hình đầu tiên rồi, trình duyệt sẽ nhận được “ảnh giả” và điều đó chỉ có trình duyệt nhận thấy mà thôi, vì thế cho dù bạn có một ảnh hay một trăm ảnh cũng chẳng thành vấn đề, bởi vì trình duyệt đã tải các ảnh giả rồi.

Sau đó thông qua JavaScript, chúng ta tráo đổi ảnh giả tương ứng bằng ảnh thật.

Khi trình duyệt thấy rằng có một ảnh mới (ảnh thật) trong HTML, nó sẽ tải ảnh đó ngay lúc ấy.

Bước tương đối đơn giản này có thể tạo ra được kết quả rất tuyệt vời. Vừa mới đây thôi, tôi đã biến một trang phải mất tám giây để tải thành chưa đến một giây chỉ nhờ phương pháp đó (chúng ta sẽ mô tả phương pháp này đầy đủ ngay bên dưới với các code mẫu để các bạn tham khảo).

Hiểu cách trang web tải xuống

Để hiểu được cách thức, thời điểm và phương thức trì hoãn được dùng, chúng ta cần phải hiểu cách tải trang diễn ra như thế nào. Đây là kiến thức quan trọng cần biết và nó chỉ khiến bạn tốn một hoặc hai phút tìm hiểu mà thôi.

cách tải trang

Ảnh trên cho thấy một trang web nhỏ tải ra sao. Trang có một ảnh chính, một vài ảnh khác, một file CSS và một file JavaScript.

Trong trang khá điển hình này, mỗi nguồn tài nguyên phải cạnh tranh với nhau để được tải về.

Sự thật là chỉ một số thứ cần tải ngay xuống lúc ban đầu, đó là các phần ở bên trên đường chấm chấm ngang (- – – – – -).

Đây là phần được gọi là “trong màn hình đầu tiên” hoặc phần nội dung đầu tiên được nhìn thấy của trang web.

Điều này nghĩa là với người dùng muốn thấy nội dung màn hình đầu tiên nhanh nhất có thể, chúng ta chỉ cần tải HTML, CSS, JavaScript và ảnh chính là đủ.

Hãy xem cách chúng ta có thể làm trang này tải nhanh hơn gấp đôi (thậm chí còn hơn) như thế nào nhé. Chúng ta cần…

  • Chỉ tải ảnh chính thôi
  • Trì hoãn tải các ảnh còn lại

Khi chúng ta làm điều đó, chúng ta sẽ thấy rằng trang sẽ tải nhanh hơn nhiều, người dùng sẽ thấy nội dung sớm hơn (đây là một trong các yếu tố dùng để đánh giá tốc độ trang trong Google PageSpeed Insights, nó gọi là First Contentful Paint/FCP).

để tăng tốc trang, bạn chỉ cần tải cái cần tải

Giờ chúng ta đã cắt giảm từ một trang phải yêu cầu tải đến 12 tài nguyên mới được phép hiển thị xuống trang chỉ cần tải 4 tài nguyên thôi cũng đã đủ cho người dùng thấy nội dung rồi.

Tôi thích điều này.

Nó có nghĩa là quảng cáo Adsense có thể hiển thị nhanh hơn, người dùng của tôi có thể mua hàng sớm hơn, và Google đánh giá cao website của tôi.

Trung thực hơn thì bạn và tôi đều biết rằng các trang của chúng ta có hàng tá ảnh, không chỉ có vài bức như trong minh họa trên. Đừng mắc sai lầm. Phương thức này có thể làm trang của bạn tải nhanh hơn rất nhiều. Bạn càng có nhiều ảnh trên trang, bạn càng tiết kiệm được nhiều thời gian với phương thức này.

Liệu lazy loading có làm điều này cho tôi không?

Nó có chứ, nhưng có nhiều tình huống mà lazy loading không phải là biện pháp lý tưởng.

Lý do phổ biến nhất là mọi người có thể chọn không trì hoãn tải hình ảnh thông qua tải lười biếng, và đây có thể là xu hướng phổ biến mới trong việc tạo các giao diện một trang.

Giao diện một trang / One page templates

Nếu bạn có giao diện một trang (điều này có nghĩa là thanh điều hướng chính của bạn không đưa bạn tới các trang khác mà là đưa bạn đến các phần khác nhau của cùng một trang) và nếu bạn chọn tải lười biếng (lazy loading), một rắc rối không hề nhỏ sẽ nổi lên.

Khi trang bạn tải, người dùng thấy thanh điều hướng chính của bạn, và nếu họ click, họ được đưa đến phần khác của trang mà hiện không có ảnh nào được tải sẵn lúc ấy.

Chẹp, tôi chẳng thích điều này đâu.

giao diện một trang

Trong trường hợp này cho dù người dùng chỉ sử dụng điều hướng của bạn, họ vẫn bị đưa đến các vị trí mà họ phải chờ đợi để ảnh tải xong.

Đây là lúc chúng ta thực hiện việc trì hoãn tải ảnh thay vì tải lười biếng

Trong kịch bản giao diện một trang (one page template), không có lý do nào để bạn phải thiết lập tất cả mọi thứ tải lười biếng (quan sát, theo dõi và phản ứng thích hợp với vị trí cuộn chuột).

Tại sao chúng ta không trì hoãn tải ảnh và giúp ảnh được tải ngay lập tức sau khi trang tải xong.

Làm nó thế nào đây?

Để làm điều đó chúng ta cần đánh dấu ảnh của mình và thêm một đoạn JavaScript rất nhỏ và cực kỳ đơn giản. Tôi sẽ cho bạn thấy phương thức mà tôi sử dụng trong thực tế cho trang này và các trang khác. Nó sử dụng ảnh base 64, nhưng đừng để khái niệm mới này làm bạn lo lắng.

Mã HTML:

<img src="data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=" data-src="anh-that-cua-ban-o-day">

Và JavaScript:

<script>
function init() {
var imgDefer = document.getElementsByTagName('img');
for (var i=0; i<imgDefer.length; i++) {
if(imgDefer[i].getAttribute('data-src')) {
imgDefer[i].setAttribute('src',imgDefer[i].getAttribute('data-src'));
} } }
window.onload = init;
</script>

Sử dụng

Với hầu hết các trang bạn có thể đơn giản thêm mã này ngay trước thẻ đóng </body> trong mã HTML và thay thế “anh-that-cua-ban-o-day” bằng đường dẫn hình ảnh thực tế của bạn.

(Dịch từ bài viết: How to defer images – Tác giả: Patrick Sexton – Website: Varvy)

Vài lời của người dịch:

  • Trì hoãn tải ảnh hay hơn lazy load ảnh ở chỗ nó làm việc quan trọng trước, sau khi hoàn thành xong nó ngay lập tức làm việc không quan trọng, trong khi lazy load thì phải chờ người dùng cuộn chuột đến gần mới tải (kiểu nước đến chân mới nhảy).
  • Tuy vậy không có plugin nào mà tôi biết hiện hỗ trợ phương thức trì hoãn tải ảnh, trong khi các plugin lazy load ảnh có rất nhiều, ví dụ như Flying Images & a3 lazy load.
  • Sự xuất hiện của kiểu lazy load cấp độ trình duyệt (native lazy-loading) trên Chrome và khả năng điều chỉnh ngưỡng cách màn hình kích hoạt tải ảnh giúp lazy load khắc phục được kha khá nhược điểm.

Leave a Comment