Comments 23
Но, как только появился браузер, сервис стал тормозить: генерация одной формулы занимала секунды
Именно генерация формулы, а не запуск Puppeteer? А то как раз на это секунды требуются.
Сам недавно для сохранения в pdf поднял express сервер с мини-очередью — чтобы держать браузер запущенным, с одной вкладкой — убрал оверхед ~3.5 секунды. Бонусом получил кэширование и отсутствие параллельно запущенных нод
Решение с браузером с твоей конфигурацией имеет ограничение по пропускной способности одна вкладка и один браузер. Можно конечно поднять несколько нод с браузерами внутри, но это будет очень дорого по памяти. Плюсом идет оверхед по холодному запуску браузера, при поднятии новой ноды с браузером.
p.s. кстати если тебя интересует рендеринг в pdf, то рекомендую посмотреть в сторону wkhtmltopdf. Но пусть и старый, но работает сильно быстрее. У нас есть отдельное решение для этого, но это тема отдельного поста :)
Для меня ограничение в одну вкладку было необходимо. Для вашей же задачи, возможно, вполне подойдёт ограничение в N вкладок, которые смогут параллельно обрабатывать очередь, размер N будет зависеть только от конфигурации железа. Масштабировать можно будет и горизонтально — через балансировщик.
А насчёт wkhtml, mpdf, phantomjs — спасибо, но нет, если требуется что-то большее, чем "картинка + текст хоть как-нибудь", я лучше заверстаю нормально для современного браузера — со всеми его плюшками и любыми фронтенд-либами — и получу 1-в-1 то, что вижу при ctrl+p -> print to pdf
Да и мы сделали это :) Решение от Wikimedia использует внутри себя PhantomJs, что было слишком медленно для нас. Но некоторые решения там интересные, при желании можно посмотреть, вот репозиторий
Недостаёт картинок отрисовки формул «до» и «после». Что значит «сломалось выравнивание»? И не все знают, как выглядят артефакты при «сломе головки струйного принтера».
Резонно :)
Выравнивание ломалось примерно так:
Про «слом головки струйного принтера», увы, не удалось найти оригинальной иллюстрации, но основной смысл в том, что svg'ка разлеталась в разные стороны из-за коллизий названий symbols разных формул. И, естественно, чем больше формул на странице, тем вероятнее коллизии.
http://chart.apis.google.com/chart?cht=tx&chl=\displaystyle \int_{-\infty}^{\infty}e^{-x^{2}} \;dx={\pi}
Кстати, html с такими формулами «открывается вордом».
Генерация формул на стороне сервера в swg и png уже реализована тут http://i.upmath.me/. Там открытый исходный код и всё такое.
Автор этого есть на Хабре: parpalak.
Выглядит здорово, но я не нашел репозиторий, чтобы это можно было использовать у себя и накрутить что-то свое, типа кэширования, предпроцессинга и прочих штук.
Если проект действительно опенсоурсный, то было бы интересно как это работает там.
Или тут tex.s2cms.ru
Или тут written.ru
или тут written.ru/articles/technologies/site_building/latex_for_web
Действительно интересное решение.
Есть несколько моментов которые необходимо проверить и один который неприменим в Яндексе :)
Надо проверить:
- Надо проверить насколько это будет быстро, потому что если я правильно понял, то это решение напрямую обращается к TexLive, потом преобразует из DVI в SVG и так далее.
- Понять какое есть точки расширения, к примеру для добавления возможности добавить доступность формуле
Неприменимо для нас:
- Это поддержка inline формул. Да, это решение поддерживает такие формулы, но только для современных браузеров с поддержкой css переменных как минимум.
Да, обращается напрямую к TeX Live.
Про css-переменные, вы имеете в виду последний коммит? Он относится только к js-скрипту, который подменяет разметку формул в html-коде страниц через двойные доллары на сами картинки. Фича нужна только для небольшого масштабирования формул, чтобы размер шрифта на картинке соответствовал размеру шрифта на странице.
Серверная часть, которая генерирует svg- и png-картинки, такие как эта, работает без каких-либо css-переменных.
Всё так, но MathJax, в свою очередь, имеет еще и выравнивать формулы относительно baseline текста, что как никак кстати подходит для inline-формул. Если я правильно понял в Вашем решении выравнивание работает тоже через css переменные.
Плюс заметил артефакты в IE 11, что для нас очень важно.
Для выравнивания задается vertical-align. Переменные тут не нужны. Svg-картинки знают о положении базовой линии. Раньше я использовал встраивание картинок через object и передачу информации о базовой линии через postMessage. Потом переделал на fetch, потому что вставка через object стала тормозить в Хроме. Fetch не поддерживается в IE11, но старая реализация работает в IE11, для кроссбраузерности можно использовать ее: https://github.com/parpalak/i.upmath.me/commit/ec56935f904caffdcba11509c3353fc24881a2a6
Или пойти по истории вглубь, старые версии скрипта работают и на IE8.
Выше уже приводили, кстати, ссылку на описание того, как это всё работает: https://written.ru/articles/technologies/site_building/latex_for_web
Сталкивался с подобной задачей.
- Попробовал KaTeX. Синхронный и очень быстрый. Всё замечательно, но мало что умеет. Пришлось сразу отказаться. ЕМНИП оно только в HTML умеет. Но могу ошибаться, это было пару лет назад. Мне нужен был SVG
- Попробовал MathJax. Ужасное API, отсутствие поддержки es6 модулей (во всяком случае на тот момент). И вообще опыт преимущественно негативный был. Однако он умеет в HTML-инъекции (мне нужно было через
<ForeignObject/>
вставлять в формулы<input/>
-ы. А MathJax это умеет - Попробовал TexLive на стороне сервера в отдельном докер-контейнере. Это было тяжко. Там около 1.5 GiB одна только его сборка. Зато она просто всемогущая. И химические формулые разных видов, и разные математические расширения и чего там только нет. Всё кроме
<ForeignObject/>
-ов.
В итоге пришёл к гибридной схеме:
- Потребитель получает готовые
SVG
избавленные от неуникальных ID. Копирование в буфер обмена не требовалось. - В админке используется и TexLive (запрос к backend-у) и MathJax. MathJax для интерактивных вставок, а TexLive для всего остального (в особенности для хитрого LaTeX синтаксиса вроде химических формул).
- При сохранении документа всё принудительно конвертируется в SVG и сохраняется на диск. Сами LaTeX формулы, разумеется, не теряются.
- Для размера используется единица измерения
ex
. Это очень удобно когда формула должна выглядеть однородно с текстом в inline-режиме.
Сборка TexLive была вынесена в отдельный репозиторий, т.к. одна только сборка docker контейнера отнимала легко 40+ минут.
Судя по алгоритму очень похоже на то что предлагает aafin, возможно имеет смысл подумать о использовании решения i.upmath.me :) Ну за исключением динамики — тут видимо альтернатив для MathJax немного.
TeX в SVG: опенсорс-решение в помощь веб-разработчикам образовательных проектов