Home > Software design >  How to make MathJax faster?
How to make MathJax faster?

Time:05-07

I was working on a website that contains a lot of mathematical expressions. I use MathJax with React (using 'react-mathjax-preview') but I noticed that rendering math equations is slow and can be noticed while refreshing the page. I compared with websites that are using MathJax like Mathematics Stack Exchange and I found that the equations are rendered faster (even with pages that contain a big amount of math expression). So why my math is rendered slower? And how to make it fast like Mathematics Stack Exchange?

Note: I tried to use KaTex with react which was faster than MathJax, But there were some problems with the positioning of fractions and roots and the text style. So I returned to MathJax as it also provides more latex functions and is used more than KaTex.

Note: The problem seems to be worse in cases where math expressions are contained in tables, as they are written in separated <MathJax /> components.

For example, this piece of code is rendered slowly, however it contains only 9 math expressions. (some of the pages I work on contain more than 50 separated math expressions (even while using environments like 'align' environment).

<div>
    <table className="table-style-a2">
        <thead>
            <tr>
                <th>Radical in the integral</th>
                <th>Trigonometric substitution</th>
                <th>Hyperbolic substitution</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td><MathJax math={String.raw`$\sqrt{a^2-x^2}$`} /></td>
                <td><MathJax math={String.raw`$x = a \sin (\theta)$`} /></td>
                <td><MathJax math={String.raw`$x = a \tanh (\phi)$`} /></td>
            </tr>
            <tr>
                <td><MathJax math={String.raw`$\sqrt{a^2 x^2}$`} /></td>
                <td><MathJax math={String.raw`$x = a \tan (\theta)$`} /></td>
                <td><MathJax math={String.raw`$x = a \sinh (\phi)$`} /></td>
            </tr>
            <tr>
                <td><MathJax math={String.raw`$\sqrt{x^2-a^2}$`} /></td>
                <td><MathJax math={String.raw`$x = a \sec (\theta)$`} /></td>
                <td><MathJax math={String.raw`$x = a \cosh (\phi)$`} /></td>
            </tr>
        </tbody>
    </table>
</div>

\\ Just an example

Thanks in advance.

CodePudding user response:

I don't know how things are implemented in react-mathjax-preview but in my own library, better-react-mathjax, the solution to your problem is to group larger portions of the DOM containing multiple expressions inside the same MathJax component. What happens otherwise is (at least in my library) that we queue several typesetting operations synchronously in Mathjax even though it could do all the typesetting in one go. This is normally not a problem but with a lot of math it could be. Your example in my library is not enough for this to show however:

https://codesandbox.io/s/user-example-14-so72149128-6nw8r5

Anyways, by instead doing this:

<MathJax>
    <table className="table-style-a2">
        <thead>
            <tr>
                <th>Radical in the integral</th>
                <th>Trigonometric substitution</th>
                <th>Hyperbolic substitution</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>{"$\\sqrt{a^2-x^2}$"}</td>
                <td>{"$x = a \\sin (\\theta)$"}</td>
                <td>{"$x = a \\tanh (\\phi)$"}</td>
            </tr>
            <tr>
                <td>{"$sqrt{a^2 x^2}$"}</td>
                <td>{"$x = a \\tan (\\theta)$"}</td>
                <td>{"$x = a \\sinh (\\phi)$"}</td>
            </tr>
        </tbody>
    </table>
</MathJax

You can add quite a lot of more math without running into problems:

https://codesandbox.io/s/user-example-13-so72149128-obxokb

If you STILL have problems, there are other things you could do as well:

  • Divide the page into smaller portion, perhaps expandable areas which are not typeset until they are expanded. From a UX perspective having too much info on the same page is not optimal either.
  • If you REALLY need to show ALL the math at once, try to turn off the initial automatic typesetting and then simply add multiple larger-portion MathJax components. Since these are enqueued in order, the first one will be typeset first and so you can make sure that the first part of the page is typeset early while the later parts (which are not in view in the first X seconds after landing on the page) are typeset later.
  • Related