VUE single page caching scheme analysis and implementation

Realize the page cache of the whole station, forward refresh, return to the cache, and remember the scroll position of the previous page, refer to the multi-technical implementation, the principle of the navigation component on GitHub either use the keyp-alive, or Refer to Keep-Alive source code, but only use Keep-alive can’t achieve the same path, different parameters show different views, this is a bit pit, so it is necessary to combine the functions you want to implement, properly transform Keep-Alive, in order to implement each The secondary advancement can be refreshed, returning the function of the cache can be automatically positioned, and the article will open from the following aspects: two sets of technical programs optional, the cause of the final technical solution, the function and principle of implementation, stepped over Pit

for VUE is specifically used:

Why is this used?

, such as VUE official website ( API / # keep-alive) Introduction:

When you wrap dynamic components, you can cache unacceptable component instances instead of destroying them. Similar to


is an abstract component: it does not render a DOM element, nor does it appear in the parent component chain.

When the component is switched within , its ActiVated and deActivated two lifecycle hook functions will be executed. Mainly used to reserve components or avoid rendering.

Because the need to be cached, when the page is switched, it is necessary to combine the Router-View of the Vue-Router to achieve

why Keep-Alive can achieve a cache?

Render () {const slot = this $ slots.default const vnode:. VNode = getFirstComponentChild (slot) const componentOptions:? VNodeComponentOptions = vnode && vnode.componentOptions if (componentOptions) {// check pattern const name:? string = getComponentName (componentOptions) const { INCLUDE, Exclude} = this if (// Name ||! Matches (include, name)) || // Excluded (Exclude && name && matches (exclude, name)) {Return vNode } const {cache, keys} = this const key:?? string = vnode.key == null // same constructor may get registered as different local components // so cid alone is not enough (# 3269) componentOptions.Ctor.cid + (ComponentOptions.tag? `: $ {componentOptions.tag}` `’): vnode.key if (cache [key]) {vNode.ComponentInstance =Cache [Key] .componentinstance // make Current Key Freshest Remove (Keys, Key) Keys.push (key)} else {cache [key] = vnode key ipush (key) // Prune Oldest Entry IF (this.max && Keys.Length> Parseint (this.max)) {prunecachentry (cache, keys [0], keys, this._vnode)}} = true} return vnode || (Slot && slot [0])}

As the Keep-Alive source code, where the render function is implemented, the attempt component to be rendered as the slot content, when rendered to the path matching When the component is stored according to the content stored by vNode, the component instance is placed in the variable cache so that the cache can be found according to the route, and the CreateComponent method can be used to perform the INITComponent, the VUE component renders this piece of code. as follows
function initComponent (vnode, insertedVnodeQueue) {if (isDef ( {insertedVnodeQueue.push.apply (insertedVnodeQueue, vNode.Data.pendingInsert = null}vnode.elm = vnode.componentInstance. $ el if (isPatchable (vnode)) {invokeCreateHooks (vnode, insertedVnodeQueue) setScope (vnode)} else {// empty component root. // skip all element-related modules except for ref (# 3455) RegisterRef (vNode) // Make Sure to Invoke The Insert Hook InsertEdvnodequeue.push (vNode)}}
Here there is vnode.elm cache VNODE creation generation DOM node. Therefore, for the first rendering, there is no difference in the establishment of caching in

, and there is no difference between ordinary component rendering. From the substantially executable process that enters returned, the function can be implemented

can render the VNODE to cache to record the Cache When returned, use the DOM directly rendered in the cache, there is the include and Exclude properties provided by the Keep-Alive component, you can have conditional cache you want to cache, if you configure your max, the length of the cache exceeds this max of this MAX It is also necessary to delete the problem with the first
  from the cache  
The problem is that the key to store the VNODE node is Name, which is the NAME corresponding to the route time component. This will lead to the same path. When the different parameters are opened, the VNODe you get from the cache will render the same view, but many business scenes are displayed according to the parameters, and Keep-Alive is under NoThis is extended, you can see the Keep-Alive source

Const key:? String = vnode.key == null? ComponentOptions.ctor.cid + (ComponentOptions.tag? `: $ {componentOptions.tag}`: ”): vNode.Key if (cache [key]) {vNode.componentInstance = cache [key] .componentinstance // make Current Key Freshest Remove (Keys, Key) keys. Push (key)} else {cache [key] = vnode keys.push (key) // prune oldest entry if (this.max && keys.length> parseint (this.max)) {prunecacheentry (cache, keys [0] , Keys vue单页缓存方案分析及实现

You is the NAME defined by the route, so it is necessary to use this set of scheme to display different views according to different parameters. The function is to be transformed, but Keep-alive is Vue itself, can’t change the bottom, then born my second plan

Scheme 2: Navigation Components, Scrollbehavior

GitHub finds a similar function component Vue-Navigation, this VUE component can be retrieved, the underlying principle is the same as Keep-alive, actually rewritten.Keep-alive component, add a parameter VNK when the forward refresh is refreshed, so when the routing changes, it will be used to bring a parameter, and the Cache’s Key value rely on this parameter, draws on the idea of ​​this component, and made a similar Keep-alive components, where Key’s value is obtained by getKey method, the render method after rewriting is as follows

  Render () {var vNode = this. $ slots.default this. $ slots.default [0]: null if (vNode) {vNode.key = vnode.key || (vNode.iscomment? 'comment': vNode.tag) const {cache, keys} = this var key = GetKey (tris. $ route, keyname) if (vNode.key.indexof (key) === -1) {vNode.key = '__navigation-' + key + '-' + vNode.key} if (cache " ]) {if (vNode.key === cache [key] .key) {vNode.componentInstance = cache [key] .componentinstance} else {cache [key] .componentinstance. $ destroy () cache [key] = vnode} REMOVE (Keys, Key)} else {cache [key] = vNode Keys.push (key) // prunE Oldest Entry if (this.max && keys.length> parseint (this.max)) {prunecachentry (cache, keys [0], keys, this._vnode)}} = true} return vnode}  
GetKey method realizes

// URL value export function genkey () {// constit t = ‘xxxxxxx-xxxx-4xxxxxxx-xxxxxxxxxxxxx’ const t = ‘xxxxxxx’ Return T.Replace (/ [xy] / g, function (c) {const r = math.random () * 16 | 0 const v = c === ‘x’? R: (R & 0x3 | 0x8) Return v.toString (16)}} // export function getKey (route, keyname) {Return `$ { || Route.Path}? $ {route.query [keyname]}

Mount this navigation component to VUE by new writing Before refresh, return to the cache, and configure the maximum number of cache, subsequent open source to Github

Lastly returned to the previous page to remember the location of the previous page, the key to the open source It is because the direct set needs to change the overall layout, Height: 100%;Style caused $ (Windows). ScrollTop failed, overall considering the cost of transformation cost, or using the scrollbehavior provided by Vue-Router, introduced in the routing configuration
to achieve the following:
VAR scrollbehavior = async (to, from, savedposition) => {if (savedposition) {return savedposition} else {return new promise ((resolve, reject) => {setTimeout (() => {Resolve ({x: 0, y: to.meta.savedposition || 0})}, 300)}}}} const router = new Vuerouter ({Mode: ‘History’, Scrollbehavior, Routes: [{PATH: ‘”, Redirect: ‘/mobile/home.html’, Meta: {NEEDMTAREPORT: TRUE, PARENTSSTYLE: {HEIGHT: ‘100%, MinHeight:’ 100% ‘}}}, {name:’ sciencecompetition ‘, PATH:’ / Mobile /SCienceCompetition.html ‘, Component: ScienceCompetition}]

1. One page cache under JS loading analysis The time of compilation execution is shortened, and when the return, the occupancy time of the slow-saving JS script is completely ignored.Slightly, the overall reduction of the page load rendering time
2. Because the project is not a single page, the code defines a lot of global variables or global event bindings, and the value of the global variable after the single page is constant. Existence, it will lead to the business logic, so you need to pay attention to the global variable or the caution of the overall variable or the event. The specific step record is in
  3. When you enter the next page, the Head will accumulate the static resource of the front page. The more the page accessed, the more static resources hanging by the last page, the more you have loaded. Resources, single-page caching is a typical spatial change scheme, and the overhead of memory is relatively large, whether the extension of resource dynamics and decreases and the optimization of memory occupation have been explored, and there is no good solution for the time being. . . . .  
The above is all the content of this article, I hope to help everyone, I hope everyone will support Tumi Cloud.
© Copyright Notice
Just support it if you like
comment Grab the couch

Please log in to comment