SVGMath overview

Explanation

SVGMath is a way to produce good looking math on the Web, without using the javascript-based approaches of MathJax,r KaTeX or Temml. It's an SVG-based approach to fast loading of beautiful math on the Web.

See the SVGMath demo page for SVGMath, MathJax and KaTeX examples, and the Temml chapter for examples and templates.

SVGMath is a proof-of-concept attempt at solving the following issues when displaying math on the Web:

  1. MathJax, KaTeX and Temml are javascript-based libraries that convert LaTeX (or MathML) to attractive mathematics (either HTML, SVG or MathML) for easy reading
  2. Being javascript based, it takes time for the javascript to load, and takes even more time to process and display the math. While developers of each of the libraries have put a lot of effort into making things as fast as possible, users are impatient when pages take a long time to load and will tend to abandon them. There's a search engine penalty for slow sites as well.
  3. Most sites already have a large volume of "javascript soup" (including libraries like JSNode, jQuery, etc, and/or advertising, social network widgets, and so on). All of this soup competes with each other as the page loads, slowing everything down.
  4. Both MathJax and KaTeX libraries produce a huge number of HTML elements (<span>s, mostly) that are necessary to display the math properly. Temml is better in this regard, because it only outputs MathML, so is less bloated. Such DOM creation and manipulation is a big reason why loading and processing take so long. Page analysis tools like Lighthouse complain bitterly about page load blocking and the large number of DOM elements on such pages.
  5. Both MathJax and KaTeX libraries provide MathML output for accessibility reasons (blind people can make use of MathML for exploring within math and copying portions, but this is normally hidden from sighted users). This adds to the large number of DOM elements created.
  6. MathJax can handle LaTeX tags, labels, refs and eqrefs, whereas KaTeX does not, and Temml's solution uses a depracated approach.

So SVGMath is an attempt to address some of the above items.

  1. There is no javascript used at all for equation processing on page load (except some sizing tweaks for narrow screens)
  2. We're embedding SVGs only, and doing it using "lazy loading" (so the browser only loads the SVGs as the user scrolls down to them).
  3. In the inline <svg> output version, the SVGs use <text> tags instead of <path>s for all numbers and variables. This makes each SVG considerably smaller, since we call the fonts once on page load (and don't draw a picture of each character, like in <path>s).
  4. SVGMath includes screen reading facilities (aria-labels) but not MathML by default, keeping the page smaller. (Try the demo page with a screen reader.)
  5. Equation tags (numbering) successfully appear if \label{...} is present in the equation, and links to those numbered equations also work.

How it's done

  1. The page is processed on the server (by PHP) so it's complete before it appears in the user's browser. It works somewhat similarly to a Wordpress plugin, where the LaTeX equations on the page are replaced by math.
  2. In the development phase for a page, all the \begin{equation} ... \end{equation}, $$... $$, $ ... $, etc are replaced with a call to MathJax-SVG, and each equation in SVG form is written to the server.
  3. Once the SVGs exist on the server, they are lazy-load added to the page using AJAX (or in the image case, actually lazy loaded). The SVGs are cached and don't need to be created again.
  4. For the demo, I created 2 versions:
    1. Inline SVG, using <text> tags and with fonts called (once) in the HTML <tag> tag, loaded using my own lazy loader
    2. SVGs using <path> tags this time called in <img> tags, and loaded using loading="lazy"
  5. Any equation tags are extracted and added as a <span> on the far right of the equation.
  6. Any tag links are kept track of by arrays and the \eqref are converted to links and point to the correct equation.
  7. Of course, the whole thing is fast to load, fast to process (there's no javascript) and phone-friendly

Accessibility

Rather than load accessibility elements for everyone, SVGMath includes enough information for a screen reader to produce spoken math, derived from MathJax's screen reader text ooutput.

Try the page using a screen reader to hear the result.

(If equation exploration and copying facilities are required, it makes more sense to use MathJax or KaTeX.)

Comparison Stats

Performance metrics for the 2 different versions of SVGMath are listed below for comparison with each other, and with MathJax , KaTeX and Temml. The stats given here are and average of what I saw in my environment in a few trials. There are many variables and your mileage will differ.

Lighthouse is the performance analysis tool within Chrome development tools. Total blocking time is how long we have to wait for the javascript to download and do its thing before anything else can happen - lowest is best, of course. The Speed index is a metric that compares a page's performance to the Web in general (a value between 0 and 3.4 s on a phone is regarded as "fast").

SVGMath and MathJax make use of lazy loading of the math, so that initial page load is as fast as possible. MathJax has a native lazy load option which I'm using here, while KaTeX and Temml do not.

The KaTeX lazy version uses my own implementation of pre-processing the math and saving it on the server, then loading it as the user scrolls down the page (which is similar to the SVGMath approach). This results in good page load speeds since there is no blocking time, albeit with a large initial DOM count.

The Temml lazy version has pre-processed math "above the fold", and as the user scrolls down, any math that's about to come into view is processed before the user sees it.

Cells with green background are the best, red is worst.

NOTE: For each of MathJax and KaTeX in the tables below, we are processing the math on the client side. For SVGMath, by design, and for KaTeX lazy, no client-side script is used for the math. In the Temml version, pre-processing is done for the visible math on page load, then on demand as the user scrolls.

(1) Inline <svg>s using <text> tags

This is the best version for performance. The resource use is low and the number of DOM elements is roughly 1/3 of those produced by MathJax or KaTeX, and similar to the Temml "lazy" version.

We're using <text> tags for numbers and variables, rather than <path>s (which is what MathJax uses in its SVG version.) We're also using a simple <span> element (not a whole SVG) for the very simple (one-character) math items (like "x") where it's overkill to use an antire SVG.

One downside of this technique is it's not so good for SEO (search engine optimisation) as the SVGs are embedded, not existing as a separate file, so they never appear as separate entities in search results. However, given that speed is one of Google's key metrics for search performance, it's a price worth paying.

SVGMath
<svg>
SVGMath
<img>
MathJax
HTML
MathJax
SVG
KaTeX KaTeX
lazy
Temml Temml
lazy
On initial load
DOM elements 419 484 97 97 97 2074 97 403
kB transferred 70 147 331 736 261 109 474 475
kB resources 156 345 1,400 2,500 805 231 609 618
Finished processing 0.174 s 0.020 s 0.859 s 0.783 s 0.538 s 0.204 0.619 s 0.294 s
Fully loaded and processed
(scrolled to bottom of page)
DOM elements 4,089 484 9,495 9,074 12,248 12,318 3,364 3,380
kB transferred 232 397 352 736 261 239 474 475
kB resources 503 1,100 1,400 2,500 805 629 609 618
Lighthouse performance score 100 100 83 87 68 100 82 100
Total blocking time 0 s 0 s 0.700 s 0.560 s 0.780 s 0 s 0.630 s 0 s
Speed index 1.0 s 1.0 s 1.1 s 1.7 s 2.8 s 1.2 s 1.9 s 1.1 s

(2) SVGs within <img> tags

The second column in the above table refers to the case where we embed the SVGs in an image tag (e.g. <img src="eqn.svg">). This approach gives us the lowest number of DOM elements (between 5 and 10% of the DOM elements produced by MathJax, KaTeX or Temml).

However, we've had to use <path>s for all elements in the math (numbers and variables as well), since any <style> tags in the main page that target the SVG are ignored when called from an <img> tag. So the resource load is greater than the embedded SVG case (by about twice).

A downside to using <img>s like this is that they aren't searchable on the page, whereas <svg> tags that use <text> are.

NOTE: I also tried out embedding the SVG in <object> tags. It proved to be an unsatisfactory user experience so I abandoned it.

Finally

The content for the SVGMath demo page was chosen because it has many equations, and label tags (equation numbering), and links to tags (which MathJax can handle, and KaTeX and Temml cannot yet, but my version does).

Which is best?

My aim was for a largish page that was: