Профилирование

Marked — это высокопроизводительная библиотека для парсинга Markdown в JavaScript. Она позволяет преобразовывать текст в формате Markdown в HTML, сохраняя семантику и структуру документа. Библиотека поддерживает расширенные возможности Markdown, включая GitHub Flavored Markdown (GFM), таблицы, списки, ссылки, изображения и встроенный HTML.

import { marked } from 'marked';

const markdown = `
# Заголовок первого уровня
Это пример **жирного текста** и *курсива*.
`;

const html = marked(markdown);
console.log(html);

Конфигурация и параметры

Marked предоставляет гибкую систему конфигурации через объект options. Основные параметры:

  • gfm — включает расширения GitHub Flavored Markdown.
  • breaks — преобразует переносы строк в <br>.
  • smartLists — улучшает обработку списков.
  • sanitize — предотвращает XSS, очищая HTML.
  • headerIds — добавляет id к заголовкам.

Пример настройки:

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

Лексический и синтаксический разбор

Marked разделяет процесс на два этапа:

  1. Лексический анализ (Lexer) Lexer разбивает Markdown на токены: заголовки, списки, параграфы, блоки кода.
const tokens = marked.lexer(markdown);
console.log(tokens);
  1. Синтаксический анализ (Parser) Parser преобразует токены в HTML.
const htmlFromTokens = marked.parser(tokens);
console.log(htmlFromTokens);

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

Кастомизация рендеринга

Marked использует объект Renderer, который определяет, как каждый элемент Markdown преобразуется в HTML. Это дает возможность полностью контролировать вывод.

const renderer = new marked.Renderer();

renderer.heading = (text, level) => {
  return `<h${level} class="custom-header">${text}</h${level}>`;
};

renderer.link = (href, title, text) => {
  return `<a href="${href}" title="${title || ''}" target="_blank">${text}</a>`;
};

const customHtml = marked(markdown, { renderer });
console.log(customHtml);

Интеграция с безопасностью

Для предотвращения внедрения вредоносного HTML важно использовать sanitize или сторонние библиотеки для очистки. Например:

import DOMPurify from 'dompurify';

const unsafeHtml = marked(markdown);
const safeHtml = DOMPurify.sanitize(unsafeHtml);

Работа с потоками и асинхронная обработка

Marked поддерживает асинхронную обработку через async/await для интеграции с системами, где Markdown может содержать внешние ресурсы:

const htmlAsync = await marked.parse(markdown);

Это особенно полезно при рендеринге документов на сервере или при генерации статических сайтов.

Расширение возможностей через плагины

Marked позволяет расширять стандартные возможности:

  • Custom Tokenizer — определяет новые типы токенов.
  • Inline Lexer — контролирует обработку встроенных элементов, таких как ссылки или эмодзи.
  • Hooks — позволяют выполнять действия перед рендерингом или после него.

Пример кастомного токенизатора:

const tokenizer = {
  emoji(src) {
    const match = /^:([a-z_]+):/.exec(src);
    if (match) {
      return {
        type: 'emoji',
        raw: match[0],
        text: match[1]
      };
    }
  }
};

marked.use({ tokenizer });

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

Marked ориентирован на высокую скорость. Для анализа производительности можно измерять время выполнения рендеринга и лексического анализа:

console.time('lexing');
const tokens = marked.lexer(largeMarkdownText);
console.timeEnd('lexing');

console.time('parsing');
const html = marked.parser(tokens);
console.timeEnd('parsing');

Использование таких измерений помогает выявлять узкие места при обработке больших документов.

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

При работе с объемными Markdown-файлами следует:

  • Использовать предварительную токенизацию для повторного рендеринга отдельных блоков.
  • Минимизировать количество операций в кастомных рендерах.
  • Применять асинхронный рендеринг для предотвращения блокировки основного потока.

Интеграция с другими инструментами

Marked легко интегрируется с:

  • Static Site Generators (SSG) — Next.js, Gatsby.
  • Frontend-фреймворки — React, Vue, Svelte через dangerouslySetInnerHTML или v-html.
  • Markdown редакторы — встроенный рендеринг в live preview.
import { marked } from 'marked';
import React from 'react';

function MarkdownPreview({ content }) {
  return <div dangerouslySetInnerHTML={{ __html: marked(content) }} />;
}

Вывод

Marked сочетает высокую скорость, гибкость и расширяемость. Его архитектура с Lexer, Parser и Renderer позволяет создавать как простые конвертеры Markdown, так и сложные системы обработки текста. Профилирование и оптимизация рендеринга помогают поддерживать производительность при больших объемах данных.