Giới thiệu
Nếu bạn thuộc nhóm những người thích nắm bắt những vấn đề như cách hoạt động của trình duyệt, thì chắc hẳn bạn đã biết rằng gần đây có một số bài viết thú vị trình bày chi tiết về hoạt động kết hợp/kết xuất đồ hoạ được 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ì 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 Ảnh trượt tuyết 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 cách thiết lập này, chúng tôi tạo một bộ các 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ụ: dưới đâ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 điều 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 tôi tìm thấy bằng chứng cho thấy một số thuộc tính CSS thực sự đắt đỏ khi hiển thị hơn 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à điều thú vị hơn là các tổ hợp các Thuộc tính CSS có thể có thời gian hiển thị lớn hơn tổng các phần của chúng. 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ực sự thú vị về việc nà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ả các tổ hợp đó; 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ế độ Hiển thị liên tục của Chrome trong Công cụ cho nhà phát triển của Chrome để hiểu rõ bạn đang phải trả phí cho những thuộc tính CSS nào.
- 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ứ được biết là tốn kém hơn, chẳng hạn như độ dốc 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ể bỏ qua bài viết này để tránh đặt box-shadow: 1px 2px 3px 4px
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.