Giới thiệu
Nếu là người luôn cập nhật những thông tin như cách hoạt động của trình duyệt, thì bạn đã biết rằng gần đây có một số bài viết tuyệt vời mô tả chi tiết về hoạt động kết hợp/trình kết xuất tăng tốc GPU của Chrome. Trước tiên, Hiển thị tăng tốc trong Chrome: Mô hình lớp là một phần giới thiệu tuyệt vời về cách Chrome sử dụng khái niệm lớp để vẽ trang; và để tìm hiểu sâu hơn, Hợp nhất tăng tốc GPU trong Chrome thảo luận về cách Chrome sử dụng các lớp này, cùng với GPU để hiển thị trang của bạn.
Câu hỏi triết học
Sau khi dành rất nhiều thời gian để viết trình quét đường quét phần mềm cho mục đích 3D, tôi nhận thấy rõ ràng rằng một số thuộc tính CSS sẽ có hiệu suất khác nhau khi vẽ trang. Ví dụ: việc tạo điểm ảnh cho một hình ảnh nhỏ trên màn hình là một thao tác thuật toán hoàn toàn khác với việc vẽ bóng đổ trên một hình dạng tuỳ ý. Vậy câu hỏi đặt ra là: Các thuộc tính CSS khác nhau ảnh hưởng như thế nào đến trọng lượng kết xuất của trang?
Mục tiêu của tôi là phân loại một tập hợp lớn các thuộc tính/giá trị CSS theo thời gian vẽ để chúng ta có thể hiểu được loại thuộc tính CSS nào hoạt động hiệu quả hơn so với các loại khác. Để làm việc này, tôi đã viết một số mã tự động hoá bằng băng keo và kẹo cao su để cố gắng thêm chế độ hiển thị dạng số vào thời gian vẽ CSS. Mã này hoạt động như sau:
- Tạo một bộ trang HTML riêng lẻ; mỗi trang có một phần tử DOM và một số hoán vị của các thuộc tính CSS được đính kèm.
- Chạy một số tập lệnh tự động hoá, đối với mỗi trang, sẽ:
- Khởi chạy Chrome
- Tải trang
- Tạo một Hình ảnh Skia cho trang
- Chạy từng Hình ảnh Skia được chụp thông qua Skia Benchmark để lấy thời gian
- Hãy kết xuất tất cả thời gian và chiêm ngưỡng những con số. (Phần này rất quan trọng…)
Với chế độ thiết lập này, chúng ta tạo một bộ trang HTML, trong đó mỗi trang chứa một hoán vị duy nhất của các thuộc tính và giá trị CSS; ví dụ: sau đây là hai tệp html:
<style>
#example1 {
background: url(foo.png) top left / 50% 60%;
padding: 20px;
margin-top: 10px;
margin-right: 20px;
text-align: center;
}
</style>
<div id="example1">WOAH</div>
Và một cách khác, phức tạp hơn
<style>
#example1 {
background-color:#eee;
box-shadow: 1px 2px 3px 4px black;
border-radius: 50%;
background: radial-gradient(circle closest-corner, white, black);
padding: 20px;
margin-top: 10px;
margin-right: 20px;
text-align: center;
}
</style>
<div id="example1">WOAH</div>
Dưới đây là một biến thể của ví dụ cuối cùng, trong đó chúng ta chỉ thay đổi giá trị radial-gradient:
<style>
#example1
{
background-color:#eee;
box-shadow: 1px 2px 3px 4px black;
border-radius: 50%;
background: radial-gradient(farthest-side, white, black);
padding: 20px;
margin-top: 10px;
margin-right: 20px;
text-align: center;
}
</style>
<div id="example1" style="padding: 20px; margin-top: 10px;margin-right: 20px; text-align: center;">WOAH</div>
Sau đó, mỗi trang được tải vào một phiên bản mới của Chrome (để đảm bảo rằng thời gian không bị thiên vị theo bất kỳ trạng thái cũ nào trong quá trình tải lại trang) và Skia Picture (*.SKP) được lấy để đánh giá những lệnh Skia được dùng để vẽ trang. Sau khi tạo tệp SKP cho mỗi tệp HTML, chúng ta sẽ chạy một lô khác để đẩy các tệp *.SKP thông qua ứng dụng Skia Benchmark (được tạo từ mã nguồn Skia). Ứng dụng này sẽ kết xuất thời gian trung bình để hiển thị trang đó.
Đánh giá dữ liệu
Từ đó, chúng ta có thể ước chừng thời gian vẽ của một bộ thuộc tính CSS. Hoặc đúng hơn, chúng ta có thể bắt đầu xếp hạng các thuộc tính CSS theo hiệu suất vẽ. Dưới đây là một biểu đồ lớn được lấy bằng Chrome 27 beta, cho thấy toàn bộ tập dữ liệu thời gian của quy trình này. Xin lưu ý rằng tất cả dữ liệu đều có thể thay đổi vì Chrome ngày càng nhanh hơn theo thời gian.
Mỗi thanh dọc đại diện cho thời gian vẽ của một trang có một tổ hợp thuộc tính CSS duy nhất, (được phóng to 100 lần; giá trị theo tỷ lệ thực của biểu đồ này là 0,156 mili giây). Có rất nhiều đường kẻ đẹp mắt, nhưng ở dạng này thì hơi vô dụng; chúng ta cần phải khai thác dữ liệu để tìm ra các xu hướng hữu ích.
Trước tiên, chúng ta tìm thấy bằng chứng cho thấy một số thuộc tính CSS đơn giản là tốn kém hơn để hiển thị so với các thuộc tính khác. Ví dụ: việc vẽ bóng đổ trên một phần tử DOM liên quan đến một thao tác nhiều lần với các đường cong gập khúc và các loại thứ khác khó chịu, trái ngược với độ mờ dễ kết xuất hơn.
Thứ hai và thú vị hơn, các tổ hợp thuộc tính CSS có thể có thời gian vẽ lớn hơn tổng thời gian vẽ của các phần. Từ góc độ của người quan sát, điều này hơi kỳ lạ, chúng ta dự kiến A+B = C, chứ không phải 2,2C. Ví dụ: thêm box-shadow
và border-radius-stroke
:
Điều thú vị ở đây là không chỉ thuộc tính box-shadow
mà còn là sự hoán vị giá trị cụ thể đó. Ví dụ: bên dưới là một nhóm box-shadow : 50%
và border-radius
với các biến thể giá trị.
Khi xem dữ liệu, bạn sẽ thấy quá trình này diễn ra trong một khoảng thời gian. Có rất nhiều tổ hợp kỳ lạ và bộ kiểm thử của tôi hầu như không chạm đến tất cả; vẫn còn rất nhiều kiểm thử và tổ hợp có thể mang lại kết quả thú vị
Tìm trọng số kết xuất trang
Nhờ có khả năng theo dõi thời gian kết xuất cho từng phần tử trên trang, nhà phát triển có thể bắt đầu đánh giá trọng số kết xuất trang và mức độ ảnh hưởng của trọng số này đến khả năng phản hồi của trang web; Dưới đây là một số mẹo để bắt đầu
- Sử dụng Chế độ vẽ liên tục của Chrome trong Công cụ cho nhà phát triển Chrome để hiểu những thuộc tính CSS nào đang gây hao tổn cho bạn.
- Tích hợp quy trình xem xét CSS vào quy trình xem xét mã hiện có để phát hiện các vấn đề về hiệu suất Tìm những vị trí trong CSS mà bạn đang sử dụng những thành phần được biết là tốn kém hơn, chẳng hạn như hiệu ứng chuyển màu và bóng đổ. Hãy tự hỏi bản thân rằng tôi có thực sự cần những thành phần này không?
- Khi không chắc chắn, hãy luôn chọn phương án có hiệu suất tốt hơn. Người dùng có thể không nhớ chiều rộng khoảng đệm trên các cột, nhưng họ sẽ nhớ cảm giác khi truy cập vào trang web của bạn.
Những lưu ý sau cùng
Một trong những điều thú vị nhất về thử nghiệm này là thời gian sẽ tiếp tục thay đổi theo từng phiên bản Chrome (hy vọng là sẽ nhanh hơn;)) phần mềm trình duyệt là một khu vực luôn thay đổi. Những gì chậm hôm nay có thể nhanh vào ngày mai. Bạn có thể rút ra từ bài viết này để tránh đặt box-shadow: 1px 2px 3px 4px
vào một phần tử đã có border-radius:5
. Tuy nhiên, điều quan trọng hơn là các thuộc tính CSS trực tiếp ảnh hưởng đến thời gian vẽ trang.