Tại sao một số ảnh động bị chậm?

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í rẻ: transformopacity. 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 chấp nhận tốc độ khung hình 60 khung hình/giây là mục tiêu khi tạo ảnh động cho nội dung bất kỳ 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ả nhữ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:

  1. Kiểu: Tính toán các kiểu áp dụng cho các phần tử.
  2. Bố cục: Tạo hình học và vị trí cho từng phần tử.
  3. Paint (Vẽ): Điền các pixel cho từng phần tử vào các lớp.
  4. Composite (Tổng hợp): 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 nội dung nào đó làm thay đổi bố cục, thì các bước sơn và kết hợp cũng phải chạy lại. Do đó, việc tạo ảnh động cho 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 nội dung chỉ thay đổi quá trình 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ử, hình dạng của các phần tử khác có thể cần phải được tính toán lại. 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à nhiệm vụ dài 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 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 các mục 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 những mục đó chứ không phải mọi nội dung 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, trong đó thực thi việc tạo kiểu, bố cục, tô màu và JavaScript. Đ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, những thay đổi khác đối với sự biến đổi và độ mờ cũng có thể do luồng trình tổng hợp xử lý.

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.