Tối ưu browser rendering: Paint

60fps là mục tiêu cuối cùng của một web page "mượt"

Trong phần tiếp theo của series tối ưu render trên trình duyệt, chúng ta sẽ cùng tìm hiểu về cơ chế tiếp theo trong quá trình rendering, đó là pain, hay repaint.

Tổng quan về paint?

Paint là gì

Paint is the process of filling in pixels that eventually get composited to the users' screens.

Nôm na ra thì paint chính là quá trình trình duyệt đổ đầy pixel và tô màu cho các khối sau khi quá trình reflow kết thúc.

Sử dụng Chrome dev tools để có cái nhìn trực quan về paint

Đầu tiên trong dev tool (F12 hoặc Ctrl + Shift + I (Cmd + shift + I đối với macos)), các bạn chọn dấu 3 chấm > More tools > Rendering.

paint1.jpg

Sau đó tick vào Paint flashing:

paint2.jpg

Rồi giờ các bạn thao tác lòng vòng trong page sẽ thấy magic.

Paint trong pipeline

Để dễ hình dung thì chúng ta cùng nhìn lại rendering pipeline:

paint3.jpg

Từ pipeline trên, chúng ta có thể dễ dàng nhận ra thời điểm paint được kích hoạt. Do nằm gần cuối pipeline, nên tất cả các thay đổi trước đó sẽ đều kích hoạt paint.

Paint cũng là tác vụ sẽ chạy lâu nhất trong pipeline, do đó việc hết chế repaint là điều rất cần chú ý.

Các yếu tố kích hoạt repaint

Đầu tiên nếy bạn kích hoạt reflow, repaint sẽ luôn được kích hoạt liên đới, vì bất cứ việc thay đổi toạ độ hay hình dạng hình học của element đều cần đến việc chỉnh sửa lại pixels của chúng (refill pixel). Thứ hai, repaint vẫn xảy ra ngay khi có sự thay đổi mà ko phải thay đổi toạ độ hay hình dạng hình học, ví dụ background, màu chữ, đổ bóng, ... Việc thay đổi những thuộc tính này tuy không kích hoạt reflow, những vẫn kích hoạt repaint.

Một vời lời khuyên

Compositor layers và Promote elements

Nếu bạn làm việc với CSS đủ nhiều, chắc hẳn bạn sẽ từng một vài lần gặp trường hợp animation ko đc mượt, xong bạn hỏi chị Gu gồ thì ra một số lời khuyên sử dụng transform: translateZ(0); hoặc will-change: transform;. Các bạn dùng thử và ... magic magic magic!. Mượt vcl.

Vậy thực sự 2 thuộc tính trên là gì. Trước tiên compositor layers là gì? Các bạn có thể hiểu compositor layers là nhóm nhiều elements lại thành 1 layer, giống kiểu photoshop hay sketch ấy. Sau khi nhóm xong chúng ta sẽ đề đạt với browser rằng chúng ta muốn có 1 compositor layers. Để làm gì? Việc painting ko chỉ xảy ra đối với một element mà có thể sẽ xảy ra với nhiều elements gần như cùng lúc. Để tránh việc một element bị kích hoạt repaint và kéo theo các elements khác cũng bị kích hoạt repaint một cách không đồng thời, chúng ta có thể gộp các elements này lại thành một compisitor layer, và đề xuất (promote) với trình duyệt về việc layer này sẽ cần được repaint. Việc promote compositor layer này sẽ giúp cảnh báo sớm trình duyệt về một loạt các elements sẽ cần repaint, từ đó gíup trình duyệt có đc sự chuẩn bị, giúp thời gian repaint rút ngắn.

Cụ thể thì thực hiện thế nào. Khá đơn giản, chỉ cần áp dụng thuộc tính sau vào tập hợp các element mà chúng ta muốn khai báo thành compositor layer.

.moving-element {
    will-change: transform;
}

Hoặc thuộc tính sau đối với safari và safari mobile:

.moving-element {
    transform: translateZ(0);
}

Sử dụng transform và opacity cho animation

Cách tuyệt vời nhất để tăng hiệu năng rendering là tránh luôn 2 thằng Layout (reflow) và Paint (repaint) trong rendering pipeline.

paint4.jpg

Để làm việc này thì chúng ta chỉ nên sử dùng những thuộc tính CSS được trình duyệt xử lý như là compositor layer cho việc animation. Hiện tại chỉ có 2 thuộc tính làm đc việc này, đó là transformopacity.

paint5.jpg

Giảm độ phức tạp của paint

Trong các thuộc tính liên quan đến paint thì không phải thằng nào cũng tốn thời gian như nhau. Sẽ có thằng tốn nhiều thằng tốn ít, ví dụ các thuộc tính dính dáng đến blur như box-shadow: 0, 4px, 4px, rgba(0,0,0,0.5); sẽ tốn thời gian hơn background: red;. Có thể bạn sẽ ko nhận ra sự khác biệt ở một số trường hợp, tuy nhiên thực sự là có.

Paint profiling

Căn cứ vào đâu để chúng ta có thể đưa ra lựa chọn xem dùng cách nào để tối ưu painting. Chắc chắn là phải dựa vào con số, đặc biệt là việc Promote elements.

Các bạn có thể tìm hiểu thêm về cách đo lường performance bằng công cụ timeline tại đây: https://developers.google.com/web/tools/chrome-devtools/evaluate-performance/timeline-tool

Tham khảo

https://developers.google.com/web/fundamentals/performance/rendering/simplify-paint-complexity-and-reduce-paint-areas https://developers.google.com/web/fundamentals/performance/rendering/stick-to-compositor-only-properties-and-manage-layer-count https://www.smashingmagazine.com/2016/12/gpu-animation-doing-it-right/#top (Một bài viết cực chi tiết về paint performance) https://developers.google.com/web/tools/chrome-devtools/evaluate-performance/timeline-tool

Previous Post Next Post