Nội dung bài viết
La Kien Vinh Tối ưu quá trình load một trang web với CSS-Sprite. Các icon, hình ảnh sẽ được "đóng gói" vào một file duy nhất cho 1 lần tải. Bài viết này cung cấp thêm cho các nhà phát triển web muốn tối ưu tốc độ nạp trang.

Giới thiệu

Giả sử ta cần hiển thị trên trang web 2 ảnh sau (article.png và experience.png).

ss_1 article.png ss_2 experience.png


Để xuất hiện được 2 ảnh như trên ta có nhiều phương pháp.

  • Dùng tag img với thuộc tính src: <img src="<path>/article.png" /> và<img src="<path>/experience.png" />
  • Dùng tag bất kỳ với việc cài đặt thuộc tính background: background:url("<path>/article.png")background:url("<path>/experience.png")
  • Dùng javascript để vẽ trong tag Canvas (được hỗ trợ trong HTML5)


Khảo sát với phương pháp trên, web-browser sẽ cần download 2 ảnh riêng biệt là article.pngexperience.png từ server về. Trong bài viết này, tôi giới thiệu một phương pháp mà chúng ta chỉ cần sử dụng một ảnh duy nhất và ảnh đó lưu thông tin của 2 ảnh như khảo sát ở trên, tạm đặt tên là icon.png như hình dưới, các ảnh nhỏ đưa vào một ảnh duy nhất và ảnh này được gọi là Image Sprite. Để hiểu thêm về Sprite các bạn có thể tham khảo bài Sprite & 2D Animation :: www.stdio.vn/articles/read/19-sprite-2d-animation.

ss_3
icon.png

Tiền đề bài viết

Bài viết được ra đời khi mà Stdio đang được xây dựng và một số thành phần của trang Stdio này được tối ưu theo phương pháp này. Bên cạnh đó, tôi muốn có nơi lưu trữ một kiến thức cho các học trò của tôi có thêm các tham khảo để làm việc hiệu quả hơn.Kiến thức của tôi là LOW LEVEL và chuyên về hệ thống nên nếu có sơ sót trong mảng này, mong các nhà phát triển chuyên về web đóng góp ý kiến để tôi hoàn thiện thêm.

Đối tượng hướng đến

Để hiểu được bài viết này, còn cần thêm kiến thức về sử dụng CSS. Bài viết này cung cấp thêm cho các nhà phát triển web muốn tối ưu tốc độ nạp trang. Tuy nhiên cần lưu ý, tôi sẽ có phân tích về sự thuận lợi và bất lợi của phương pháp này.

Môi trường đã thử nghiệm

Thật tế thì kỹ thuật này đã phổ biến rộng rãi hầu hết các trình duyệt web phổ thông kể cả các trình duyệt web trên thiết bị di động, tuy nhiên, sau đây là 3 trình duyệt web mà tôi thường dùng để thử nghiệm: Google Chrome 37.0.2062.103 m+ / Firefox 31.0+ / IE 9+.

Hướng dẫn

Hệ trục tọa độ dành cho tọa độ <X>, <Y>

CSS Image Sprite có hệ trục tọa độ <X>, <Y> sao cho chiều dương của trục X là hướng sang trái, và chiều dương của Y là hướng lên và gốc tọa độ đặt tại gốc trái trên của Image Sprite, cần hiểu rõ điều này để cài đặt đúng tọa độ <X>, <Y> của từng phần trong Image Sprite. Có một phương pháp để dễ nhớ hơn là, ta cứ xét theo tất cả là tọa độ âm.

ss_4
icon.png

Như ở icon.png, ta lưu trữ các thành phần được đánh số 1, 2, 3, 4, 5, 6 chính là các ảnh nhỏ vào chung một Image Sprite. Mỗi phần nhỏ của ảnh này có chiều rộng <WIDTH>50px và chiều cao <HEIGHT>50px. Ta có các thông tin như sau để xác định được 1 phần bao gồm <X>, <Y> là tọa độ bắt đầu của 1 phần và width, height là độ rộng và cao của một phần.

PHẦN TRONG IMAGE SPRITE <X> <Y> <WIDTH> <HEIGHT>
PHẦN 1 0px 0px 50px 50px
PHẦN 2 -50px 0px 50px 50px
PHẦN 3 -100px 0px 50px 50px
PHẦN 4 0px -50px 50px 50px
PHẦN 5 -50px -50px 50px 50px
PHẦN 6 -100px -50px 50px 50px

Hiện thực 1 class thể hiện "Phần 5" của icon.png

"CÔNG THỨC"

.part_5
{
	width: <WIDTH>;
	height: <HEIGHT>;
	background: url("<path_to_image_sprite>") <X> <Y>;
}

Với "công thức như trên" ta có được một selector để thể hiện PHẦN 5 hoàn chỉnh như sau

.part_5
{
	width: 50px;
	height: 50px;
	background: url("icon.png") -50px -50px;
}

Trong HTML ta sử dụng như sau, giả sử ta dùng tag <div>

<div class="part_5"></div>

Kết quả ta nhận được sẽ là

ss_5

Áp dụng tương tự cho các thành phần còn lại, ví dụ

.part_1
{
	width: 50px;
	height: 50px;
	background: url("icon.png") 0px 0px;
}

.part_2
{
	width: 50px;
	height: 50px;
	background: url("icon.png") -50px 0px;
}

Cần lưu ý ở đây là, icon.png sẽ được xem là 1 request duy nhất tới nơi chứa nó mặc dù nó xuất hiện ở nhiều selector do đó có thể khẳng định là icon.png chỉ được DOWNLOAD MỘT LẦN DUY NHẤT và trong bộ nhớ nó được DÙNG CHUNG cho các selector ở part_1, part_2, ... part_6.

Một số vấn đề ảnh hưởng tốc độ tải trang

[A] Vấn đề nảy sinh khi ứng dụng client gửi request đến server

Để hiểu được mặt thuận lợi của phương pháp này, ta cần hiểu thêm một số vấn đề khi trình duyệt web tiến hành gửi một request đến server và nhận lại kết quả response. Ở đây để tránh làm cho kiến thức bị loãng tôi chỉ chọn ra 2 quá trình đơn giản xảy ra khi một ứng dụng ở client tiến hành gửi một request đến server.

  • DNSLookup: Client (Web-Browser) tiến hành gửi đến DNS server domain name để tra cứu xem địa chỉ IP của server đang lưu dữ liệu và sau đó gửi lại cho Client.
  • Download: Gửi request đến tải dữ liệu cần thiết từ địa chỉ IP của server sau khi tra cứu được từ bước trước.

Thật tế sẽ còn nhiều bước nữa nảy sinh, và chúng ta cần lưu ý rằng, mỗi bước đều tiêu tốn 1 thời gian TIME T để hoàn tất.

ss_6

 

[B] Trình duyệt web có thể gửi request và nhận response song song

Khi Client nhận được 1 trang HTML, nó sẽ tiến hành lập danh sách các tài nguyên từ thông tin trong HTML bao gồm (CSS, JS, IMAGE, SOUND, và còn nhiều loại tài nguyên khác) và tiến hành gửi các request, điểm cần lưu ý là, các dữ liệu cùng loại với nhau sẽ được gửi và nhận song song, các loại dữ liệu cùng loại khác sẽ chờ cho tới khi quá trình của dữ liệu trước đó gửi xong rồi tới loại dữ liệu khác.

ss_7
 

Thuận lợi và bất lợi

Thuận lợi

  • Phương pháp này rất có lợi nếu các thành phần khá nhỏ (thông thường dành cho các bộ icon, hình ảnh nhỏ) vì có thể giảm được XÁC SUẤT mà các quá trình khác ngoài việc Download diễn ra quá lâu mặc dù xảy ra song song (DNSLOOKUP là một ví dụ như trên).
  • Giảm được số lượng request tới server, giúp server làm việc ít hơn.
  • Trong quá trình gửi request, nếu request bao gồm cả cookie, sẽ giảm đáng kể được việc gửi qua lại cookie giữa Client và Server.
  • Dễ hơn cho việc quản lý tập trung một bộ dữ liệu, xác suất tiết kiệm được bộ nhớ của máy tính khi sắp xếp các thành phần hợp lý bằng cách tận dụng các khoảng trống trong Image Sprite.
  • Thông thường các ảnh nén chuẩn PNG sẽ nén tốt hơn nếu thành phần màu là liên tục, xác suất giảm thiểu dung lượng file sẽ cao hơn nếu màu ít và liên tục.

Bất lợi

  • Phải thiết kế trước các thành phần cần thiết, khi thêm một thành phần mới, sẽ phải CẬP NHẬT cho Image Sprite và CSS gây ảnh hưởng tới các thành phần cũ thay vì chỉ cần THÊM MỚI.
  • Phương pháp này chỉ phù hợp khi các thành phần trong Image Sprite nhỏ (thường dùng cho các button, icon nhỏ) do nếu các thành phần trong Sprite quá lớn, sẽ phải download lâu hơn thay vì nếu chia nhỏ ra sẽ tận dụng được khả năng download song song của trình duyệt.

*Phù hợp với các thành phần nhỏ, ít thay đổi.

Các trang web đang sử dụng Image Sprite

  • www.youtube.com
  • www.facebook.com
  • www.gmail.com
  • www.microsoft.com

Lời kết

Việc sử dụng kỹ thuật đúng đắn và phù hợp sẽ giúp cho kết quả đạt mong đợi tốt hơn, bất kỳ giải pháp nào cũng có điểm tốt và điểm hạn chế, do đó, chúng ta cần phân tích cụ thể yêu cầu và tìm ra giải pháp phù hợp nhất, và kể cả yếu tố này cũng có thể thay đổi theo thời gian.

THẢO LUẬN
ĐÓNG