Group
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 phía 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.
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ó.
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 đề…
Sự thật thì lazy loading ảnh là cách thức phức tạp hơn của 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ì đã.
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.
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 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 để hiểu mà thôi.
Ả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 (- – – – – -)
Đâ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…
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.
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.
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.
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.
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.
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 đ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>
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)