Отладка в различных браузерах

Поведение timeago.js может различаться в зависимости от браузера из-за различий в движках JavaScript, реализации таймеров и поддержке стандартов. Знание типичных браузерных отличий сокращает время отладки.


Chrome

Наиболее удобная среда для отладки timeago.js. Chrome DevTools предоставляет:

  • Performance — запись активности таймеров (Timer Fired).
  • Memory — Heap snapshot для выявления утечек HTMLTimeElement.
  • Coverage — процент исполненного кода timeago.js.

Особенности:

// Chrome корректно парсит ISO 8601 строки
new Date('2025-06-01T12:00:00').getTime(); // Парсится как локальное время
new Date('2025-06-01T12:00:00Z').getTime(); // UTC — корректно

Chrome более строго следует стандарту ECMA-262 при парсинге дат.


Firefox

Firefox обрабатывает некоторые форматы дат иначе:

// Firefox корректен со стандартными форматами
new Date('2025-06-01');               // OK
new Date('June 1, 2025');             // OK в FF
new Date('01.06.2025');               // NaN в Firefox!

Особенность таймеров: Firefox может быть точнее при соблюдении интервалов setInterval, что влияет на частоту обновлений.

Отладка в Firefox:

  1. DevTools → Performance → Record.
  2. Искать “Timer” в стеке вызовов.
  3. В Memory: Take Snapshot → Compare с предыдущим.

Safari

Safari имеет наиболее строгий парсер дат:

// Safari
new Date('2025-06-01T12:00:00');     // Может вернуть Invalid Date!
new Date('2025-06-01T12:00:00Z');    // OK
new Date('2025-06-01');              // Invalid Date в старых версиях Safari

Основная проблема Safari: строки дат без явного часового пояса и с дефисами в формате YYYY-MM-DD воспринимаются некорректно в Safari < 14.

Нормализация для Safari:

function safariSafeDate(str) {
  // Safari не принимает строки без Z
  if (typeof str === 'string' && str.includes('T') && !str.includes('Z') && !str.includes('+')) {
    return new Date(str + 'Z');
  }
  // Safari не принимает YYYY-MM-DD без времени
  if (typeof str === 'string' && /^\d{4}-\d{2}-\d{2}$/.test(str)) {
    return new Date(str + 'T00:00:00Z');
  }
  return new Date(str);
}

Edge (Chromium)

Edge на основе Chromium ведёт себя аналогично Chrome. Специфических проблем с timeago.js нет.


iOS Safari (WebKit на мобильных)

Самая проблемная среда:

// iOS Safari 14 и ниже
new Date('2025-6-1'); // Invalid Date — однозначные месяц/день без ведущего нуля
new Date('2025-06-01T12:00:00'); // Invalid Date без Z!

Обязательная нормализация для iOS:

function parseForIOS(dateStr) {
  if (typeof dateStr !== 'string') return new Date(dateStr);

  // Заменить пробелы на T, добавить Z если нет timezone
  let normalized = dateStr.trim().replace(' ', 'T');
  if (!normalized.includes('Z') && !normalized.includes('+') && normalized.includes('T')) {
    normalized += 'Z';
  }
  return new Date(normalized);
}

Тестирование в разных браузерах: инструменты

Инструмент Назначение
BrowserStack Реальные браузеры, включая iOS Safari
Playwright Chrome, Firefox, WebKit (Safari engine) через Node.js
Cypress Electron (Chromium) — не Safari
kangax/compat Таблица поддержки стандартов

Playwright для кросс-браузерного тестирования

// tests/cross-browser.spec.ts
import { test, expect, Browser } from '@playwright/test';

const BROWSERS = ['chromium', 'firefox', 'webkit'];

for (const browserName of BROWSERS) {
  test(`[${browserName}] timeago отображает корректное время`, async ({ playwright }) => {
    const browser = await playwright[browserName].launch();
    const page    = await browser.newPage();

    await page.goto('http://localhost:3000');

    const timeEl = page.locator('time').first();
    await expect(timeEl).not.toBeEmpty();

    const text = await timeEl.textContent();
    expect(text).toMatch(/назад|только что/);

    await browser.close();
  });
}

Симуляция Safari-специфичного поведения в Jest

// Тестировать нормализатор дат, имитируя поведение Safari
describe('safariSafeDate', () => {
  it('обрабатывает строку без Z (Safari bug)', () => {
    const result = safariSafeDate('2025-06-01T12:00:00');
    expect(isNaN(result.getTime())).toBe(false);
  });

  it('обрабатывает строку без времени (Safari bug)', () => {
    const result = safariSafeDate('2025-06-01');
    expect(isNaN(result.getTime())).toBe(false);
  });
});

Диагностика в DevTools

Chrome/Edge:

F12 → Application → Local Storage — проверить кешированные значения
F12 → Console → new Date('ваша строка') — проверить парсинг

Firefox:

F12 → Performance → Profiler → Start Recording

Safari:

Develop → Web Inspector → Timelines → JavaScript & Events

Единый тест совместимости

// Запустить в консоли любого браузера
function browserCompat() {
  const tests = [
    ['ISO with Z',          new Date('2025-06-01T12:00:00Z')],
    ['ISO without Z',       new Date('2025-06-01T12:00:00')],
    ['Date only',           new Date('2025-06-01')],
    ['Timestamp',           new Date(1748779200000)],
  ];

  tests.forEach(([label, d]) => {
    console.log(label + ':', isNaN(d.getTime()) ? 'INVALID' : 'OK → ' + d.toISOString());
  });
}

browserCompat();