Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Load MathJax JS library only when page contains equations #2

Open
WebDrake opened this issue Jul 26, 2012 · 22 comments
Open

Load MathJax JS library only when page contains equations #2

WebDrake opened this issue Jul 26, 2012 · 22 comments

Comments

@WebDrake
Copy link

The MathJax JS library is quite large, so ideally it would be loaded only on pages that actually contain equations -- else it's just wasted bandwidth. Currently the Simple-MathJax plugin loads the library globally.

I appreciate there's a tradeoff here with the simplicity of the plugin, so no worries if this is a "won't fix" issue.

@scoskey
Copy link
Contributor

scoskey commented Jul 26, 2012

I'll definitely look into it. The best (for me) would be if mathjax
itself would take care of the problem. Perhaps they have a script or
mode to only load the meat of the plugin if they detect something to
do.

Otherwise it's a bit tricky. There are several ways to include an
equation, and I don't want to try to write the detection code. It
would mostly duplicate a part of their code, and any small difference
in logic would lead to the wrong behavior.

Thanks for the suggestion!

Sam

On Thu, Jul 26, 2012 at 2:43 AM, Joseph Rushton Wakeling
reply@reply.github.com
wrote:

The MathJax JS library is quite large, so ideally it would be loaded only on pages that actually contain equations -- else it's just wasted bandwidth. Currently the Simple-MathJax plugin loads the library globally.

I appreciate there's a tradeoff here with the simplicity of the plugin, so no worries if this is a "won't fix" issue.


Reply to this email directly or view it on GitHub:
#2

@pkra
Copy link
Member

pkra commented Jul 26, 2012

@scoskey there's a couple of things we can do. The default is to use a combined configuration that's rather large. Also, we could add an opt-in or opt-out button to the wp editor (like the markdown plugin does).

But it's a common misconception that MathJax is heavy on a page without mathematics. The thing is -- MathJax's load depends heavily on the math it finds on the page. The fonts it downloads, the additional script it downloads, the rendering it does, it only does what it needs to when going through the page.

While it is true that the combined configuration file that the plugin defaults to is relatively large, it was actually designed to improve loading! That is, an author knows the content and what readers are going to need, so combining everything into one file to be loaded upfront is much more efficient than MathJax making calls only as it finds out what it needs while processing the actual page.

Reversely, @WebDrake can make your own configuration and make it extremely light -- and the plugin already allows for that. For more information, see @dvpc 's advice over on SE.

@WebDrake
Copy link
Author

@scoskey -- I ask because some of the other plugins (e.g. LaTeX for WordPress) only load the MathJax JS if there's an equation on the page. I understand if it may be over-complicated to implement or maintain, or just a sub-optimal solution -- one reason I don't use LaTeX for WP is that it produces some minor but irritating alterations to the appearance of non-mathematical text.

@pkra -- I recognize that MathJax loads a minimum of material -- it does amount to about 50kB on a page with no mathematics at all. Still, that's enough to make a reasonable difference to page load/display times. Compare a few metrics generated for my website:

##Page without maths
MathJax enabled: http://www.webpagetest.org/result/120726_E0_WE8/1/details/
MathJax disabled: http://www.webpagetest.org/result/120726_RM_WJ6/1/details/

##Page with maths:
MathJax enabled: http://www.webpagetest.org/result/120726_KW_WNP/1/details/
MathJax disabled: http://www.webpagetest.org/result/120726_N9_WKV/1/details/

Even with such a small footprint, MathJax doubles the load time of the page with no maths.

Now, to be fair, you might say that anyone complaining about 2s vs. 1s is greedy (obviously it's a small page without many graphics), but what bothers me more isn't overall load time but that the loading of MathJax JS gets in the way of other site elements and so affects the rendering time for the page. By contrast I was struck by how on the page with mathematical elements, MathJax delayed the loading of the expensive parts such as fonts until after the rest of the page had rendered.

That makes me curious about whether it might be possible to implement some improvements in how/when different parts of the JS get loaded, and also whether it might be possible on the WP plugin side to implement some cacheing that parses a post at save time and determines whether it's necessary to load MathJax for that page or not.

Anyway, thanks for all your suggestions. :-)

@pkra
Copy link
Member

pkra commented Jul 26, 2012

@WebDrake no worries. I totally get that you want that 1s.

But... looking at those tests. The first one: you'll notice that it's precisely loading the combined configuration file that delays everything. If you use a smaller file or do everything as inline configuration, then you'll save that .6s. You can also tweak MathJax to wait for the page to load so that the user has something to look at -- and if no mathjax is needed, will actually be ok. (side comment: that page is so tiny! no fair ;) )

For the second and regarding the fonts: MathJax doesn't know ahead of time, which fonts it needs. This may sound odd at first, but the thing is that the webfonts are not just one single font file (that would be rather huge), but many smaller ones.

So MathJax processes the page, sees what characters are actually used and loads the fonts that it needs. Note also that users with installed STIX fonts won't have to download any fonts -- MathJax just uses those (unless you override that of course). Another thing: your users' browser will cache MathJax locally, across all CDN-using sites, so performance is really more of an issue upon visiting the first time around.

Regarding your final comment. Yes, the plugin could scan for the delimiters and load MathJax depending on them. And that what Philip Lord's plugin does, I think. But Sam's is called "simple mathjax", so I don't know if he wants to do that...

@scoskey
Copy link
Contributor

scoskey commented Jul 26, 2012

Thanks for all the advice Peter.

Again, I don't think I will attempt to write code that detects whether
there is an equation on the page. I don't think it's trivial, since
the user can make equations with (arbitrary) delimeters and with

<script>s. But we can put the control into the hands of the user by allowing them the option to "Disable mathjax" on each post and page. This is an easy and reasonable feature. Sam On Thu, Jul 26, 2012 at 12:27 PM, pkra reply@reply.github.com wrote: > @WebDrake no worries. I totally get that you want that 1s. > > But... looking at those tests. The first one: you'll notice that it's precisely loading the combined configuration file that delays everything. If you use a smaller file or do everything as inline configuration, then you'll save that .6s. You can also tweak MathJax do wait for the page to load so that the user has something to look at -- and if no mathjax is needed, will actually be ok. (side comment: that page is so tiny! no fair ;) ) > > For the second and regarding the fonts: MathJax doesn't know ahead of time, which fonts it needs. This may sound odd at first, but the thing is that the webfonts are not just one single font file (that would be rather huge), but many smaller ones. > > So MathJax processes the page, sees what characters are actually used and loads the fonts that it needs. Note also that users with installed STIX fonts won't have to download any fonts -- MathJax just uses those (unless you override that of course). Another thing: your users' browser will cache MathJax locally, across all CDN-using sites, so performance is really more of an issue upon visiting the first time around. > > Regarding your final comment. Yes, the plugin could scan for the delimiters and load MathJax depending on them. And that what Philip Lord's plugin does, I think. But Sam's is called "simple mathjax", so I don't know if he wants to do that... > > --- > > Reply to this email directly or view it on GitHub: > https://github.com//issues/2#issuecomment-7286098

@pkra
Copy link
Member

pkra commented Jul 26, 2012

Yep. Make it both ways maybe (globally-active+deactivation and globally-inactive+activation)?

@WebDrake
Copy link
Author

Agree, a global on/off by default with individual post and page enable/disable would be very nice.

@pkra I'll see what I can tweak in the configuration that might bring the size down -- if I get something that works, I'll pass it on as something to add to the plugin's FAQ.

Thanks very much to both of you for the helpful remarks. :-)

@WebDrake
Copy link
Author

So, after a bit of reading and tweaking, here's what I have.

The custom MathJax CDN is now set to http://cdn.mathjax.org/mathjax/latest/MathJax.js i.e. not loading any pre-prepared config file.

Then, the custom config is as follows:

MathJax.Hub.Config({
    jax: ["input/TeX","output/HTML-CSS"],
    extensions: ["tex2jax.js"],
    tex2jax: {
        inlineMath: [ ["\\(","\\)"] ],
        displayMath: [ ["\\[","\\]"] ]
    }
});

The result is a much faster load time for pages without maths, and comparable (sometimes faster) speeds when maths is present. Compare to the previous benchmarks:

Page without maths: http://www.webpagetest.org/result/120730_CS_NFF/1/details/
Page with maths: http://www.webpagetest.org/result/120730_C5_P06/1/details/

It seems to benefit from the fact of loading a lot less, and what does load loads in parallel rather than all in one go.

@WebDrake
Copy link
Author

Actually, I think the with-maths benchmark would be much faster than the earlier one if not that the "native" CSS and JS were slow to load.

@pkra
Copy link
Member

pkra commented Jul 31, 2012

Glad it worked as expected! Regarding your second comment: MathJax needs to wait for your site's CSS to arrive (rendering depends on your CSS), so not much can be done from MJ's side.

@WebDrake
Copy link
Author

Yes, of course -- wasn't suggesting a fault of MathJax there, just noticing that on the MathJax side the improvement was even stronger than that test gives credit for.

@pkra
Copy link
Member

pkra commented Jul 31, 2012

No worries, that's how I understood your comment. I added mine just in case somebody stumbles upon this thread and wonders :)

@pkra
Copy link
Member

pkra commented Apr 5, 2017

If there's interest, I'm happy to help with a "proper" solution, i.e., running a full pre-processor to detect math on the page and then load MathJax with a -full configuration for faster renedering.

@pkra
Copy link
Member

pkra commented Apr 26, 2020

A more recent request for this: https://wordpress.org/support/topic/load-simple-mathjax-in-just-some-pages/.

@talgalili
Copy link

+1 To this request. Thanks.

@pkra
Copy link
Member

pkra commented Sep 28, 2020

Thanks for following up here as well, @talgalili.

@rafisics
Copy link

If there's interest, I'm happy to help with a "proper" solution, i.e., running a full pre-processor to detect math on the page and then load MathJax with a -full configuration for faster rendering.

I really want to have this feature such that MathJax will be loaded only to the mathematical posts. What's the effective way to do it? (The issue is recently mentioned on WordPress SE too.)

@talgalili
Copy link

BTW, I added the following code using wordpress snippets:

// this depends on having the WP QuickLaTeX plugin turned on
function add_latexpage($content)
{

  	// We try to match \[ bla \] and \( bla \) or \begin{equation} bla \end{equation} - and they MUST preceed with either space or > and < (of some HTML tag)
  	// because of the way php works, the string below actually translates to:
    // ~(\s|\>)(((\\(\(|\[|begin\{equation\}))(.|\s)+?(\\(\)|\]|end\{equation\}))))(\s|\<)~
  	// notice how any double \ is turned to one. i.e.: \\ == \
  	// so in order to get the regex I want, I have way too many backslashes
  	//	this was debugged using: https://regex101.com/ AND https://sandbox.onlinephpfunctions.com/
  	$pattern = '~(\s|\>)(((\\\\(\\(|\\[|begin\\{equation\\}))(.|\s)+?(\\\\(\\)|\\]|end\\{equation\\}))))(\s|\<)~';
  
  	if(preg_match($pattern, $content) > 0) {
	  $content = $content . '[mathjax]'; // '[latexpage]';
	}	
  
    return $content;
}
// The timing of this must be BEFORE the other content modification code...
add_filter('the_content','add_latexpage', 0.1);

In case this might be helpful to others.

@gtawebb
Copy link

gtawebb commented Mar 9, 2022

+1 for this feature.

@pkra
Copy link
Member

pkra commented Mar 9, 2022

@christianp are you by any chance interested in implementing this? (I'm too far away from WP plugins these days.)

@christianp
Copy link
Collaborator

Not any time soon, sorry.

@pkra
Copy link
Member

pkra commented Mar 10, 2022

Not any time soon, sorry.

No worries at all -- thanks for the quick response!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants