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.