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

Concurrent rendering of nunjucks tags within a post #4923

Open
2 tasks done
ppwwyyxx opened this issue Mar 28, 2022 · 2 comments · May be fixed by #4926
Open
2 tasks done

Concurrent rendering of nunjucks tags within a post #4923

ppwwyyxx opened this issue Mar 28, 2022 · 2 comments · May be fixed by #4926

Comments

@ppwwyyxx
Copy link
Contributor

ppwwyyxx commented Mar 28, 2022

Check List

Please check followings before submitting a new feature request.

  • I have already read Docs page
  • I have already searched existing issues

Feature Request

Currently, if we use async rendering in custom tag plugins, rendering of tags can run concurrently between posts. However, tags within the same post are still rendered sequentially.

This is because when rendering a post, hexo makes a single render call to nunjucks to render the entire post. Inside nunjucks, it renders all the tags sequentially.

I have a custom tag plugin that needs to make expensive async calls, so it could benefit a lot from within-post async rendering of tags.

Others

I have made a draft implementation of this feature at ppwwyyxx@17565f7 . Instead of making one render call per-post, it finds each nunjucks tag in the post and call render on each of them.

This diff has improved my whole-site generation speed by 10x.

I would like to hear:

  • Whether the feature makes sense to add
  • If the above is yes, whether my implementation is in the right direction. If so I could start a PR.
@SukkaW
Copy link
Member

SukkaW commented Mar 28, 2022

The feature sounds awesome! You can draft a PR first as a PoC. And we will see if any changes/adoptions are required.

@ppwwyyxx ppwwyyxx linked a pull request Mar 30, 2022 that will close this issue
2 tasks
@ppwwyyxx
Copy link
Contributor Author

ppwwyyxx commented Mar 30, 2022

UPDATE: I managed to fix the issue.


I ran into a test failure that I'm not sure how to address.
The problem is that for an input like this:

<p><code>{{ 1 + 1 }}</code> {{ 1 + 1 }}</p>

When the entire input is given, nunjucks is smart enough to know that the first {{ 1+1 }} should not be rendered.
However, if we (i) find all tags and then (ii) render each tag independently using nunjucks, nunjucks lost the context and will therefore render both tags in the input.

  1. It seems difficult to implement this correctly without touching nunjucks. One potential approach:
  • When registering tags to nunjucks, register a cheap function that replaces tag content with some placeholder such as <hexoTag>a unique id string<hexoTag>. Save the mapping from "a unique id string" to the actual (fn, args) that should be called to render the tag.

  • Still use nunjucks to render the entire post in one render() call. The cheap function that we register will be called here.

  • After rendering with nunjucks, find all <hexoTag> and asynchronously call the corresponding (fn, args) to render the real content in the custom tag.

    This seems too complicated that I probably won't be able to work on it any time soon.

    Please comment if you have other ideas.

  1. Alternatively, would it make sense to add the new feature (independent & async rendering of tags) as a per-post option? This way users can enable it for posts that don't have the abovementioned problem.

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

Successfully merging a pull request may close this issue.

2 participants