Vue: Make it possible to clear/disable templates cache

Created on 14 Dec 2017  ·  13Comments  ·  Source: vuejs/vue

What problem does this feature solve?

When using <script type="x-template"> for providing template source - it get cached (https://github.com/vuejs/vue/blob/cfd73c2386623341fdbb3ac636c4baf84ea89c2c/src/platforms/web/entry-runtime-with-compiler.js#L12). When using same elements for templates like #order-template on different pages like /orders/1, /orders/2, both components are rendered with first compiled template.

Even when using different template ids, their content is cached which is unnecessary and leads to memory bloat: it caches inner html which is fast to fetch.

Proposed feature will give ability to opt out template caching.

What does the proposed API look like?

Vue.clearAllCaches() or Vue.templateCache = false.

Most helpful comment

I still consider this a bug. When doing "new Vue({template:'#template1'.." and then purposefully load a different page where #template1 has a different content, doing "new Vue({template:'#template1'.." should respect that and not still use the old template content. This is especially weird when using Vue as an on demand tool when extending foreign single page apps.
My workaround for now is using "template: $('#template1').text(),"

And why should a user care about caching of a tool in the first place (setting templateCache=false)? Its the tools responsibility to use the cache correctly which means checking if its cache is current before it proceeds to use it.

All 13 comments

Just wondering, why /orders/1 and /orders/2 have different templates instead of using logic directive in same template?

That's not how templates are intended to be used. The same component should always have the same template, you should use Vue's own logic directives to display different content based on data.

Thank you, I'll try this.

What if I have localized templates (template with same id will have different translations), and want to give ability to switch language without full page reload?

@JounQin some features are available only for premium users, so we want some parts of templates not be visible even in page source.

@yyx990803 what if cached wrapper will take optional cache argument to set cache object explicitly, and in this place Vue.templateCache will be passed? This way template cache will be accessible from user-space and can be cleared manually.

The template cache is something we do not intend to expose to the user, nor should your app logic rely on it. The template self is a language to express dynamic information and you should work within the template, not outside of it.

If you don't want to expose your template source, you should use a pre-compile step, e.g. with vue-loader.

@yyx990803 thank you! I've just checked vue-loader, it seems to work only with webpack.

Can you please advise, how should this be done: server renders vue template into <script id='some-template'> with some translations (eg., action names, labels, etc.). When user changes locale, server renders new content (same markup, different translated phrases) into the same script tag. This way, vue will continue render this template in old locale. The only way i see is to use locale suffix in all template ids, but this will require having global js variable to be used in template: "#some-template-#{window.LOCALE}". This looks dirty to me.

UPD. moving all translations to js is not acceptable for our app.

Are you saying when changing locale the page does not reload, but simply fetches new templates via Ajax and updates the <script> nodes?

@yyx990803 yes, we use turbolinks, it replaces body with one fetched via xhr.

@Akryum thank you! If i get i right, it's lib for client-side translations. We are not able to move translation logic to frontend for now, it's out of scope of current tasks.

@yyx990803 one more issue we've faced is rendering old templates after deploying updates: server renders updated vue template but it's not applied until user reloads page.

I want to create more complex widgets/components.
I've describe one of them here: https://forum.vuejs.org/t/how-to-create-reusable-component-with-external-plugin-behavior-logic/28101

I did it with dynamic templates and i've also notice the issue with template cache.
But if on call I change some prop value of this component it works fine...
Is there gonna be some core problem ?

I still consider this a bug. When doing "new Vue({template:'#template1'.." and then purposefully load a different page where #template1 has a different content, doing "new Vue({template:'#template1'.." should respect that and not still use the old template content. This is especially weird when using Vue as an on demand tool when extending foreign single page apps.
My workaround for now is using "template: $('#template1').text(),"

And why should a user care about caching of a tool in the first place (setting templateCache=false)? Its the tools responsibility to use the cache correctly which means checking if its cache is current before it proceeds to use it.

Was this page helpful?
0 / 5 - 0 ratings