
# Производительность

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

## Чего ожидать

Ожидайте десятков или сотен миллисекунд на файл, а не микросекунд. Токенизатор кэширует скомпилированные правила и сканеры, грамматики загружаются по запросу (если в образце не встречается встроенный язык, тратить время на его декодирование не придётся), а большинство шаблонов грамматик обрабатывается нативным `preg_*` по ускоренному пути PCRE, проверенному на эквивалентность; остальные обрабатывает сопоставитель на чистом PHP (см. раздел [Архитектура](https://shikiphp.inline0.dev/ru/docs/architecture#the-scanner-and-its-pcre-fast-path)).

Это результаты одного запуска с прогретым кэшем из теста производительности репозитория (`bench/bench.php`, тема `github-dark`), выполненного на одной машине на файлах корпуса примерно от 55 до 105 строк:

| Грамматика | PHP 8.2 | PHP 8.4 |
| --- | --- | --- |
| JSON, YAML | 30–65 мс | 25–45 мс |
| CSS, HTML | 100–120 мс | 80–100 мс |
| Python, Rust, Go, Bash, Markdown | 190–220 мс | 125–175 мс |
| PHP | около 290 мс | около 170 мс |
| TypeScript, TSX | 490–510 мс | 310–370 мс |

Первый вызов языка в процессе также требует однократной загрузки и компиляции грамматики: в тех же запусках это занимало от 50–70 мс для JSON до чуть больше секунды для Markdown. Затраты растут с усложнением грамматики и увеличением размера входных данных; результаты зависят от оборудования, поэтому измерьте их у себя: клонируйте репозиторий, выполните `composer install`, а затем `composer bench`.

## Ограничения для защиты

Регулярный движок включает запоминание ошибок и защиту от ReDoS, поэтому патологический шаблон замедляет работу, а не вызывает зависание. Также можно ограничить обработку каждой строки с помощью [`tokenizeMaxLineLength`](https://shikiphp.inline0.dev/ru/docs/options#tokenizemaxlinelength): строки заданной длины и больше будут выводиться одним обычным токеном — это защита от вредоносных чрезмерно длинных строк.

## Кэширование в рабочей среде

Надёжный способ убрать подсветку из пути обработки запроса — **не** запускать её при каждом запросе. Подсветка одного и того же кода с одинаковыми параметрами всегда даёт один и тот же HTML, поэтому результат отлично кэшируется:

- Выполняйте подсветку во время сборки статических сайтов и документации.
- Кэшируйте отрисованный HTML (по ключу из кода и параметров) для фрагментов, предоставленных пользователями или сохранённых в базе данных, и используйте его повторно, пока исходный код не изменится.

В рамках одного процесса используйте повторно один экземпляр подсветчика (фасад `Shikiphp` сделает это за вас), чтобы кэши грамматик и тем использовались совместно при разных вызовах.
