Hacker News new | ask | show | jobs
by joppy 1823 days ago
The "server-side rendering" aspect of KaTeX is (and always has been, as far as I'm aware) front-and-centre on their landing page [1]. It allows you to input LaTeX and output HTML ready for inclusion server-side - the only thing this HTML needs to support it is the KaTeX CSS. This is very easy to do if your web server or static site generator is running on Node, and only a bit more difficult if it's running on something else (and therefore needs to shell out to Node). So if the author wants a good solution to server-side rendering, just look a little more at KaTeX.

On the flip side, I have reverted some of my server-side rendering of mathematics back to client-side rendering, because of considerations like webpage size. On mathematics-heavy pages, I found that pages that would otherwise be about 50KB in size got inflated up to about 1MB after server-side rendering all of the mathematics. After compression the difference was more like 70K, but this difference is the entire size of the (compressed) KaTeX library. I think it is completely reasonable to only transmit LaTeX markup over the wire, and have a client-side library take care of the presentation (as we do for HTML, SVG, ...).

I've also investigated MathML, but cross-browser support is terrible and has been for years. You also still get the size explosion problem, because LaTeX markup is just so much more compact than whatever MathML soup is equivalent.

[1]: https://katex.org/

2 comments

MathJax can also (apparently) render MathML on Chrome.

Maybe the answer is:

Write maths notation on your site with MathML. (You'd probably want to preprocess LaTeX notation into MathML some way, because MathML isn't fun to write by hand in the same way that septic tanks aren't fun to unblock by hand.) This will be displayed natively in Safari/Firefox, and be accessible to screen readers (apparently.. I don't use one so don't know what it's like in practice).

Serve MathJax to Chrome users so they can see your maths.

?

Well I hope that you took efforts to avoid the other nasty side effect of client side rendering at least: page content jumping all over the place when the page reloads and the scrollbar not initializing at the right location (so cross page anchors are useless).

I personally solved that problem by stuffing the equation into a separate vue component and putting the katex compilation into the render function. Indeed, a dedicated equation HTML tag supporting latex (with what packages though?) would be nice. Getting the equation numbering to work nicely in an automatic fashion was a bit annoying though. I appreciate your comment on the page size, since I was considering moving to server side rendering via nuxt and hadn't made this consideration.

I've not used Vue, but how does this solve the problem? In most of my own sites, whatever preprocessor (eg markdown -> html) I use is instructed to replace mathematics with something like <span class="math">z = \frac{x}{y}</span>, then after the page has loaded a small loop runs KaTeX on all eligible spans. This results in some small amount of jumping, but I've found anchors to still work quite well.
Vue is an SPA framework, so it solves the problem by "rendering all the html" as actual preprocessing and then serving it to the browser which visually renders it, as opposed to the usual document.onLoad() approach where the base page gets loaded and then the javascript actually postprocesses this iteratively updating the DOM which triggers re-rendering events. I am not savvy to the precise details of vue and browser lifecycle events, but I think effectively it builds a shadow DOM and then triggers a single rendering event to avoid the jumping around. But yeah, a single rendering vs multiple renderings.

Getting the client javascript to render the entire page has a variety of problems, hence my desire to server side render (during a build step) what is essentially static content. If the page size bloats up too much though I might need to reconsider the approach...

I guess web components (https://developer.mozilla.org/en-US/docs/Web/Web_Components) could allow me to combine these approaches. It is already quite close to the vue programming model.