🛝Toolio
О нас Контакты

⏱️ Онлайн-секундомер с функцией отсчета кругов

Нажмите "Старт", и инструмент не просто добавляет кусочки времени по 30 миллисекунд. Он записывает точное значение performance.now() в момент нажатия, а затем при каждом обновлении экрана вычитает это значение из текущего, чтобы получить прошедшее время — пересчитывается с нуля, а не накапливается. Эта разница важна, потому что браузеры намеренно замедляют setInterval в фоновых вкладках, чтобы сэкономить заряд батареи, что является классическим способом, как домашние таймеры сдвигаются или теряют секунды. Поскольку этот секундомер всегда вычисляет время на основе разницы временных меток, а не считает, сколько тиков было отправлено, отображаемое время мгновенно возвращается к правильному значению, как только вы возвращаетесь к вкладке, даже если вы были отсутствовали несколько минут.

Секундомер — это бесплатный лап-таймер в браузере, который отслеживает прошедшее время, сравнивая монотонный performance.now() с сохранённой временной меткой начала, а не считая тики setInterval, поэтому отображаемое число остаётся точным, даже если браузер уменьшает частоту обновления вкладки.

00:00.00

Приватно по умолчанию. Этот инструмент работает полностью в вашем браузере — ничего из введённого не загружается и не сохраняется, и он работает офлайн.

Об инструменте

Внутри есть три состояния: накопленное значение `elapsed` в миллисекундах, `startAt` — снимок `performance.now()` в момент нажатия на "Старт", и булевый флаг `running`. Функция, которая выводит число на экран, просто добавляет `elapsed` к разнице между текущим временем и `startAt`, если `running` истинно. `setInterval` вызывает эту функцию каждые 30 миллисекунд исключительно для обновления отображения — сам интервал не несёт информации о времени, это просто триггер для обновления. Это правильный способ построить секундомер, и это напрямую избегает распространённой ошибки, когда таймер добавляет фиксированное значение на каждом тике и постепенно сдвигается, когда тики задерживаются, пропускаются или объединяются.

Этот выбор дизайна также влияет на то, что происходит, когда вы переключаетесь на другую вкладку. Браузеры замедляют таймеры в фоновых вкладках, чтобы сэкономить процессор и батарею — `setInterval`, настроенный на каждые 30 миллисекунд, может быть задержан до одного раза в секунду или медленнее, когда вкладка не видна. В этом секундомере это влияет только на частоту обновления числа на экране; подлежащая вычислениям математика (текущая временная метка минус начальная временная метка, плюс накопленное время) не заботится о количестве пропущенных обновлений. Вернувшись к вкладке, следующее обновление экрана покажет точное значение прошедшего времени — ничего не теряется и ничего не прибавляется из-за замедления, только плавность отображения времени, когда вы смотрели на что-то другое.

Использование `performance.now()` вместо `Date.now()` — это правильный выбор для этой задачи, а не случайная деталь. `Date.now()` отражает системный часовой пояс, и часовые пояса могут прыгать — например, ноутбук, пробуждающийся после сна и синхронизирующийся с сервером NTP, ручное изменение времени или корректировка времени в переходный период могут заставить `Date.now()` прыгнуть вперёд или даже назад в середине сессии. `performance.now()` определяется как монотонный таймер: он всегда увеличивается с постоянной скоростью и не подвержен этим корректировкам, что в точности то, что нужно секундомеру, а обычный таймер на основе часового пояса не имеет.

Честная ограничение — это сохранение, и его нет. Эта реализация хранит `elapsed` и массив `laps` как обычные переменные JavaScript в памяти страницы — в исходном коде нет вызовов `localStorage` или собственной `Playground.store()` этого сайта, которую используют другие инструменты Toolio для сохранения данных при перезагрузке. Это означает, что при обновлении страницы, закрытии вкладки или переходе к другому инструменту, ваше текущее время и все записанные лапы мгновенно и навсегда удаляются. Нет функции "возобновить последнюю сессию", ничего не синхронизируется между устройствами, и ничего не нужно резервировать, потому что сначала ничего не записывается в хранилище. Если история лап действительно важна для вас — журнал тренировок, набор времён для презентации — запишите числа или сделайте скриншот до того, как уйти, потому что эта страница не запомнит их для вас.

Как пользоваться

  1. Нажмите "Старт" — кнопка сразу переименуется в "Пауза", и секундомер начинает увеличиваться в реальном времени, обновляясь каждые 30 миллисекунд.
  2. Нажмите "Лап" в любой момент, когда секундомер работает, чтобы зафиксировать текущее время; новая запись появляется вверху списка лап и показывает как разницу (время с момента предыдущей лапы), так и общее время.
  3. Нажмите ту же кнопку ещё раз, теперь с надписью "Пауза", чтобы остановить отображение — прошедшее время сохраняется внутри, ничего не теряется, а кнопка возвращается к надписи "Старт".
  4. Нажмите "Старт" ещё раз, чтобы возобновить счёт с того же момента, с которого вы остановились, а не с нуля.
  5. Нажмите "Сброс", чтобы обнулить отображение, очистить все записанные лапы и вернуть обе кнопки к их первоначальным надписям — это единственный способ начать новую сессию, потому что нет функции сохранения, чтобы защитить предыдущую.

Частые вопросы

Как на самом деле измеряет время этот секундомер?
Он читает `performance.now()` один раз, в момент нажатия на "Старт", и сохраняет это число. После этого значение на экране — это просто "время, уже зачисленное" плюс "текущее performance.now() минус сохранённая временная метка начала" — пересчитывается с нуля при каждом обновлении каждые 30 миллисекунд. Он никогда не просто добавляет фиксированное +30 миллисекунд к общему времени на каждом тике, что является способом, который делает многие домашние таймеры постепенно сбрасывать синхронизацию.
Что происходит с временем, если я переключусь на другую вкладку браузера, пока он работает?
Фоновые вкладки замедляются — браузер может задержать `setInterval` с интервалом в 30 миллисекунд до одного раза в секунду или медленнее, чтобы сэкономить процессор и батарею, поэтому число на экране может казаться замороженным или прыгающим, пока вы отсутствуете. Но поскольку этот секундомер всегда вычисляет прошедшее время как разницу временных меток, а не считает, сколько тиков было отправлено, возвращение к вкладке заставляет следующее обновление экрана показать точное значение прошедшего времени. Вы не теряете и не приобретаете время из-за замедления — только плавность отображения страдает, пока вы не смотрите.
Почему performance.now() вместо Date.now() — действительно ли это имеет значение?
Да. `Date.now()` отражает системный часовой пояс, который может прыгать вперёд или назад — например, сразу после того, как ноутбук просыпается из сна и синхронизируется с сервером NTP, или если системный час вручную изменён. `performance.now()` — это монотонный таймер, который всегда увеличивается с постоянной скоростью и не подвержен этим корректировкам, что в точности то свойство, которое нужно секундомеру, и эта реализация использует правильный.
Сохраняет ли он моё прошедшее время или историю лап где-нибудь?
Нет — и в отличие от некоторых других инструментов Toolio, он вообще не использует `localStorage` браузера для этой информации. Все, что вы видите, существует только в памяти страницы, пока эта конкретная вкладка открыта. Обновите страницу, закройте вкладку или перейдите к другому инструменту, и ваше прошедшее время и все лапы исчезнут навсегда; нет отмены и нет автосохранения, потому что ничего не записывается в хранилище с самого начала. Скопируйте числа или сделайте скриншот, если вам нужна запись, прежде чем уйти.
Есть ли ограничение на количество лап, и что означают два числа в каждой строке лап?
Ограничений нет — список просто растёт, и новая лапа фиксируется вверху. Каждая строка показывает два числа: разницу, в цвете акцента, которая является временем, прошедшим с момента предыдущей лапы; и общее время, в сером цвете, которое является общим временем с момента нажатия на "Старт". Это сочетание позволяет оценить отдельный сегмент — одну тренировочную интервал, одну часть выступления — без потери общей продолжительности.
Загружает ли этот инструмент мои данные?
Нет. Всё выполняется прямо в вашем браузере, поэтому ваши данные никогда не покидают устройство — после загрузки страницы он работает даже офлайн.