Для работы с библиотекой Marked в JavaScript необходимо установить пакет через npm:
npm install marked
Импортировать библиотеку можно стандартным образом:
import { marked } from 'marked';
Marked предоставляет возможность конвертации текста в формате
Markdown в HTML. Основной метод для этого — marked.parse().
Для больших документов использование этого метода напрямую может стать
узким местом, поэтому важно понимать, как настроить парсер для
оптимальной производительности.
Большие документы лучше обрабатывать потоково, а не целиком в памяти. Marked поддерживает использование лексеров и парсеров отдельно:
const lexer = new marked.Lexer();
const tokens = lexer.lex(largeMarkdownString); // разбиение на токены
Затем можно передавать токены в парсер:
const parser = new marked.Parser();
const html = parser.parse(tokens);
Такой подход позволяет:
Marked поддерживает объект конфигурации с множеством опций. Ключевые параметры для оптимизации:
gfm (GitHub Flavored Markdown) — если
документ не использует расширенный синтаксис, его отключение уменьшает
нагрузку.breaks — контролирует разрыв строк. В
больших документах отключение может ускорить обработку.sanitize — проверка HTML может быть
затратной; при необходимости лучше использовать внешние библиотеки для
безопасного рендеринга.mangle и headerIds —
автоматическая генерация ID заголовков и кодировка email-адресов. Для
больших документов можно отключить, если это не критично.Пример настройки:
marked.setOptions({
gfm: true,
breaks: false,
headerIds: false,
mangle: false
});
Создание собственного рендерера позволяет оптимизировать обработку определённых элементов. Например, если в документе много изображений и ссылок, можно уменьшить нагрузку на генерацию HTML:
const renderer = {
image(href, title, text) {
return `<img src="${href}" alt="${text}" loading="lazy">`; // отложенная загрузка
},
link(href, title, text) {
return `<a href="${href}" rel="noopener noreferrer">${text}</a>`; // безопасные ссылки
}
};
marked.use({ renderer });
Это уменьшает время рендеринга и снижает потенциальные проблемы с безопасностью при больших объёмах контента.
Для очень больших документов стоит вынести процесс парсинга в отдельный поток с помощью Web Workers:
// worker.js
importScripts('https://cdn.jsdelivr.net/npm/marked/marked.min.js');
onmess age = (event) => {
const html = marked.parse(event.data);
postMessage(html);
};
Главный поток:
const worker = new Worker('worker.js');
worker.onmess age = (e) => {
document.getElementById('output').innerHTML = e.data;
};
worker.postMessage(largeMarkdownString);
Такой подход:
Для документов, которые часто обновляются частично, имеет смысл кэшировать:
Токены отдельных секций:
Промежуточный HTML:
Пример кэширования:
const tokenCache = new Map();
function renderSection(markdown, id) {
if (tokenCache.has(id)) {
return marked.Parser.parse(tokenCache.get(id));
}
const tokens = marked.Lexer.lex(markdown);
tokenCache.set(id, tokens);
return marked.Parser.parse(tokens);
}
Большие Markdown-файлы могут занимать сотни мегабайт в памяти. Рекомендации:
tokens,
renderer) после рендеринга.walkTokens для фильтрации и трансформацийМетод walkTokens позволяет обрабатывать токены на лету,
что часто быстрее, чем модификация HTML после генерации:
marked.use({
walkTokens(token) {
if (token.type === 'heading' && token.depth === 1) {
token.text = token.text.toUpperCase(); // кастомизация заголовков
}
}
});
Это эффективно для:
Для больших Markdown-документов эффективна комбинация:
walkTokens.Такой подход минимизирует нагрузку на память, ускоряет генерацию HTML и делает обработку больших документов управляемой и масштабируемой.