⏱️ Đồng Hồ Bấm Giờ Trực Tuyến Có Ghi Vòng
Nhấn vào nút Bắt đầu và công cụ này không thực sự cộng dồn từng mảnh nhỏ thời gian 30 mili giây. Nó ghi lại giá trị chính xác của performance.now() ngay khi bạn nhấn Bắt đầu, sau đó mỗi lần vẽ lại, nó trừ giá trị đó khỏi thời gian hiện tại để tính thời gian đã trôi qua — được tính lại từ đầu, không cộng dồn. Sự khác biệt này quan trọng vì trình duyệt cố ý làm chậm setInterval trong các tab nền để tiết kiệm pin, điều này là nguyên nhân phổ biến khiến các đồng hồ đo thời gian tự làm mất đồng bộ hoặc mất giây. Vì đồng hồ này luôn tính toán thời gian dựa trên sự chênh lệch giữa các timestamp thay vì đếm số lần tick thực tế đã xảy ra, thời gian hiển thị sẽ quay lại giá trị chính xác ngay khi bạn quay lại tab, ngay cả sau hàng phút không sử dụng.
Đồng hồ bấm giờ là một công cụ đo thời gian miễn phí trong trình duyệt, theo dõi thời gian trôi qua bằng cách so sánh đồng hồ performance.now() (một đồng hồ đơn điệu) với thời điểm bắt đầu được lưu trữ, thay vì đếm các tick của setInterval, do đó số hiển thị vẫn chính xác ngay cả khi trình duyệt làm chậm các cập nhật màn hình của tab.
Riêng tư từ thiết kế. Công cụ này chạy hoàn toàn trong trình duyệt của bạn — không có gì bạn nhập bị tải lên hay lưu lại, và hoạt động cả khi ngoại tuyến.
Giới thiệu
Bên trong có ba trạng thái: một giá trị 'elapsed' (thời gian đã trôi qua) tính bằng mili giây, một 'startAt' là bản chụp của performance.now() được ghi lại ngay khi bạn nhấn Bắt đầu, và một cờ 'running' (đang chạy) là boolean. Hàm tạo ra con số hiển thị trên màn hình chỉ đơn giản là 'elapsed' cộng thêm, nếu đang chạy, sự chênh lệch giữa thời điểm hiện tại và 'startAt'. Một 'setInterval' gọi hàm này mỗi 30 mili giây chỉ để làm tươi màn hình — khoảng thời gian này không chứa thông tin thời gian, chỉ là một tín hiệu làm tươi. Đây là cách đúng để xây dựng một đồng hồ bấm giờ, và nó trực tiếp tránh lỗi phổ biến khi đồng hồ cộng thêm một lượng cố định trên mỗi tick và dần dần trôi dạt khi các tick bị chậm, bỏ qua hoặc gộp lại.
Lựa chọn thiết kế này cũng là điều xảy ra khi bạn chuyển sang tab khác. Trình duyệt làm chậm các đồng hồ trong tab nền để tiết kiệm CPU và pin — một 'setInterval' được thiết lập mỗi 30 mili giây có thể bị chậm lại xuống mỗi giây hoặc chậm hơn nữa khi tab không hiển thị. Trên đồng hồ bấm giờ này, điều đó chỉ ảnh hưởng đến tần suất làm tươi con số trên màn hình; toán học cơ bản (thời điểm hiện tại trừ thời điểm bắt đầu, cộng thêm thời gian đã tích lũy) không quan tâm đến số lần làm tươi bị bỏ qua. Chuyển lại tab và lần làm tươi tiếp theo sẽ hiển thị thời gian trôi qua chính xác — không mất hay thêm thời gian do việc làm chậm, chỉ là sự mượt mà khi xem giây đếm khi bạn đang xem thứ khác.
Việc sử dụng 'performance.now()' thay vì 'Date.now()' cũng là lựa chọn đúng cho công việc này, không phải chi tiết phụ. 'Date.now()' phản ánh đồng hồ tường (wall clock) của hệ thống, và đồng hồ tường có thể nhảy — ví dụ như sau khi máy tính tỉnh từ chế độ ngủ và đồng bộ lại với máy chủ NTP, thay đổi đồng hồ thủ công, hoặc điều chỉnh giờ tiết kiệm năng lượng có thể khiến 'Date.now()' nhảy lên hoặc thậm chí xuống giữa phiên. 'performance.now()' được định nghĩa là một đồng hồ đơn điệu: nó chỉ bao giờ tăng đều đặn và không bị ảnh hưởng bởi các điều chỉnh đó, đây chính xác là đảm bảo mà đồng hồ bấm giờ cần có, trong khi đồng hồ tường thông thường thì không có.
Giới hạn trung thực là tính bền bỉ, và không có gì cả. Thiết kế này lưu trữ 'elapsed' và mảng 'laps' dưới dạng biến JavaScript thông thường trong bộ nhớ trang — không có lệnh nào trong mã nguồn gọi đến localStorage hay đến hàm 'Playground.store()' của trang web này mà các công cụ khác của Toolio sử dụng để lưu trữ khi trang được tải lại. Điều đó có nghĩa là làm tươi trang, đóng tab, hoặc chuyển sang công cụ khác sẽ xóa thời gian đang chạy và mọi lần đo đã ghi lại ngay lập tức và vĩnh viễn. Không có tính năng 'tiếp tục phiên trước', không có đồng bộ giữa các thiết bị, và không có gì để sao lưu, bởi vì không có dữ liệu nào được ghi vào bộ nhớ từ đầu. Nếu lịch sử lần đo thực sự quan trọng với bạn — ví dụ như nhật ký tập thể dục, hoặc thời gian trình bày — hãy ghi lại các con số hoặc chụp ảnh màn hình trước khi rời khỏi trang, bởi vì trang này sẽ không nhớ chúng cho bạn.
Cách sử dụng
- Nhấn vào nút 'Bắt đầu' — nút sẽ ngay lập tức đổi nhãn thành 'Tạm dừng' và đồng hồ trên màn hình bắt đầu tăng dần theo thời gian thực, làm tươi mỗi 30 mili giây.
- Nhấn vào nút 'Lần đo' bất kỳ lúc nào khi đang chạy để chụp lại thời gian đã trôi qua; mục mới sẽ được gắn ở đầu danh sách lần đo và hiển thị cả thời gian chênh lệch (tính từ lần đo trước) và tổng thời gian tích lũy.
- Nhấn nút đó lần nữa, nay được ghi nhãn là 'Tạm dừng', để đóng băng hiển thị — thời gian đã trôi qua được lưu trữ bên trong, không mất gì cả, và nút sẽ quay lại nhãn 'Bắt đầu'.
- Nhấn 'Bắt đầu' lần nữa để tiếp tục đếm từ đúng thời điểm bạn đã dừng lại, không phải từ 0.
- Nhấn 'Đặt lại' để đưa hiển thị về 0, xóa tất cả lần đo đã ghi, và khôi phục lại nhãn của cả hai nút về trạng thái ban đầu — đây cũng là cách duy nhất để bắt đầu một phiên mới, vì không có tính năng lưu trữ để bảo vệ phiên cũ trước đó.
Câu hỏi thường gặp
- Đồng hồ bấm giờ này thực sự đo thời gian như thế nào bên trong?
- Nó đọc 'performance.now()' một lần, ngay khi bạn nhấn Bắt đầu, và lưu trữ con số đó. Từ đó, giá trị trên màn hình chỉ là 'thời gian đã tích lũy' cộng với 'performance.now() hiện tại trừ đi timestamp bắt đầu đã lưu trữ' — được tính lại từ đầu mỗi 30 mili giây khi làm tươi màn hình. Nó không bao giờ chỉ cộng thêm cố định +30 mili giây vào tổng thời gian đang chạy trên mỗi tick, điều này là cách tắt nhanh khiến nhiều đồng hồ tự làm chậm dần dần không đồng bộ.
- Điều gì xảy ra với thời gian nếu tôi chuyển sang tab trình duyệt khác khi đồng hồ đang chạy?
- Các tab nền bị làm chậm — trình duyệt có thể làm chậm 'setInterval' 30 mili giây xuống chỉ mỗi giây hoặc chậm hơn nữa để tiết kiệm CPU và pin, do đó con số trên màn hình có thể dường như bị đóng băng hoặc nhảy khi bạn không nhìn thấy. Tuy nhiên, vì đồng hồ này luôn tính toán thời gian trôi qua dựa trên sự chênh lệch timestamp thay vì đếm số lần tick đã xảy ra, việc quay lại tab sẽ khiến lần làm tươi tiếp theo hiển thị thời gian trôi qua chính xác. Bạn không mất hay thêm thời gian do việc làm chậm — chỉ sự mượt mà của việc xem giây đếm bị ảnh hưởng khi bạn không nhìn.
- Tại sao lại dùng 'performance.now()' thay vì 'Date.now()' — điều này thực sự có quan trọng không?
- Có. 'Date.now()' phản ánh đồng hồ tường của hệ thống, có thể nhảy lên hoặc xuống — ví dụ như ngay sau khi máy tính tỉnh từ chế độ ngủ và đồng bộ lại với máy chủ NTP, hoặc nếu đồng hồ hệ thống bị thay đổi thủ công. 'performance.now()' là một đồng hồ đơn điệu, chỉ tăng đều đặn và không bị ảnh hưởng bởi các điều chỉnh đó, đây chính xác là tính chất mà đồng hồ bấm giờ cần có, và thiết kế này sử dụng đúng loại đồng hồ đó.
- Nó có lưu trữ thời gian đã trôi qua hoặc lịch sử lần đo ở đâu không?
- Không — và khác với một số công cụ Toolio khác, nó hoàn toàn không sử dụng localStorage của trình duyệt để lưu trữ dữ liệu này. Mọi thứ bạn thấy chỉ tồn tại trong bộ nhớ của trang cho đến khi tab cụ thể này còn mở. Làm tươi trang, đóng tab, hoặc chuyển sang công cụ khác sẽ khiến thời gian đã trôi qua và mọi lần đo biến mất mãi mãi; không có tính năng 'khôi phục' hay 'lưu tự động', bởi vì không có dữ liệu nào được ghi vào bộ nhớ từ đầu. Nếu bạn cần ghi lại các con số, hãy ghi chúng lại hoặc chụp ảnh màn hình trước khi rời đi.
- Có giới hạn nào đối với số lần đo không, và hai con số trên mỗi hàng lần đo có ý nghĩa gì?
- Không có giới hạn — danh sách sẽ chỉ tăng lên, với lần đo mới nhất được gắn ở đầu. Mỗi hàng hiển thị hai con số: 'khoảng thời gian' (màu nhấn mạnh), là thời gian trôi qua kể từ lần đo trước; và 'tổng thời gian' (màu xám), là tổng thời gian tích lũy kể từ khi bạn nhấn Bắt đầu. Sự kết hợp này giúp bạn đánh giá một phần cụ thể — một khoảng thời gian tập thể dục, một phần của bài thuyết trình — mà không mất theo dõi tổng thời gian.