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

Enhancement of fragment_cache - enhance_cache #3897

SukkaW opened this issue Dec 1, 2019 · 1 comment

Enhancement of fragment_cache - enhance_cache #3897

SukkaW opened this issue Dec 1, 2019 · 1 comment


Copy link

@SukkaW SukkaW commented Dec 1, 2019

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

Aggressive Cache for Partial

Fragment cache was introduced in #637. It stores the function's output (usually partial()'s) to a big Object and later read value from it.

Before we could completely understand hexo's rendering & generation process, fragment cache was probably the best way to solve the issue like #2164 (binding locals again and again for thousands of times) and #2991 (renders everything and only do comparison when writing files into disk).

Let's take a look at #1769 again. Before the theme utilizing fragment_cache(), although files are loaded less than 5 seconds, but rendering process has lasted for 4 min and no files has changed and written to drive. This issue is definitely the result of #2164 — rendering everything but nothing generated. But after just enable fragment_cache for sidebar partial the rendering process drops from 4 min to 6.41s.

Users could get significant performance boost if theme developer could utilize fragment_cache() correctly, but currently most of the theme developers don't know how to use fragment_cache() correctly: #3071 (fragment_cache can be enabled directly in partial()) & #3738 (fragment cache shouldn't be enabled in a partial when its locals could change).

Recently I have noticed ppoffice/hexo-theme-icarus@958138f : every partial will be cached in fragment cache with cacheId as md5 of locals. Then the output of a partial can be found in the fragment cache if its locals has not changed since the first time call. In this way every partial could enable fragment cache without theme developers enables it manually.

And there is a problem: if a partial has its locals changed frequently, fragment cache will consume memory very, very quickly every time this partial is called. So if we are going to introduce this feature to hexo, we have to first refactoring fragment cache from a big Object to LFU.

I suggest if enhance_cache is enabled, all partial() should be cached by fragment_cache unless { cache:false } is set.

The current problem is how we handle { cache: true } and { cache: [theme developer specific cache id] }. In some cases, theme developer want to cache a partial even locals has been changed.

The current problem is nearly no theme developers are using locals, while config & page contains to much changeable things across different pages. We need a way to recognize what value from site, config or page will be used during rendering the partial. If we have to let theme developer to support enhance_cache by passing locals, the feature will become useless.

Cache output for Helpers

Since it is hard to address aggressive cache for partial, another idea is to enable cache for other helpers. For example, url_for() should output the same result when inputted paths are the same (unless relative option is enabled). Based on this idea we could enable lfu cache for helpers likes url_for(), full_url_for(), gravatar(), meta_generator() and list_[type]().

cc @hexojs/core

@SukkaW SukkaW changed the title Enhancement of fragment_cache Enhancement of fragment_cache - enhance_cache Dec 1, 2019
@SukkaW SukkaW added the discussion label Dec 1, 2019

This comment has been minimized.

Copy link
Member Author

@SukkaW SukkaW commented Dec 2, 2019

I have bring up the implementation of this proposal in #3901 & #3092.

In #3902, I add enhance_cache option (default: false) option.

When a theme developer has specified { cache: true } or { cache: [cacheId] }, the fragment_cache will be enabled no matter enhance_cache is enabled or not. For the case a theme developer want to cache this partial even the locals has changed, I believe this approach will be helpful.

When a theme developer doesn't utilize fragment_cache (no specific { cache }), the fragment_cache will still be enabled if enhance_cache is enabled. The cache id will be the md5 of the current locals to make sure there will be different cache across different locals.

When a theme developer has specified { cache: false }, the fragment_cache will be disabled no matter enhance_cache is enabled or not. For the case a theme developer want to disable caching through { cache } option, the enhance_cache will not break current behavior.

When a partial will have different locals across pages and posts, there will be multiple cache inside fragment_cache, causing huge memory consumption. To avoid this, the LFU cache has been introduced in #3901. The called-once cache will be considered as "cold" and be removed from fragment_cache.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
None yet
1 participant
You can’t perform that action at this time.