Производительные узкие места

Axe-core — это библиотека для автоматизированного тестирования доступности веб-приложений, реализованная на JavaScript. Она позволяет выявлять проблемы доступности (accessibility issues) в DOM, поддерживает различные правила проверки, а также предоставляет детальные отчёты с указанием элементов и нарушений стандартов WCAG.

Для интеграции Axe-core в проект используется npm-пакет axe-core. Основной объект библиотеки предоставляет метод run, который выполняет анализ текущего DOM и возвращает структурированный результат с информацией о найденных нарушениях.

import axe from 'axe-core';

axe.run(document, {}, (err, results) => {
  if (err) throw err;
  console.log(results.violations);
});

Метод run принимает три аргумента: корневой элемент DOM, объект опций и callback. Объект опций позволяет ограничить набор правил или настроить исключения. Например, можно проверить только определённую область страницы:

axe.run(document.querySelector('#main-content'), {}, (err, results) => {
  console.log(results.violations);
});

Структура результатов проверки

Результаты анализа содержат несколько ключевых полей:

  • violations — массив найденных нарушений стандартов WCAG, каждая запись включает описание, уровень серьёзности (impact) и список элементов DOM, на которых обнаружено нарушение.
  • passes — массив проверок, которые прошли успешно.
  • incomplete — проверки, которые не удалось завершить из-за неопределённого контекста.
  • inapplicable — правила, которые не применимы к текущему DOM.

Каждое нарушение имеет структуру:

{
  "id": "color-contrast",
  "impact": "serious",
  "description": "Элемент имеет низкую контрастность текста",
  "nodes": [
    {
      "html": "<span style='color:#ccc;'>Текст</span>",
      "target": ["#header span"],
      "failureSummary": "Контраст текста недостаточен для читабельности"
    }
  ]
}

Настройка правил и кастомизация

Axe-core поддерживает отключение отдельных правил и создание собственных конфигураций. Опции задаются через объект options:

const options = {
  runOnly: {
    type: 'tag',
    values: ['wcag2a', 'wcag2aa']
  },
  rules: {
    'color-contrast': { enabled: false }
  }
};

axe.run(document, options, (err, results) => {
  console.log(results.violations);
});

runOnly позволяет ограничить проверку только конкретными тегами правил WCAG, что полезно при частичном аудите или ускорении анализа. Поле rules предоставляет возможность отключать или модифицировать отдельные правила. Например, при тестировании специфического компонента можно временно отключить проверку контрастности.

Интеграция в тестовые фреймворки

Axe-core широко используется вместе с Jest, Cypress и другими инструментами для написания автоматических тестов доступности. Пример интеграции с Jest:

import { configureAxe, toHaveNoViolations } from 'jest-axe';
import { render } from '@testing-library/react';
import MyComponent from './MyComponent';

expect.extend(toHaveNoViolations);

test('Компонент соответствует стандартам доступности', async () => {
  const { container } = render(<MyComponent />);
  const axe = configureAxe();
  const results = await axe(container);
  expect(results).toHaveNoViolations();
});

Подход позволяет встроить проверку доступности в CI/CD-процесс, обеспечивая постоянный контроль за соответствием стандартам WCAG.

Производительность и узкие места

Проверка доступности может быть ресурсоёмкой на больших страницах. Основные узкие места:

  1. Объём DOM — Axe-core анализирует каждый элемент, поэтому страницы с тысячами узлов требуют значительно больше времени.
  2. Сложные CSS-правила — вычисление контрастности и видимости элементов может замедлять выполнение.
  3. Асинхронный контент — динамически загружаемые элементы требуют повторного анализа или использования MutationObserver.
  4. Избыточные правила — включение всех доступных правил сразу может создавать нагрузку без значимого эффекта.

Для оптимизации производительности используют следующие стратегии:

  • Ограничение области проверки с помощью селекторов (context).
  • Выбор только необходимых правил через runOnly.
  • Разделение проверки на блоки страниц или компонентов.
  • Кэширование результатов для статического контента.
  • Использование серверной версии Axe-core (axe-core/axe.min.js) для снижения накладных расходов при тестах.

Работа с динамическим контентом

Для SPA и динамических страниц актуально использование axe-core вместе с наблюдателями изменений:

const observer = new MutationObserver((mutationsList) => {
  axe.run(document, {}, (err, results) => {
    console.log(results.violations);
  });
});

observer.observe(document.body, { childList: true, subtree: true });

Это позволяет автоматически отслеживать новые элементы и выполнять проверку доступности без повторного полного анализа страницы.

Расширение правил и кастомные проверки

Axe-core поддерживает создание кастомных правил для специфических требований проекта. Структура правила включает:

  • id — уникальный идентификатор.
  • selector — CSS-селектор элементов для проверки.
  • any, all, none — условия для проверки атрибутов или контента.
  • enabled — включение/отключение.
  • tags — категории WCAG.

Пример кастомного правила:

axe.configure({
  rules: [
    {
      id: 'custom-button-label',
      selector: 'button',
      enabled: true,
      any: ['aria-label', 'text'],
      tags: ['wcag2a', 'wcag111']
    }
  ]
});

Подобные правила позволяют реализовать внутренние стандарты доступности, которые не покрыты WCAG, и интегрировать их в автоматические тесты.