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

Improve import startup time #2073

Closed
Viicos opened this issue Feb 15, 2024 · 4 comments
Closed

Improve import startup time #2073

Viicos opened this issue Feb 15, 2024 · 4 comments
Labels
performance Too slow renderings

Comments

@Viicos
Copy link

Viicos commented Feb 15, 2024

On my machine, importing weasyprint takes more that half a second:

$ time python -c 'import weasyprint'

real	0m0.638s
user	0m0.494s
sys	0m0.101s

Which can get annoying e.g. when running a Django server in dev. with autoreload. Did a bit of profiling to see where it was coming from1:

image

And it seems to be spread across different modules.

I will propose a workaround in a follow up PR, although there isn't only one way to deal with this so open to alternatives

Footnotes

  1. python -X importtime -c 'import weasyprint' 2> import.log && tuna import.log

@grewn0uille grewn0uille added the performance Too slow renderings label Feb 15, 2024
liZe added a commit to Kozea/Flask-WeasyPrint that referenced this issue Feb 17, 2024
It gives an interesting boost performance that’s very useful when
auto-reloading is enabled.

Related to Kozea/WeasyPrint#2073.
@liZe
Copy link
Member

liZe commented Feb 17, 2024

Hi!

On my machine, importing weasyprint takes more that half a second:

Yes, it’s slow.

Which can get annoying e.g. when running a Django server in dev. with autoreload.

Hacking imports (as you did in #2074) is possible, but it requires extra workarounds for many use cases: typing, tests, lint, submodule imports, API discovery, IDEs, etc.

When import weasyprint is done, it’s generally to render documents, and the startup time is not that important. Web apps with a reloader are exceptions where this loading time can be painful.

Wouldn’t it be easier to lazy load WeasyPrint in your application? Or maybe include this in Django-WeasyPrint, where the lazy load is probably easier to implement than in WeasyPrint?

(That’s actually a great idea, here we go: Kozea/Flask-WeasyPrint@6604003 😄)

@Viicos
Copy link
Author

Viicos commented Feb 17, 2024

Hi,

lazy loading weasyprint in our Django project is definitely possible. You are right making use of PEP 562 (module level __getattr__) can be tricky. The added if TYPE_CHECKING block should solve typing/IDE issues but there might be some that I'm not aware of.

Imo the ideal solution would be to have this "fix" in weasyprint directly but I do understand you prefer to have it handled downstream (the implementation isn't that pretty indeed).

@liZe
Copy link
Member

liZe commented Feb 17, 2024

lazy loading weasyprint in our Django project is definitely possible.

That’s good news. Do you use Django-WeasyPrint?

You are right making use of PEP 562 (module level __getattr__) can be tricky. The added if TYPE_CHECKING block should solve typing/IDE issues but there might be some that I'm not aware of.

Yes, thanks for taking care of that, but I’m sure that other issues will appear if I merge this PR!

Imo the ideal solution would be to have this "fix" in weasyprint directly but I do understand you prefer to have it handled downstream (the implementation isn't that pretty indeed).

I agree, it’d be better, but unfortunately there’s no easy solution for that. For now, I’d prefer to have it in Django-WeasyPrint, Flask-WeasyPrint, and other web app libraries where it could be useful: the implementation is straightforward and much easier to maintain.

Even better, we could have this one day in Python. PEP-690 has been rejected, but who knows…

@Viicos
Copy link
Author

Viicos commented Feb 17, 2024

Do you use Django-WeasyPrint?

Just plain vanilla weasyprint but fortunately it's just a matter of moving the import in a function.

Even better, we could have this one day in Python. PEP-690 has been rejected, but who knows…

This PEP was interesting indeed, I'll have to check why it was rejeceted.

Thanks, closing the issue and related PR.

@Viicos Viicos closed this as completed Feb 17, 2024
@Viicos Viicos closed this as not planned Won't fix, can't repro, duplicate, stale Feb 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
performance Too slow renderings
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants