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

Latency issues for large style sheets: Caching style sheets in php/dompdf for successive calls in production env? #3374

Open
gidzr opened this issue Jan 9, 2024 · 3 comments
Labels

Comments

@gidzr
Copy link

gidzr commented Jan 9, 2024

Hi Brian

Quick one: I've noticed when adding style sheets (like bootstrap) to the pdfing process, dompdf goes from a millisecond to create a pdf to a few seconds. Once I've added all my style sheets, it takes around 7 seconds per pdf, which is quite a bit.

Is there some way to cache or load the style sheets in through the composer / vendor / dompdf library? or is there a cache setting that once in production, I can lock down the styles so they are just loaded once and for each successive pdf, it doesn't take 7 seconds to pdf?

Cheers!

@bsweeney
Copy link
Member

Dompdf doesn't provide any type of functionality to support this. It's also a challenging question. There are actually two parts to the problem:

  1. downloading/parsing the stylesheet
  2. applying the stylesheet to the document

While it may be possible to support something for the first part, there's no getting around the second. It's likely the second part that's eating up most of the rendering time. Still, if you wanted to try you would do it something like the following:

$dompdf_styles = new Dompdf();
$dompdf_styles->loadHtml($empty_doc); // only has stylesheet references
$dompdf_styles->render();
$css = $dompdf_styles->getCss();
$dompdf = new Dompdf();
$dompdf->loadHtml($content_doc); // no stylesheets, only content
$dompdf->setCss($css);
$dompdf->render();

I have not tested that code and I'm not sure it will work (and expect it would not).


If the content you're rendering is fairly static (e.g., a "frame" around some content) then you might consider PDF templating or merging. Not something Dompdf supports but you could use it in conjunction with another library.

@gidzr
Copy link
Author

gidzr commented Jan 10, 2024

ok.. reading your algorithm, I have a couple of questions:

  1. Is there a getCSS and setCSS method for dompdf. I've found this: https://github.com/dompdf/dompdf/blob/ae691fbbcb0204d29d6809f2c2ae6646e770961c/tests/DompdfTest.php. I'll play around with your code to see what it does and if I can get something along those lines to work.

  2. I'm not sure if your code creates a css object that applied to the dompdf instance, OR if it creates a persistent global dompdf instance that is appended to later or both? Is it possible to append to an existing rendered instance

Is this what you're indicating?

Possible approach 1 - applying rendered styles (have I understood this re scoping?)
GLOBAL SCOPE onload
$dompdf_styles = new Dompdf();
$dompdf_styles->loadHtml($empty_doc); // only has stylesheet references
$dompdf_styles->render();

// in function
$css = $dompdf_styles->getCss();
$dompdf = new Dompdf();
$dompdf->loadHtml($content_doc); // no stylesheets, only content
$dompdf->setCss($css);
$dompdf->render();

Possible approach 2 - modular appending
GLOBAL SCOPE onload
$global_dompdf = new Dompdf();
$global_dompdf->loadHtml();
$global_dompdf->render();

// in function
$dompdf = $global_dompdf->loadHtml($content_inner); //<-- from client
$dompdf->loadHtml('');
$dompdf->render();

@bsweeney
Copy link
Member

getCss and setCss are in the main Dompdf class.

Your first approach is what I had in mind. The second approach won't work because data from each document will pollute impact the previous one. So, you just want the styles generated by an initial, global instance.

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

No branches or pull requests

2 participants