2010-05-30 43 views
26

Khi viết một hoạt ảnh JavaScript, bạn tất nhiên tạo một vòng lặp bằng cách sử dụng setInterval (hoặc setTimeout lặp lại). Nhưng độ trễ tốt nhất để sử dụng trong các cuộc gọi setInterval/setTimeout là gì?Cách xác định "tốc độ khung hình" tốt nhất (chậm trễ setInterval) để sử dụng trong vòng lặp hoạt ảnh JavaScript?

Trong jQuery API page for the .animate() function, người sử dụng "fbogner" nói:

Chỉ cần nếu có ai quan tâm đến: Ảnh động được "trả lại" sử dụng một setInterval với thời gian ra khỏi 13ms. Điều này khá nhanh! Khoảng thời gian nhanh nhất có thể của Chrome là khoảng 10ms. Tất cả các trình duyệt khác "mẫu" vào khoảng 20-30ms.

Bất kỳ ý tưởng nào về cách jQuery xác định sử dụng số cụ thể này?


Bắt đầu thưởng. Tôi hy vọng ai đó có kiến ​​thức về mã nguồn đằng sau Chromium hoặc Firefox có thể cung cấp một số sự kiện khó có thể sao lưu quyết định của tốc độ khung hình cụ thể. Hoặc có lẽ một danh sách các hình ảnh động (hoặc khung công tác) và sự chậm trễ của chúng. Tôi tin rằng điều này làm cho một cơ hội thú vị để làm một chút nghiên cứu.


Thú vị - Tôi vừa dành thời gian xem mã nguồn của Google Pac-Man để xem những gì họ đã làm. Họ thiết lập một loạt các FPS có thể (90, 45, 30), bắt đầu từ đầu tiên, và sau đó mỗi khung họ kiểm tra "chậm" của khung (số khung vượt quá thời gian quy định của nó). Nếu độ chậm đi vượt quá 50ms 20 lần, tốc độ khung hình sẽ giảm xuống mức tiếp theo trong danh sách (90 -> 45, 45 -> 30). Có vẻ như tốc độ khung hình không bao giờ được nâng lên, có lẽ vì trò chơi quá ngắn ngủi nên sẽ không có vấn đề gì khi viết mã đó.

Ồ, và độ trễ setInterval tất nhiên được đặt thành 1000/tốc độ khung hình. Họ làm, trên thực tế, sử dụng setInterval và không lặp lại setTimeouts.

Tôi nghĩ tính năng tốc độ khung hình động này khá gọn gàng!

Trả lời

16

Tôi muốn mạo hiểm nói rằng một phần lớn người dùng web đang sử dụng màn hình làm mới ở 60Hz, dịch thành một khung 16,66ms một lần. Vì vậy, để làm cho màn hình nút cổ chai, bạn cần phải sản xuất khung hình nhanh hơn 16.66ms.

Có hai lý do bạn sẽ chọn một giá trị như 13ms. Đầu tiên, trình duyệt cần một chút thời gian để vẽ lại màn hình (theo kinh nghiệm của tôi, không bao giờ nhỏ hơn 1ms). Mà đặt bạn tại, nói, cập nhật mỗi 15ms, đó sẽ xảy ra là một số rất thú vị - độ phân giải hẹn giờ tiêu chuẩn trên Windows là 15ms (xem John Resig's blog post). Tôi nghi ngờ rằng một 15ms hoạt hình tốt bằng văn bản trông rất giống nhau trên một loạt các trình duyệt/hệ điều hành.

FWIW, fbogner là sai đồng đều về bộ kích hoạt trình duyệt không phải ChromeTối ưu mỗi 20-30ms. Tôi đã viết một test để đo tốc độ của bắn setInterval, và nhận được những con số:

  • Chrome - 4ms
  • Firefox 3.5 - 15ms
  • IE6 - 15ms
  • IE8 - 15ms
+0

Liên kết bài đăng trên blog của 'John Resig trỏ đến địa chỉ sai –

+0

bài đăng trên blog của John Resig có lẽ nên trỏ đến http://ejohn.org/blog/accuracy-of-javascript-time/ –

+0

Đã sửa - cảm ơn. –

1

Không biết lý do đằng sau khoảng thời gian của jQuery, vì 13ms chuyển thành 80fps rất nhanh. Các "tiêu chuẩn" fps được sử dụng trong phim và như vậy là 25fps và đủ nhanh mà mắt người sẽ không nhận thấy bất kỳ jittering. 25fps chuyển thành 40ms, do đó, để trả lời câu hỏi của bạn: bất kỳ điều gì dưới 40ms là đủ cho hoạt ảnh.

+0

Jitter là đáng chú ý ở 30 khung hình/giây cho các trò chơi. Khi bạn đã chơi ở tốc độ 200 khung hình/giây và giảm xuống còn 40 khung hình/giây, điều đó là đáng chú ý. Sau đó, một lần nữa, mà có thể phải làm với màn hình làm mới ... BTW, khi trình duyệt render để họ sử dụng đồng bộ dọc? Nếu vậy, bạn bị khóa nhiều ở 50/60 khung hình/giây ... – Warty

+6

phim được quay ở tốc độ 24 khung hình/giây, đủ chậm để chụp được chuyển động mờ tự nhiên. bộ não của bạn làm mịn mọi thứ khi xem một bộ phim. hoạt ảnh được hiển thị tự động sẽ không có lợi ích khi bị bắt từ cuộc sống thực. – lincolnk

3

Khi thực hiện vòng lặp cho hoạt ảnh, tốt nhất bạn nên tìm sự cân bằng giữa tốc độ vòng lặp và số lượng công việc cần thực hiện.

Ví dụ: nếu bạn muốn trượt một div trên trang trong vòng một giây để đó là hiệu ứng đẹp và kịp thời. Bạn sẽ bỏ qua các tọa độ và có thời gian lặp lại hợp lý để hiệu ứng đáng chú ý, nhưng không phải là sự thay đổi.

Vì vậy, đó là một thử nghiệm và lỗi điều (bằng cách phải đưa công việc, thời gian, và khả năng trình duyệt vào tài khoản). Vì vậy, nó không chỉ trông đẹp trên một trình duyệt.

2

Số được nói bởi fbogner đã được kiểm tra. Trình duyệt điều chỉnh hoạt động js ở một mức độ nhất định có thể sử dụng được mọi lúc.

Nếu javascript của bạn có thể chạy mỗi 5msec thời gian chạy trình duyệt sẽ có ít thời gian cpu để làm mới hiển thị hoặc phản ứng khi người dùng nhập (nhấp chuột) vì thực thi javascript chặn trình duyệt.Tôi nghĩ rằng chrome-dev cho phép bạn chạy javascript của bạn trong khoảng thời gian ngắn hơn nhiều so với các trình duyệt khác vì V8-Javascript-Engine biên dịch JavaScript và do đó nó chạy nhanh hơn và trình duyệt sẽ bị chặn miễn là giải thích js-code.

Nhưng động cơ không phải là chỉ nên nhanh hơn nhiều để cho phép khoảng cách ngắn hơn các devs đã chắc chắn kiểm tra đó là khoảng thời gian ngắn nhất có thể tốt nhất để cho phép khoảng thời gian ngắn và không ngăn chặn các trình duyệt cho đến dài

+0

Ai là fbogner? – Ricket

+0

Người bạn đã trích dẫn trong câu hỏi của bạn xD –

+0

Ồ, haha! Tôi thậm chí còn không nhớ điều đó, vì tôi đã viết câu hỏi này cách đây vài tuần ... – Ricket

5

Các pseudo- mã cho điều này là:

FPS_WANTED = 25 
(just a number, it can be changed while executing, or it can be constant) 

TIME_OF_DRAWING = 1000/FPS_WANTED 
(this is in milliseconds, I believe it is accurate enough) 
(should be updated when FPS_WANTED changes) 

UntilTheUserLeavesTheDrawingApplication() 
{ 

    time1 = getTime(); 
    doAnimation(); 
    time2 = getTime(); 
    animationTime = time2-time1; 

    if (animationTime > TIME_OF_DRAWING) 
    { 
    [the FPS_WANTED cannot be reached] 
    You can: 
    1. Decrease the number of FPS to see if a lower framerate can be achieved 
    2. Do nothing because you want to get all you can from the CPU 
    } 
    else 
    { 
    [the FPS can be reached - you can decide to] 
    1. wait(TIME_OF_DRAWING-animationTime) - to keep a constant framerate of FPS_WANTED 
    2. increase framerate if you want 
    3. Do nothing because you want to get all you can from the CPU 
    } 

} 

Tất nhiên có thể có các biến thể này nhưng đây là thuật toán cơ bản hợp lệ trong mọi trường hợp hoạt ảnh.

+1

+1 cảm ơn vì đã đơn giản và dễ hiểu –

Các vấn đề liên quan