-
Notifications
You must be signed in to change notification settings - Fork 50
Improve PDF performance #4425
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
base: develop
Are you sure you want to change the base?
Improve PDF performance #4425
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -48,10 +48,17 @@ def generate_pdf( | |
| :param pages: at least on page to render as PDF document | ||
| :return: Redirection to PDF document | ||
| """ | ||
| # Build a lightweight queryset with the (large) translation content deferred, so that the | ||
| # cache key computation and the existence check below do not load the page contents. The | ||
| # full content is only fetched further down if the PDF actually has to be rendered. | ||
| pages = pages.prefetch_related(None) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This makes |
||
| hash_pages = pages.prefetch_public_translations_without_content() | ||
|
|
||
| # first all necessary data for hashing are collected, starting at region slug | ||
| # region last_updated field taking into account, to keep track of maybe edited region icons | ||
| pdf_key_list = [region.slug, region.last_updated] | ||
| for page in pages: | ||
| excluded_page_ids = [] | ||
| for page in hash_pages: | ||
| # add translation id and last_updated to hash key list if they exist | ||
| page_translation = page.get_public_translation(language_slug) | ||
| if page_translation and not page.archived: | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Non-blocking, pre-existing: |
||
|
|
@@ -60,7 +67,9 @@ def generate_pdf( | |
| pdf_key_list.append(page_translation.last_updated) | ||
| else: | ||
| # if the page has no translation for this language | ||
| pages = pages.exclude(id=page.id) | ||
| excluded_page_ids.append(page.id) | ||
| if excluded_page_ids: | ||
| pages = pages.exclude(id__in=excluded_page_ids) | ||
| # finally combine all list entries to a single hash key | ||
| pdf_key_string = "_".join(map(str, pdf_key_list)) | ||
| # compute the hash value based on the hash key | ||
|
|
@@ -94,9 +103,12 @@ def generate_pdf( | |
| max_len = 192 - len(ext) | ||
| name = f"{settings.BRANDING_TITLE} - {language.translated_name} - {title}" | ||
| filename = f"{pdf_hash}/{truncate_bytewise(name, max_len)}{ext}" | ||
| # Only generate new pdf if not already exists | ||
| # Only generate new pdf if not already exists. The existence check is performed before the | ||
| # (expensive) page content is loaded and rendered, so that repeated requests for an already | ||
| # generated PDF stay cheap. | ||
| if not pdf_storage.exists(filename): | ||
| # Convert queryset to annotated list which can be rendered better | ||
| # Cache miss: load the full page content and render the PDF document | ||
| pages = pages.prefetch_public_translations() | ||
| annotated_pages = Page.get_annotated_list_qs(pages) | ||
| context = { | ||
| "right_to_left": language.text_direction == text_directions.RIGHT_TO_LEFT, | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer to use a different attribute name to avoid confusion. Something like
prefetched_public_translations_without_contentmaybe? I won't die on that hill, though.