Making a transition from XeLatex to LuaLatex and I'm struggling with some odd font and loading issues.

My starting point for this question is this answer by https://tex.stackexchange.com/a/234785/15886 by @ulrike-fischer - 5 years ago. 5 years later and using a current version of TexLive and LuaHBTeX, Version 1.12.0 (TeX Live 2020/W32TeX) (format=lualatex 2020.7.28) on Windows 10

I am getting quite slow compilation speeds versus XeLatex

Like Ulrike I find that supposedly switching off the "feature" of fontspec to search for .fontspec files massively speeds compilation by a factor of 3 (for example from 23 seconds to 8 seconds on my current document)

I start with Ulrike's MWE (below) extended to add some font testing routines.

Lines 4--7 of the MWE according to Ulricke do nothing more than prevent an unnecessary search for .fontspec files. This should make no difference to the output of the MWE anyway, because the fonts in the libertine package used here do not seem to have .fontspec files anyway.

Toggling lines 4-7 on/off does indeed massively speed compilation (not demonstrable with this short MWE so clearly not just to do with initial font loading). However the fonts are actually changed, for reasons I don't understand.

The last few lines of the MWE output are for example - without Ulrike's magic lines

enter image description here

and with Ulrike's lines (which supposedly just switch off .fontspec search

enter image description here

So my questions are:

a) Why does preventing the system-killing search for .fontspec change the rendering, particularly when libertine does not use this anyway b) 5 years after the earlier question, what should we be doing in LuaLatex in terms of font loading. If I want to use libertine and Biolinium for example should I be loading them from a package (supposedly LuaLatex "compliant") or directly, with fontspec at all (?), and how should I be dealing with this slowing - which is clearly something to do with fonts, perhaps only on Windows?

MWE Follows:

 % \ExplSyntaxOn
 % \cs_set:Nn \__fontspec_load_external_fontoptions:Nn
 %  {}
 % \ExplSyntaxOff

\newcommand{\FontCmd}[3]{\PBS\verb!\#1{!\textit{text}\verb!}!  \> %
                         \verb!{\#2 !\textit{text}\verb!}! \> %
\textit{Command} & \textit{Declaration} & \textit{Effect} \\
\verb!\textrm{!\textit{text}\verb!}!                    & %
        \verb!{\rmfamily !\textit{text}\verb!}!               & %
        \textrm{Roman family} \\
\verb!\textsf{!\textit{text}\verb!}!                    & %
        \verb!{\sffamily !\textit{text}\verb!}!               & %
        \textsf{Sans serif family} \\
\verb!\texttt{!\textit{text}\verb!}!                    & %
        \verb!{\ttfamily !\textit{text}\verb!}!               & %
        \texttt{Typewriter family} \\
\verb!\textmd{!\textit{text}\verb!}!                    & %
        \verb!{\mdseries !\textit{text}\verb!}!               & %
        \textmd{Medium series} \\
\verb!\textbf{!\textit{text}\verb!}!                    & %
        \verb!{\bfseries !\textit{text}\verb!}!               & %
        \textbf{Bold series} \\
\verb!\textup{!\textit{text}\verb!}!                    & %
        \verb!{\upshape !\textit{text}\verb!}!               & %
        \textup{Upright shape} \\
\verb!\textit{!\textit{text}\verb!}!                    & %
        \verb!{\itshape !\textit{text}\verb!}!               & %
        \textit{Italic shape} \\
\verb!\textsl{!\textit{text}\verb!}!                    & %
        \verb!{\slshape !\textit{text}\verb!}!               & %
        \textsl{Slanted shape} \\
\verb!\textsc{!\textit{text}\verb!}!                    & %
        \verb!{\scshape !\textit{text}\verb!}!               & %
        \textsc{Small Caps shape} \\
\verb!\emph{!\textit{text}\verb!}!                      & %
        \verb!{\em !\textit{text}\verb!}!               & %
        \emph{Emphasized} \\
\verb!\textnormal{!\textit{text}\verb!}!                & %
        \verb!{\normalfont !\textit{text}\verb!}!       & %
        \textnormal{Document font} \\
\verb!\underline{!\textit{text}\verb!}!                 & %
                                                        & %

\verb!\footnotesizezzz!          \= \kill%sets the tab
\verb!\tiny!                  \>  \tiny{tiny} \\
\verb!\scriptsize!            \>  \scriptsize{scriptsize} \\
\verb!\footnotesize!          \>  \footnotesize{footnotesize} \\
\verb!\small!                 \>  \small{small} \\
\verb!\normalsize!            \>  \normalsize{normalsize} \\
\verb!\large!                 \>  \large{large} \\
\verb!\Large!                 \>  \Large{Large} \\
\verb!\LARGE!                 \>  \LARGE{LARGE} \\
\verb!\huge!                  \>  \huge{huge} \\
\verb!\Huge!                  \>  \Huge{Huge}

\textit{Environment}  &  \textit{Declaration}  \\
\verb!\begin{center}!      & \verb!\centering!  \\
\verb!\begin{flushleft}!  & \verb!\raggedright! \\
\verb!\begin{flushright}! & \verb!\raggedleft!  \\

\textit{Name} & \textit{Source} & \textit{Example} & \textit{Usage} \\
hyphen  & \verb!-!   & X-ray          & In words. \\
en-dash & \verb!--!  & 1--5           & Between numbers. \\
em-dash & \verb!---! & Yes---or no?    & Punctuation.




\textbf{x} & \textbf{y} \\\midrule

\verb|{\Huge\libertineGlyph{uni211A}}| \hfill {\Huge\libertineGlyph{uni211A}} \par\medskip
\verb|{\Huge\libertineGlyph{uni211A}}| \hfill {\Huge\libertineGlyph{uni211A}} \par\medskip
\verb|{\Huge\textbf{\libertineGlyph{uni211A}}}| \hfill{\Huge\textbf{\libertineGlyph{uni211A}}} \par\medskip
\verb|{\Huge\textit{\libertineGlyph{uni211A}}}| \hfill {\Huge\textit{\libertineGlyph{uni211A}}} \par\medskip

\verb!\footnotesizezzz!          \= \kill
\verb!\tiny!                  \>  {\tiny tiny} \\
\verb!\scriptsize!            \>  {\scriptsize scriptsize} \\
\verb!\footnotesize!          \>  {\footnotesize footnotesize} \\
\verb!\small!                 \>  {\small small} \\
\verb!\normalsize!            \>  {\normalsize normalsize} \\
\verb!\large!                 \>  {\large large} \\
\verb!\Large!                 \>  {\Large Large} \\
\verb!\LARGE!                 \>  {\LARGE LARGE } \\
\verb!\huge!                  \>  {\huge huge} \\
\verb!\Huge!                  \>  {\Huge Huge}\\

\par{\Huge\textit{textit text test}}
\par{\sffamily\bfseries\Huge Test Text}

  • libertine calls fontspec in the background. The [nofontspec] option reverts to Type1, by the looks of it. Is that a factor for the question? There's a pdfmap file involved. In any case, I get Libertine R italic for the serif, and Biolinum R bold for the sans on my system (Miktek, Windows). I'll try the switch. (FYI: 3 seconds xelatex, 8 seconds lualatex) – Cicada Aug 1 '20 at 6:33
  • The question may resolve into: (1) is fontspec_load_external_fontoptions how fontspec automatically finds bold, italic etc font filenames (expected answer: yes); and (2) does libertine load fontspec if fontspec is already loaded (expected answer: no). Don't have time to research this tonight. Apologies. – Cicada Aug 1 '20 at 6:45

(This is more of a comment than an answer, but it was too long for that...)


\cs_set:Nn \__fontspec_load_external_fontoptions:Nn

should no longer be used for modern fontspec versions since fontspec added an official interface for this: The IgnoreFontspecFile option. Basically any font loaded with this option will not trigger a search for a fontspec file. When using the libertine package and not loading the fonts directly, you can pass this option using libertines defaultfeatures option:


This still shows the issue you observed though. This is a fontspec bug but the fix will probably be merged soon.

I guess that this won't fix your issue either because you mentioned that the delay does not appear during font loading but later in the document. In that case it's probably not caused by searching the fontspec file at all and the speedup after this change appeared as a sideeffect of using less fonts because of the bug. Of course it's hard to say without seeing an example file which shows the slowdown.

  • A little followup from me (the OP). Clearly two issues here a) A known bug making it hazardous to use the IgnoreFontspecfile option. Until corrected, and now that the option is formalised it would seem appropriate to tell users not to use that option until fixed b) The slowing issue itself: Strangely it sped up my end (same files being compiled). I wonder whether it might be an issue with the inbuilt Windows Defender (which does check fonts in addition to executable files). Perhaps anyone experiencing slowing should try to turn defender off as a test. – Aubrey Blumsohn Jan 2 at 12:59

I don't know why but moving the \usepackage{libertine} line before the ExplSyntax lines seems to avoid the problem.

  • But if you do that, loading isn't sped up (which was the point of adding the lines in the first place): presumably because the macro we are defining to do nothing with these lines has already done its work in \usepackage{libertine}. – moewe Aug 1 '20 at 13:02
  • @moewe -- this is not strictly true. There is something more complex here. What is definitely true is that the code from Ulrike (The [nofontspec] option) definitely dramatically speeds slow-compiling LuLatex files as Ulrike found. It is also the case that this is not benign (in changes the fonts preventing bolds, italics and perhaps other things). What is NOT true is that the speeding is at the font loading stage. I have not produces a short MWE that is slow loading simply by loading fonts. Something may be happening afterwards in a long document that is prevented by the [nofontspec]. – Aubrey Blumsohn Aug 1 '20 at 16:12
  • @AubreyBlumsohn Mhhh, if I issue\cs_set:Nn \__fontspec_load_external_fontoptions:Nn {\undefinedcommandthatwillthrowanerror} instead of \cs_set:Nn \__fontspec_load_external_fontoptions:Nn {} after loading the libertine package, I do not get an error about the obviously undefined control sequence. That strongly suggests that the command that is being undefined is not used after loading the package and hence redefining it does not make any difference. Indeed issuing said redefinition before \usepackage{libertine} causes an error, suggesting the command is indeed used. – moewe Aug 1 '20 at 18:13
  • @AubreyBlumsohn What is probably true, however, is that you can reproduce the same slow-down by simply loading the fonts directly with fontspec instead of letting the package do that.(If used with a Unicode engine, the package libertine loads the fonts via fontspec, it does that very carefully and thoroughly and defines addition commands, but at its heart is the fontspec call). – moewe Aug 1 '20 at 18:16
  • @AubreyBlumsohn @moewe Font-loading in xelatex is proportional to the number of glyphs in the font (or filesize): On a Latin-text-only file, Noto Serif = 5-6 seconds (2793 glyphs); Noto Sans Adlam = <0.5 second (96 glyphs) and PDF produced. For lualatex, loading Adlam, unintentionally I had Latin text in the file and got this: ! error: (file C:/WINDOWS/Fonts/notosansadlam-regular_0.ttf) (type 2): there are no glyphs in the subset! ==> Fatal error occurred, no output PDF file produced! From which I infer the lua side is proceeding glyph-by-glyph. Adlam text with Noto Serif font, same error. – Cicada Aug 2 '20 at 4:12

I’m not sure why this problem would be reappearing five years after Ulrike Fischer reported that the bug in file search was fixed. This might be a regression.

I’ve noticed (in TeX Live 2020) that LuaLaTeX sometimes takes an excessive amount of time and memory to load large fonts, unless I specify Renderer=HarfBuzz.

In theory, fontspec should not need to search for as many filenames if you specify UprightFont=, BoldFont=, ItalicFont=, BoldItalicFont=, and Extension=, or search at all if you also specify Path=.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.