Hướng dẫn does css animation affect performance? - hoạt ảnh css có ảnh hưởng đến hiệu suất không?

Hoạt hình rất quan trọng cho trải nghiệm người dùng thú vị trên nhiều ứng dụng. Có nhiều cách để thực hiện các hình ảnh động web, chẳng hạn như CSS ________ 3/________ 4 hoặc hoạt hình dựa trên JavaScript (sử dụng requestAnimationFrame()). Trong bài viết này, chúng tôi phân tích sự khác biệt về hiệu suất giữa hoạt hình dựa trên CSS và dựa trên JavaScript.

Chuyển tiếp CSS và hình ảnh động

Cả hai chuyển tiếp CSS và hình ảnh động có thể được sử dụng để viết hoạt hình. Họ mỗi người có kịch bản người dùng riêng:

  • CSS transitions cung cấp một cách dễ dàng để làm cho hình ảnh động xảy ra giữa kiểu hiện tại và trạng thái CSS kết thúc, ví dụ: trạng thái nút nghỉ và trạng thái di chuột. Ngay cả khi một yếu tố ở giữa quá trình chuyển đổi, quá trình chuyển đổi mới bắt đầu từ kiểu hiện tại ngay lập tức thay vì nhảy đến trạng thái CSS cuối. Xem sử dụng chuyển đổi CSS để biết thêm chi tiết.
  • CSS animations, mặt khác, cho phép các nhà phát triển tạo hình ảnh động giữa một tập hợp các giá trị thuộc tính bắt đầu và một tập hợp cuối cùng thay vì giữa hai trạng thái. Hoạt hình CSS bao gồm hai thành phần: một kiểu mô tả hoạt hình CSS và một bộ các khung chính cho thấy trạng thái bắt đầu và kết thúc của phong cách hoạt hình, cũng như các điểm trung gian có thể. Xem bằng cách sử dụng hình ảnh động CSS để biết thêm chi tiết.

Về hiệu suất, không có sự khác biệt giữa việc thực hiện một hình ảnh động với các chuyển tiếp CSS hoặc hoạt hình. Cả hai đều được phân loại theo cùng một chiếc ô dựa trên CSS trong bài viết này.

requestAnimationFrame

API requestAnimationFrame() cung cấp một cách hiệu quả để tạo hình ảnh động trong JavaScript. Hàm gọi lại của phương thức được trình duyệt gọi trước lần lặp tiếp theo trên mỗi khung hình. So với ________ 9/________ 10, cần một tham số độ trễ cụ thể, requestAnimationFrame() hiệu quả hơn nhiều. Các nhà phát triển có thể tạo một hình ảnh động bằng cách thay đổi kiểu của một phần tử mỗi khi vòng lặp được gọi (hoặc cập nhật bản vẽ Canvas hoặc bất cứ điều gì.)

Lưu ý: Giống như chuyển đổi CSS và hình ảnh động, requestAnimationFrame() tạm dừng khi tab hiện tại được đẩy vào nền. Like CSS transitions and animations, requestAnimationFrame() pauses when the current tab is pushed into the background.

Để biết thêm chi tiết, hãy đọc hoạt hình với JavaScript từ SetInterVal đến RequestAnimationFrame.

So sánh hiệu suất: Chuyển tiếp so với RequestAnimationFrame
transitions vs. requestAnimationFrame

Thực tế là, trong hầu hết các trường hợp, hiệu suất của các hình ảnh động dựa trên CSS gần giống như hình ảnh động của Javascrip-ít nhất là trong Firefox. Một số thư viện hoạt hình dựa trên JavaScript, như GSAP và Velocity.js, thậm chí tuyên bố rằng họ có thể đạt được hiệu suất tốt hơn so với chuyển đổi/hoạt hình CSS gốc. Điều này có thể xảy ra do các chuyển đổi/hình ảnh động CSS là các kiểu phần tử được lấy mẫu lại trong luồng giao diện người dùng chính trước khi mỗi sự kiện lặp lại xảy ra, gần giống như các kiểu phần tử lấy mẫu lại thông qua cuộc gọi lại requestAnimationFrame(), cũng được kích hoạt trước lần lặp tiếp theo. Nếu cả hai hình ảnh động được thực hiện trong chuỗi UI chính, không có hiệu suất khác biệt.

Trong phần này, chúng tôi sẽ hướng dẫn bạn qua một bài kiểm tra hiệu suất, sử dụng Firefox, để xem phương pháp hoạt hình nào có vẻ tốt hơn tổng thể.

Cho phép các công cụ FPS

Trước khi đi qua ví dụ, vui lòng bật các công cụ FPS trước để xem tốc độ khung hình hiện tại:

  1. Trong thanh URL, nhập về: Cấu hình; Nhấp vào nút <div id="header"> <button id="toggle-button">Toggle</button> <span id="type">CSS Animation</span> </div> <div id="box-container"></div> 4 để vào màn hình cấu hình.
  2. Trong thanh tìm kiếm, tìm kiếm sở thích <div id="header"> <button id="toggle-button">Toggle</button> <span id="type">CSS Animation</span> </div> <div id="box-container"></div> 5.
  3. Bấm đúp vào mục nhập để đặt giá trị thành <div id="header"> <button id="toggle-button">Toggle</button> <span id="type">CSS Animation</span> </div> <div id="box-container"></div> 6. Bây giờ bạn sẽ có thể nhìn thấy ba hộp nhỏ màu tím ở góc trên bên trái của cửa sổ Firefox. Hộp đầu tiên đại diện cho FPS.

Chạy kiểm tra hiệu suất

Ban đầu trong thử nghiệm được thấy dưới đây, tổng cộng 1000 phần tử <div id="header"> <button id="toggle-button">Toggle</button> <span id="type">CSS Animation</span> </div> <div id="box-container"></div> 7 được chuyển đổi bởi hoạt hình CSS.

const boxes = []; const button = document.getElementById("toggle-button"); const boxContainer = document.getElementById("box-container"); const animationType = document.getElementById("type"); // create boxes for (let i = 0; i < 1000; i++) { const div = document.createElement("div"); div.classList.add("css-animation"); div.classList.add("box"); boxContainer.appendChild(div); boxes.push(div.style); } let toggleStatus = true; let rafId; button.addEventListener("click", () => { if (toggleStatus) { animationType.textContent = " requestAnimationFrame"; for (const child of boxContainer.children) { child.classList.remove("css-animation"); } rafId = window.requestAnimationFrame(animate); } else { window.cancelAnimationFrame(rafId); animationType.textContent = " CSS animation"; for (const child of boxContainer.children) { child.classList.add("css-animation"); } } toggleStatus = !toggleStatus; }); const duration = 6000; const translateX = 500; const rotate = 360; const scale = 1.4 - 0.6; let start; function animate(time) { if (!start) { start = time; rafId = window.requestAnimationFrame(animate); return; } const progress = (time - start) / duration; if (progress < 2) { let x = progress * translateX; let transform; if (progress >= 1) { x = (2 - progress) * translateX; transform = `translateX(${x}px) rotate(${ (2 - progress) * rotate }deg) scale(${0.6 + (2 - progress) * scale})`; } else { transform = `translateX(${x}px) rotate(${progress * rotate}deg) scale(${ 0.6 + progress * scale })`; } for (const box of boxes) { box.transform = transform; } } else { start = null; } rafId = window.requestAnimationFrame(animate); }

<div id="header"> <button id="toggle-button">Toggle</button> <span id="type">CSS Animation</span> </div> <div id="box-container"></div>

#header { position: sticky; top: 0.5rem; margin: 0 0.5rem; z-index: 100; background-color: lightgreen; } #box-container { margin-top: 1.5rem; display: grid; grid-template-columns: repeat(40, 1fr); gap: 15px; } .box { width: 30px; height: 30px; background-color: red; } .css-animation { animation: animate 6s linear 0s infinite alternate; } @keyframes animate { 0% { transform: translateX(0) rotate(0deg) scale(0.6); } 100% { transform: translateX(500px) rotate(360deg) scale(1.4); } }

Hoạt hình có thể được chuyển sang requestAnimationFrame() bằng cách nhấp vào nút chuyển đổi.

Hãy thử chạy cả hai ngay bây giờ, so sánh FPS cho mỗi (hộp màu tím đầu tiên.) Bạn sẽ thấy rằng hiệu suất của hình ảnh động CSS và requestAnimationFrame() rất gần.

Tắt hoạt hình chủ đề chính

Ngay cả khi đưa ra kết quả kiểm tra ở trên, chúng tôi sẽ lập luận rằng hoạt hình CSS là lựa chọn tốt hơn. Nhưng bằng cách nào? Điều quan trọng là miễn là các thuộc tính mà chúng tôi muốn làm động không kích hoạt Refle/REPAINT (đọc các kích hoạt CSS để biết thêm thông tin), chúng tôi có thể chuyển các hoạt động lấy mẫu đó ra khỏi luồng chính. Thuộc tính phổ biến nhất là biến đổi CSS. Nếu một phần tử được quảng bá như một lớp, các thuộc tính biến đổi hoạt hình có thể được thực hiện trong GPU, có nghĩa là hiệu suất/hiệu quả tốt hơn, đặc biệt là trên thiết bị di động. Tìm hiểu thêm chi tiết trong OffMainThreadCompositing.

Để kích hoạt OMTA (tắt hoạt hình chủ đề chính) trong Firefox, bạn có thể truy cập về: Cấu hình và tìm kiếm #header { position: sticky; top: 0.5rem; margin: 0 0.5rem; z-index: 100; background-color: lightgreen; } #box-container { margin-top: 1.5rem; display: grid; grid-template-columns: repeat(40, 1fr); gap: 15px; } .box { width: 30px; height: 30px; background-color: red; } .css-animation { animation: animate 6s linear 0s infinite alternate; } @keyframes animate { 0% { transform: translateX(0) rotate(0deg) scale(0.6); } 100% { transform: translateX(500px) rotate(360deg) scale(1.4); } } 0. Chuyển giá trị của nó thành <div id="header"> <button id="toggle-button">Toggle</button> <span id="type">CSS Animation</span> </div> <div id="box-container"></div> 6.

Sau khi bật OMTA, hãy thử chạy lại bài kiểm tra trên. Bạn sẽ thấy rằng FPS của hình ảnh động CSS bây giờ sẽ cao hơn đáng kể.

Lưu ý: Trong phiên bản hàng đêm/nhà phát triển, bạn sẽ thấy OMTA được bật theo mặc định, vì vậy bạn có thể phải thực hiện các bài kiểm tra theo cách khác (kiểm tra với nó được bật trước, sau đó vô hiệu hóa để kiểm tra mà không cần OMTA.) In Nightly/Developer Edition, you should see that OMTA is enabled by default, so you might have to do the tests the other way around (test with it enabled first, then disable to test without OMTA.)

Bản tóm tắt

Trình duyệt có thể tối ưu hóa các luồng kết xuất. Tóm lại, chúng ta nên luôn luôn cố gắng tạo hình ảnh động của mình bằng cách sử dụng chuyển đổi/hình ảnh động CSS nếu có thể. Nếu hình ảnh động của bạn thực sự phức tạp, bạn có thể phải dựa vào hình ảnh động dựa trên JavaScript.

Tài nguyên hoạt hình CSS có nặng không?

Hoạt hình liên tục có thể tiêu thụ một lượng tài nguyên đáng kể, nhưng một số thuộc tính CSS tốn kém hơn so với các thuộc tính khác. Trình duyệt càng khó hoạt động để làm động một tài sản, tốc độ khung hình sẽ càng chậm., but some CSS properties are more costly to animate than others. The harder a browser must work to animate a property, the slower the frame rate will be.

Hoạt hình CSS có sử dụng GPU không?

Chúng ta đã biết rằng hoạt hình biến đổi và độ mờ thông qua các chuyển đổi CSS hoặc hoạt hình tự động tạo ra một lớp tổng hợp và hoạt động trên GPU.works on the GPU.

Hoạt hình có làm chậm trang web không?

Quá nhiều chuyển động có thể làm chậm quá trình tải của một trang web.Quá nhiều hình ảnh động ngăn khách truy cập biết phần nào của trang để tập trung vào.Hoạt hình trang web không phải lúc nào cũng dịch tốt sang điện thoại di động, điều này dẫn đến những trải nghiệm kém.. Too many animations prevent visitors from knowing which parts of the page to focus on. Website animation doesn't always translate well to mobile, which leads to poor experiences.

Bạn có nên sử dụng hình ảnh động CSS không?

Chuyển đổi CSS và hình ảnh động là lý tưởng để mang menu điều hướng từ bên cạnh hoặc hiển thị một chú giải công cụ.Cuối cùng, bạn có thể sử dụng JavaScript để kiểm soát các trạng thái, nhưng bản thân hoạt hình sẽ nằm trong CSS của bạn.Sử dụng JavaScript khi bạn cần kiểm soát đáng kể đối với hình ảnh động của mình.. You may end up using JavaScript to control the states, but the animations themselves will be in your CSS. Use JavaScript when you need significant control over your animations.

Chủ đề