Màn hình có mật độ điểm ảnh cao đang nhanh chóng trở thành tiêu chuẩn. Nhà sáng tạo nội dung cần thích ứng với thực tế này. Đây là một hướng dẫn ngắn về cách phân phát hình ảnh chất lượng cao trên web hiện nay mà không cần đến đoạn mã polyfill, JavaScript, tấn công CSS và những tính năng trình duyệt chưa được triển khai. Nói tóm lại: không có những thay đổi lớn đối với quy trình làm việc.
Hiện có nhiều đề xuất về hình ảnh thích ứng, trong đó có nhiều đề xuất liên quan đến những thay đổi đáng kể đối với nhà phát triển web. Thuộc tính <img>
srcset
theo dõi tiêu chuẩn khó triển khai, đặc biệt là với tính phức tạp của việc lựa chọn bổ sung dựa trên khung nhìn của srcset
:
banner-HD.jpeg 2x, banner-phone.jpeg 100w, banner-phone-HD.jpeg 100w 2x
Mặc dù thuộc tính CSS image-set
chỉ sử dụng devicePixelRatio
để quyết định hình ảnh cần tải, nhưng thuộc tính này vẫn buộc nhà phát triển phải viết nhiều mã đánh dấu bổ sung cho mỗi hình ảnh.
Các đề xuất khác, chẳng hạn như phần tử <picture>
, thậm chí còn chi tiết hơn.
Hơn nữa, các lớp này không theo dõi tiêu chuẩn, vì vậy, tính sẵn có của các lớp này thậm chí còn vượt xa hơn thuộc tính srcset. JavaScript và các giải pháp phía máy chủ là giải pháp thay thế duy nhất, nhưng các phương pháp này cũng có những hạn chế riêng như đã đề cập trong các bài viết khác.
Bài viết này sẽ trình bày một số cách sử dụng hình ảnh thường thấy trên web và đề xuất các giải pháp đơn giản có thể hoạt động trên các màn hình có mật độ pixel cao cũng như màn hình thông thường. Vì mục đích của cuộc thảo luận này, bất kỳ thiết bị nào báo cáo window.devicePixelRatio
lớn hơn 1 đều có thể được coi là DPI cao, vì điều đó có nghĩa là pixel CSS không giống với pixel thiết bị và hình ảnh đang được tăng tỷ lệ.
Sau đây là bản tóm tắt:
- Sử dụng CSS/SVG thay vì hình ảnh đường quét nếu có thể.
- Sử dụng hình ảnh được tối ưu hoá cho màn hình có mật độ hiển thị cao theo mặc định.
- Sử dụng PNG cho các bản vẽ và tác phẩm nghệ thuật điểm ảnh đơn giản (ví dụ: biểu trưng).
- Dùng tệp JPEG nén cho hình ảnh có nhiều màu sắc (ví dụ: ảnh).
- Luôn đặt kích thước rõ ràng (sử dụng CSS hoặc HTML) trên tất cả các phần tử hình ảnh.
Bản vẽ đơn giản và nghệ thuật điểm ảnh
Bạn thường có thể tránh hoàn toàn hình ảnh nhỏ bằng cách sử dụng các tính năng CSS hoặc SVG.
Ví dụ: bạn không cần sử dụng hình ảnh cho các góc bo tròn vì thuộc tính CSS border-radius
được hỗ trợ rộng rãi. Tương tự, phông chữ tuỳ chỉnh được hỗ trợ rộng rãi, vì vậy, bạn không nên sử dụng văn bản "có hình ảnh".
Tuy nhiên, trong một số trường hợp, chẳng hạn như biểu trưng, hình ảnh có thể là cách duy nhất để tiếp tục. Ví dụ: biểu trưng Chrome này có kích thước tự nhiên là 256x256. Trên màn hình Retina, bạn có thể thấy đường kẻ chồng chéo ở các đường chéo và đường cong, trông nó trông rối mắt và kém chất lượng, đặc biệt là khi so sánh với văn bản được kết xuất sắc nét:
Kích thước tự nhiên: 256x256px
, kích thước thành phần: 31 kB
, định dạng: PNG
Bạn bị thuyết phục? Tốt. Bây giờ, hãy sử dụng hình ảnh có độ phân giải cao. Bạn có thể muốn tiết kiệm dung lượng bằng cách lưu biểu trưng dưới dạng JPEG, nhưng đây có thể không phải là ý hay vì việc lưu biểu trưng và các đồ hoạ khác ở định dạng có tổn hao thường có xu hướng tạo ra các cấu phần phần mềm. Trong trường hợp này, tôi đã phóng đại vấn đề bằng cách sử dụng mức độ nén rất cao, nhưng hãy lưu ý các dải trên hiệu ứng chuyển màu, các đốm trên nền trắng và các đường kẻ lộn xộn:
Kích thước tự nhiên: 512x512px
, kích thước thành phần: 13 kB
, định dạng: JPEG
Đối với hình ảnh tương đối nhỏ, bạn nên sử dụng tệp PNG 2x. Xin lưu ý rằng sự khác biệt về kích thước giữa tệp PNG 1x và 2x thường khá lớn (52 kB trong trường hợp này). Tuy nhiên, đối với biểu trưng thì đó là bộ mặt của trang web và là điều đầu tiên mà khách truy cập nhìn thấy. Nếu bạn quá chú trọng đến kích thước mà bỏ qua chất lượng, thì đó cũng sẽ là điều cuối cùng mà khách truy cập nhìn thấy!
Dưới đây là biểu trưng Chrome với tất cả huy hiệu, được giảm kích thước xuống một nửa kích thước tự nhiên cho màn hình gấp 2 lần:
Kích thước tự nhiên: 512x512px
, kích thước thành phần: 83 kB
, định dạng: PNG
Mã đánh dấu để tạo bản kết xuất ở trên như sau:
<img src="chrome2x.png" style="width: 256px; height: 256px;"/>
Lưu ý rằng tôi đã chỉ định chiều rộng và chiều cao cho hình ảnh. Điều này là cần thiết vì kích thước tự nhiên của hình ảnh là 512 px. Điều này cũng tốt cho hiệu suất vì công cụ kết xuất nắm bắt tốt kích thước của phần tử và không cần phải nỗ lực quá nhiều để tính toán kích thước đó.
Một cách tối ưu hoá có thể hiệu quả là giảm tệp PNG 24 bit xuống tệp PNG 8 bit có bảng màu. Cách này phù hợp với các hình ảnh có một số ít màu sắc, bao gồm cả biểu trưng Chrome. Để thực hiện việc tối ưu hoá này, bạn có thể sử dụng một công cụ như http://pngquant.org/. Bạn có thể thấy một chút dải ở đây, nhưng tệp này chỉ là 13 kB, đây là mức tiết kiệm kích thước khổng lồ gấp 6 lần so với tệp PNG 512x512 ban đầu.
Kích thước tự nhiên: 512x512px
, kích thước thành phần: 13 kB
, định dạng: PNG,
8-bit palette
Hình ảnh có nhiều màu sắc
Tôi đã viết một bài viết về HTML5Rocks khảo sát một số kỹ thuật hình ảnh thích ứng, đồng thời thực hiện một số nghiên cứu về việc nén tệp JPEG 1x và 2x, đồng thời so sánh kích thước thu được và chất lượng hình ảnh. Sau đây là một thẻ thông tin như vậy trong bài viết trên:
Tôi đã gắn nhãn hình ảnh với mức độ nén (biểu thị bằng chất lượng JPEG), kích thước (tính bằng byte) và ý kiến chủ quan của tôi về độ trung thực hình ảnh so sánh của hình ảnh (xếp hạng theo số). Điều thú vị ở đây là hình ảnh 2x được nén nhiều (được gắn nhãn 3) có kích thước nhỏ hơn và trông đẹp hơn so với hình ảnh 1x không nén (được gắn nhãn 4). Nói cách khác, giữa hình ảnh 4 và 3, chúng ta đã cải thiện chất lượng hình ảnh bằng cách tăng gấp đôi mỗi kích thước và tăng đáng kể mức độ nén, đồng thời giảm kích thước xuống 2 kB.
Độ nén, kích thước và chất lượng hình ảnh
Tôi muốn hiểu rõ hơn một chút về sự đánh đổi giữa mức độ nén, kích thước hình ảnh, chất lượng hình ảnh và kích thước hình ảnh. Tôi đã chạy một nghiên cứu với giả thuyết sau đây dựa trên nghiên cứu ở trên:
Giả thuyết
Với mức độ nén đủ, hình ảnh 2x sẽ trông tương đương với cùng một hình ảnh ở kích thước 1x ở một số mức nén khác (thấp hơn). Tuy nhiên, trong trường hợp này, hình ảnh 2x được nén nhiều sẽ có kích thước nhỏ hơn hình ảnh 1x.
Quy trình
- Với hình ảnh 2x, hãy tạo hình ảnh 1x.
- Nén cả hai hình ảnh ở nhiều cấp độ.
- Tạo một trang thử nghiệm hiển thị cả hai nhóm hình ảnh cạnh nhau.
- Tìm vị trí tương đương giữa các hình ảnh trong 2 tập hợp.
- Hãy lưu ý đến kích thước hình ảnh và mức nén tương đương.
- Hãy dùng thử trên cả màn hình 1x và 2x.
Tôi đã xây dựng một ứng dụng so sánh hình ảnh cạnh nhau tương tự như chế độ xem so sánh của Lightroom. Mục đích là hiển thị hình ảnh 1x và 2x cạnh nhau, nhưng cũng cho phép bạn phóng to bất kỳ phần nào của hình ảnh để có thêm chi tiết. Bạn cũng có thể chọn giữa định dạng JPEG và WebP và thay đổi chất lượng nén để xem kích thước tệp và chất lượng hình ảnh so sánh. Ý tưởng là điều chỉnh chế độ cài đặt cho một số hình ảnh, tìm ra chất lượng nén, tỷ lệ và định dạng so với chất lượng hình ảnh mà bạn cảm thấy thoải mái và sử dụng chế độ cài đặt đó cho tất cả hình ảnh.
Công cụ này cũng có sẵn để bạn sử dụng. Bạn có thể phóng to hình ảnh bằng cách chọn một khu vực phụ để phóng to.
Phân tích
Trước tiên, tôi xin nói rằng chất lượng hình ảnh là một khái niệm chủ quan. Ngoài ra, trường hợp sử dụng cụ thể của bạn có thể sẽ cho biết mức độ ưu tiên của bạn trong phổ độ trung thực hình ảnh so với phổ kích thước tệp. Ngoài ra, các loại tính năng hình ảnh khác nhau phản ứng khác nhau với chất lượng tỷ lệ và nén, vì vậy, giải pháp phù hợp với mọi trường hợp có thể không hoạt động ở đây. Mục đích của công cụ này là giúp bạn xây dựng trực giác về các tính năng nén, tỷ lệ và định dạng chất lượng ảnh.
Từ việc sử dụng trình thu phóng hình ảnh, tôi nhận thấy một vài điều nhanh chóng trở nên rõ ràng. Trước tiên, tôi thích hình ảnh quality=30 dpr=2x
hơn hình ảnh quality=90
dpr=1x
để tăng độ chi tiết. Những hình ảnh này cũng có kích thước tệp tương đương (trong trường hợp mặt phẳng, hình ảnh 2x được nén là 76 kB trong khi hình ảnh 1x không nén là 80 kB).
Các trường hợp ngoại lệ của quy tắc này là hình ảnh được nén nhiều (quality<30
) có hiệu ứng chuyển màu. Những hình ảnh này thường bị hiện tượng dải màu, điều này cũng gây ảnh hưởng xấu bất kể tỷ lệ hình ảnh. Các mẫu chim và ô tô có trong công cụ là ví dụ cho trường hợp này.
Hình ảnh WebP có vẻ sạch hơn nhiều so với JPEG, đặc biệt là ở cấp độ nén thấp. Hiện tượng dải màu này có vẻ ít nghiêm trọng hơn nhiều. Cuối cùng, hình ảnh WebP nhỏ gọn hơn nhiều.
Lưu ý và vây
Việc làm cho hình ảnh trông đẹp trên màn hình có mật độ điểm ảnh cao chỉ là một nửa trong số các vấn đề liên quan đến hình ảnh do sự khác biệt lớn về màn hình. Trong một số trường hợp, bạn có thể muốn phân phát các hình ảnh hoàn toàn khác nhau tuỳ thuộc vào kích thước của khung nhìn. Ví dụ: ảnh chân dung của Obama có thể phù hợp với màn hình có kích thước điện thoại, nhưng ảnh đứng phía trước và gắn cờ phía sau ông và một số ảnh có thể phù hợp hơn với màn hình máy tính xách tay.
Tôi đã cố tình tránh chủ đề "hướng dẫn nghệ thuật" này để chỉ tập trung vào hình ảnh DPI cao. Bạn có thể giải quyết vấn đề này bằng một số phương pháp khác nhau: sử dụng truy vấn nội dung đa phương tiện và hình nền, thông qua JavaScript, thông qua một số tính năng mới như image-set
hoặc trên máy chủ. Chủ đề này được đề cập trong phần Hình ảnh có DPI cao cho mật độ pixel biến đổi.
Tôi sẽ phê duyệt với một số vấn đề chưa được giải quyết:
- Ảnh hưởng của mức độ nén cao đến hiệu suất. Hình phạt khi giải mã hình ảnh được nén ở mức cao là gì?
- Các hình phạt về hiệu suất khi phải giảm kích thước hình ảnh khi tải hình ảnh 2x trên màn hình 1x là gì?
Tóm lại, hãy chọn CSS và SVG thay vì sử dụng hình ảnh đường quét. Nếu bắt buộc phải sử dụng hình ảnh đường quét, hãy sử dụng tệp PNG cho hình ảnh có ít bảng màu và nhiều màu đồng nhất, đồng thời sử dụng tệp JPEG cho hình ảnh có nhiều màu và độ dốc. Điều tuyệt vời về phương pháp này là phần đánh dấu của bạn hầu như không thay đổi. Tất cả những gì nhà phát triển web cần làm là tạo thành phần 2x và định cỡ hình ảnh đúng cách trong DOM.
Để đọc thêm, hãy xem bài viết của Scott Jehl về một chủ đề tương tự. Có thể hình ảnh của bạn trông sắc nét và mức sử dụng dữ liệu di động thấp!