Тестирование производительности

Marked — это высокопроизводительная библиотека для преобразования Markdown в HTML на JavaScript. Производительность является одной из ключевых характеристик этой библиотеки, и правильное тестирование позволяет оценить скорость обработки больших объёмов текста и выявить узкие места.


Измерение базовой скорости рендеринга

Для оценки производительности сначала необходимо измерить скорость преобразования Markdown в HTML при использовании функции marked.parse() или её синонима marked():

import { marked } from 'marked';

const markdown = `
# Заголовок уровня 1
## Заголовок уровня 2
### Заголовок уровня 3
Список:
- Элемент 1
- Элемент 2
- Элемент 3
**Жирный текст**, *курсив*, \`код\`
`;

console.time('Markdown render');
const html = marked(markdown);
console.timeEnd('Markdown render');

Метод console.time() позволяет оценить время выполнения преобразования. Для больших текстов и документации такой подход позволяет выявить среднее время рендеринга и сравнивать разные конфигурации.


Тестирование с различными конфигурациями

Marked поддерживает ряд опций, которые влияют на скорость обработки и безопасность:

  • gfm — включает поддержку расширенного синтаксиса GitHub Flavored Markdown.
  • breaks — преобразует переносы строк в <br>.
  • sanitize / sanitizer — обезопасивание HTML-контента.
  • headerIds — генерация идентификаторов для заголовков.
  • mangle — защита email-адресов в тексте.

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

marked.setOptions({
  gfm: true,
  breaks: true,
  headerIds: false,
  mangle: false
});

console.time('Markdown render with options');
const htmlWithOptions = marked(markdown);
console.timeEnd('Markdown render with options');

Выключение генерации идентификаторов и манглирования email часто снижает нагрузку и ускоряет рендеринг больших файлов.


Тестирование больших документов

При работе с крупными Markdown-документами важно проверять производительность на реальных сценариях. Для этого создают искусственные большие тексты или используют реальные документации.

let largeMarkdown = '';
for (let i = 0; i < 1000; i++) {
  largeMarkdown += `## Раздел ${i}\nТекст с **жирным** и *курсивом*.\n- Пункт 1\n- Пункт 2\n`;
}

console.time('Large document render');
marked(largeMarkdown);
console.timeEnd('Large document render');

Такой тест позволяет измерить время рендеринга тысяч заголовков и сотен списков, выявляя потенциал оптимизации.


Профилирование и оптимизация

Для глубокого анализа производительности рекомендуется использовать профайлер Node.js:

node --prof benchmark.js

Далее результаты можно анализировать через node --prof-process, что позволяет определить, какие функции библиотеки выполняются медленнее всего.

Частые рекомендации для оптимизации:

  • Кэширование рендеринга: если часть Markdown не изменяется, хранение HTML-копий ускоряет повторный рендеринг.
  • Минимизация использования опций sanitize и headerIds при рендеринге больших документов.
  • Пакетная обработка: разбивка текста на блоки и параллельная генерация HTML при серверной обработке.

Сравнение с альтернативами

Marked показывает высокую производительность по сравнению с другими библиотеками, такими как markdown-it или showdown, благодаря оптимизированному синтаксическому анализатору и отсутствию лишних проходов по тексту. Тесты показывают, что обработка больших файлов часто происходит в несколько раз быстрее, если отключить ненужные функции.


Автоматизация тестирования

Для регулярного мониторинга производительности удобно использовать фреймворки для тестирования, такие как benchmark.js:

import Benchmark from 'benchmark';
import { marked } from 'marked';

const suite = new Benchmark.Suite;

suite
  .add('Marked render', function() {
    marked(largeMarkdown);
  })
  .on('cycle', function(event) {
    console.log(String(event.target));
  })
  .on('complete', function() {
    console.log('Fastest is ' + this.filter('fastest').map('name'));
  })
  .run({ async: true });

Такой подход позволяет систематически отслеживать изменения в скорости рендеринга при обновлениях библиотеки или при модификации опций.


Ключевые моменты производительности

  • Простые Markdown-документы рендерятся практически мгновенно.
  • Большие документы с тысячами заголовков и списков требуют оптимизации и возможно отключение некоторых функций.
  • Настройки библиотеки напрямую влияют на скорость: headerIds, mangle, sanitize.
  • Автоматическое тестирование с использованием benchmark.js или Node.js профайлера позволяет отслеживать регрессии в производительности.

Тщательное тестирование и понимание влияния каждой опции Marked позволяет использовать библиотеку максимально эффективно при любых объёмах Markdown-контента.