Спостереження за роботою JavaScript-таймерів в реальному часі

Візуалізація динамічного процесу на графіку — один із способів отримання нової/додаткової інформації. У публікації показана проста утиліта, за допомогою якої можна побачити роботу JavaScript-таймерів. З одного боку, JavaScript-таймери добре підходять для організації циклічного процесу. З іншого боку, вони, в загальному вигляді, наочно демонструють поведінку однопотокового JavaScript-багатозадачності, що, у ряді випадків, теж може бути корисним.

Зображення - JavaScript-таймери

Графік дозволяє:
  • Побачити роботу JavaScript-таймера в реальному часі.
  • Змоделювати різні умови навантаження.
  • Порівняти роботу різних браузерів.
  • Дає інформацію для роздумів (деякі результати виявилися цікавими).

Введення

По горизонтальній осі (X) вимірюється кількість пройдених циклів. По вертикальній осі (Y) вимірюється час в мілісекундах (мс). Початок — по кнопці «СТАРТ». Завершення — происходат автоматично, після візуального заповнення даних по осі X.

Вимірювані значення:
  • Червоний: проміжок часу від початку одного циклу до початку іншої (час повного циклу).
  • Білий: проміжок часу від закінчення одного циклу до початку іншої (час затримки).
  • Синій: час видеонагрузки. Видеонагрузкой є графічне відображення цього графіка.
  • Ціан: час псевдонагрузки. Псевдонагрузкой є просте циклічне повторення JavaScript-коду.
Працездатність перевірялася:
  • Windows: FF, OPERA, CR, IE.
  • Linux: FF, OPERA.
Код на GitHub.
Демо на GitHub (також працює з жорсткого диска).

Типи таймерів

setTimeout
setTimeout використовується для разових затримок виконання коду та для організації циклів. Цикл на основі setTimeout:
MyFunc = function () {

// прикладної код

setTimeout(function () {
MyFunc();
}, 100);
}

Тут все, начебто, очевидно: 100 — це затримка в мілісекундах (мс), через яку буде запущено наступний цикл завдання. Але, при організації циклу, інтуїтивно очікуєш, що код буде виконуватися саме з цим періодом. Насправді (видно на графіку), фактичний час циклу буде складатися з часу виконання коду плюс часу затримки. Тобто, чим складніше код, тим довше буде фактичний час циклу.

setInterval
setInterval використовується для виконання коду через певні проміжки часу. Цикл на основі setInterval:
MyTimer = function () {
setInterval(function () {
MyFunc(); // прикладної код
}, 100);
}

На графіку видно, що setInterval контролює час повного циклу. При зміні часу виконання коду, «інтелектуально» коригується час між викликами так, щоб час повного циклу залишалося стабільним. Якщо час виконання коду, перевищує заданий період, то таймер, вичерпавши можливості по зменшенню часу між викликами, починає викликатися з подовженим періодом.

requestAnimationFrame
requestAnimationFrame використовується для циклічної перемальовування екрану, яка синхронізована з циклами перемальовування браузера. Цикл на основі requestAnimationFrame:
MyFunc = function () {

// прикладної код

requestAnimationFrame(function () {
MyFunc();
});
}


setTimeout/setInterval + requestAnimationFrame
Теоретично, гібридні рішення мали поєднати можливості точного таймерування і синхронізації відтворення з циклом оновлення екрану. Цикл на основі setTimeout + requestAnimationFrame:
MyFunc = function () {

// прикладної код

setTimeout(function () {
requestAnimationFrame(function () {
MyFunc();
});
}, 100);
}

Цикл на основі setInterval + requestAnimationFrame:
MyTimer = function () {
setInterval(function () {
requestAnimationFrame(function () {
MyFunc(); // прикладної код
});
}, 100);
}

Функціонально код виконується, але, при цьому, спостерігається підвищена нестабільність періодів циклів.

Спостереження:
  • Для різних браузерів поведінка таймерів може відрізнятися. Особливо це проявляється при низьких значеннях часу затримки та/або при підвищених навантаженнях.
  • Якщо в браузері, з закладки з графіком перейти на іншу закладку (в тому ж вікні), то робота таймерів зупиняється, і знову відновлюється після активізації закладки з графіком. Якщо ж відкрити в браузері інше вікно, то робота таймерів не припиняється.


Видеонагрузка

Як видеонагрузки використовуються функції відтворення графіка на Canvas.

При виборі простої функції (APELSERG.CANVA.Paint), сітка графіка малюється один раз, при старті. І, далі, в процесі побудови графіка, виводиться тільки поточний результат (чотири точки) і лічильник циклів.

При виборі складної функції (APELSERG.CANVA.PaintComplex), всі результати зберігаються в масиви. Кожен раз при візуалізації, заново оновлюється сітка графіка і виводяться всі збережені результати з усіх масивів.

Псевдонагрузка

Псевдонагрузка — це простий цикл на JavaScript, у якому вибирається випадкове значення:
APELSERG.MAIN.VirtCalc = function () {
for (var n = 0; n < APELSERG.CONFIG.SET.TypeVirtCalc ; n++) {
var q = Math.round(Math.random() * 100);
}
}

Цикл винесено в окрему функцію, щоб простіше можна було підставити інший код. Можна вибрати кількість циклів від 0 до 1 000 000 000. Результат тестування під псевдонагрузкой, в різних браузерах, трохи здивував.

Масштабування і збереження графіка

Щоб змінити масштаб сітки, треба:
  1. Змінити масштаб відображення браузера (Ctrl-, Ctrl+).
  2. Перезавантажити сторінку.
  3. Вибрати розмір виведення значення (від 1 до 4 px).


Отриманий графік, можна зберегти як стандартне зображення:
  1. Права кнопка миші на графіку.
  2. Зберегти зображення як...


Корисні посилання

Основний цикл в Javascript
Про те, як працюють JavaScript таймери

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.