Các trình duyệt hiện đại có thể tạo ảnh động cho hai thuộc tính CSS với chi phí thấp: transform
và opacity
.
Nếu tạo ảnh động cho bất kỳ nội dung nào khác, rất có thể bạn sẽ không đạt được tốc độ 60 khung hình/giây (FPS) mượt mà.
Bài đăng này giải thích lý do tại sao lại như vậy.
Hiệu suất ảnh động và tốc độ khung hình
Mọi người đều công nhận rằng tốc độ khung hình 60 khung hình/giây là mục tiêu khi tạo ảnh động trên web. Tốc độ khung hình này sẽ đảm bảo ảnh động của bạn trông mượt mà. Trên web, khung là thời gian cần thiết để thực hiện tất cả công việc cần thiết để cập nhật và vẽ lại màn hình. Nếu mỗi khung hình không hoàn tất trong vòng 16,7 mili giây (1000 mili giây / 60 ≈ 16,7), thì người dùng sẽ nhận thấy độ trễ.
Quy trình kết xuất
Để hiển thị nội dung trên trang web, trình duyệt phải trải qua các bước tuần tự sau:
- Kiểu: Tính toán các kiểu áp dụng cho các phần tử.
- Bố cục: Tạo hình học và vị trí cho từng phần tử.
- Paint (Vẽ): Điền các pixel cho từng phần tử.
- Hợp chất: Tách các phần tử thành lớp và vẽ các lớp đó lên màn hình.
Bốn bước này được gọi là quy trình kết xuất của trình duyệt.
Khi bạn tạo ảnh động cho một nội dung trên trang đã tải, các bước này phải diễn ra lại. Quá trình này bắt đầu từ bước phải thay đổi để cho phép ảnh động diễn ra.
Như đã đề cập trước đó, các bước này là tuần tự. Ví dụ: nếu bạn tạo ảnh động cho một nội dung thay đổi bố cục, thì các bước vẽ và kết hợp cũng phải chạy lại. Do đó, việc tạo ảnh động cho một nội dung thay đổi bố cục sẽ tốn kém hơn so với việc tạo ảnh động cho một nội dung chỉ thay đổi thành phần kết hợp.
Tạo ảnh động cho các thuộc tính bố cục
Các thay đổi về bố cục liên quan đến việc tính toán hình học (vị trí và kích thước) của tất cả các phần tử chịu ảnh hưởng của thay đổi.
Nếu bạn thay đổi một phần tử, thì có thể bạn cần phải tính toán lại hình học của các phần tử khác.
Ví dụ: nếu bạn thay đổi chiều rộng của phần tử <html>
, thì mọi phần tử con của phần tử đó đều có thể bị ảnh hưởng.
Do cách các phần tử tràn và ảnh hưởng lẫn nhau, nên các thay đổi ở phía dưới cây đôi khi có thể dẫn đến việc tính toán bố cục từ đầu đến cuối.
Cây phần tử hiển thị càng lớn thì thời gian tính toán bố cục càng lâu.
Tạo ảnh động cho các thuộc tính sơn
Vẽ là quá trình xác định thứ tự vẽ các phần tử lên màn hình. Đây thường là tác vụ chạy lâu nhất trong tất cả các tác vụ trong quy trình.
Phần lớn hoạt động vẽ trong các trình duyệt hiện đại được thực hiện trong trình tạo điểm ảnh phần mềm. Tuỳ thuộc vào cách các phần tử trong ứng dụng được nhóm thành các lớp, bạn cũng có thể cần vẽ các phần tử khác ngoài phần tử đã thay đổi.
Tạo ảnh động cho các thuộc tính tổng hợp
Kết hợp là quá trình tách trang thành các lớp, chuyển đổi thông tin về giao diện của trang thành pixel (tạo điểm ảnh) và kết hợp các lớp với nhau để tạo một trang (kết hợp).
Đây là lý do tại sao thuộc tính opacity
được đưa vào danh sách những thứ có chi phí tạo ảnh động thấp.
Miễn là thuộc tính này nằm trong lớp riêng, GPU có thể xử lý các thay đổi đối với thuộc tính đó trong bước kết hợp.
Các trình duyệt dựa trên Chromium và WebKit tạo một lớp mới cho mọi phần tử có hiệu ứng chuyển đổi hoặc ảnh động CSS trên opacity
.
Lớp là gì?
Bằng cách đặt những nội dung sẽ được tạo ảnh động hoặc chuyển đổi vào một lớp mới, trình duyệt chỉ cần vẽ lại các mục đó chứ không phải mọi thứ khác. Bạn có thể đã quen thuộc với khái niệm về lớp (layer) trong Photoshop, trong đó chứa một nhóm các phần tử có thể được di chuyển cùng nhau. Các lớp kết xuất của trình duyệt cũng tương tự như ý tưởng đó.
Mặc dù trình duyệt có thể đưa ra quyết định chính xác về những phần tử nào nên nằm trên một lớp mới, nhưng nếu thiếu một phần tử, bạn có thể buộc tạo lớp. Bạn có thể tìm hiểu về điều đó trong bài viết Cách tạo ảnh động hiệu suất cao. Tuy nhiên, bạn cần phải cẩn thận khi tạo lớp mới vì mỗi lớp đều sử dụng bộ nhớ. Trên các thiết bị có bộ nhớ hạn chế, việc tạo lớp mới có thể gây ra nhiều vấn đề về hiệu suất hơn so với vấn đề bạn đang cố gắng giải quyết. Ngoài ra, bạn cần tải kết cấu của từng lớp lên GPU. Do đó, bạn có thể gặp phải các hạn chế về băng thông giữa CPU và GPU.
Hiệu suất của CSS so với JavaScript
Bạn có thể thắc mắc: xét về hiệu suất, bạn nên sử dụng CSS hay JavaScript cho ảnh động?
Ảnh động dựa trên CSS và Ảnh động trên web (trong các trình duyệt hỗ trợ API) thường được xử lý trên một luồng được gọi là luồng trình kết hợp. Điều này khác với luồng chính của trình duyệt, nơi các thao tác tạo kiểu, bố cục, vẽ và JavaScript được thực thi. Điều này có nghĩa là nếu trình duyệt đang chạy một số tác vụ tốn kém trên luồng chính, thì các ảnh động này có thể tiếp tục mà không bị gián đoạn.
Như đã giải thích trong bài viết này, trong nhiều trường hợp, luồng trình kết hợp cũng có thể xử lý các thay đổi khác đối với phép biến đổi và độ mờ.
Nếu bất kỳ ảnh động nào kích hoạt quá trình vẽ, bố cục hoặc cả hai, thì luồng chính sẽ được yêu cầu thực hiện công việc. Điều này đúng với cả ảnh động CSS và JavaScript, và chi phí của bố cục hoặc sơn có thể sẽ nhỏ hơn bất kỳ công việc nào liên quan đến việc thực thi CSS hoặc JavaScript, khiến câu hỏi này trở nên vô nghĩa.