I encountered a problem when using the throttling function today. It took me a long time to find the reason, so I will give a summary here.
Throttle function
Some events in the browser, such as: resize, scroll, mousemove, etc. These events trigger too frequently, and the callback functions bound to these events will be called continuously, increasing the burden on the browser and causing a very bad user experience. So the sages invented the throttling function, the simple version is as follows:
function throttle (f, wait = 200) { let last = 0 return function (...args) { let now = () if (now - last > wait) { last = now (this, args) } } }
Suppose there is a vue component svgMark. The rendered elements in this component should be redrawed when the page window size changes, and the throttling function should be used to prevent performance losses when redrawing. Under normal circumstances, the code is as follows:
<template> <div>{{ index }}</div> </template> <script> import { throttle } from 'lodash' export default { name: 'SvgMark', data() { return { index: 0 } }, mounted() { ('resize', ) }, beforeDestroy() { ('resize', ) }, methods: { reDraw: throttle(function() { ++ }, 500) } } </script> </script>
Generally speaking, there is no problem using this. However, there is a scenario where the throttling function fails when using it, that is, when this component is loaded many times by a v-for loop:
<template> <div> <svgMark v-for="item in 10" :key="" /> </div> </template>
At this time, no matter how many svgMark components are rendered, the redraw of the first component and the n-th cutting component is triggered when the window size changes. Why are other components not triggered? This has to start from the beginning.
- Throttle function
The throttling function generates a closure when initializing, and the variable last is saved in the closure. This last records the time when the f function was last executed. When the throttling function is triggered the next time, if the time now minus the last time last is less than the throttling time wait , then the function f will not be executed.
Obviously, the first child component produces a last when triggering the throttling function, while the second component produces now when triggering the throttling function does not meet the conditions of now - last > wait, so the redraw code is not executed. When the nth component triggers the throttling function, the condition of now - last > wait is met so the redraw is successful.
- vue component
During the code compilation stage of vue component, the method reDraw in component svgMark reDraw: throttle(function() { ++ }, 500) has been compiled into a function similar to the following:
reDraw: ƒ (...args) { let now = () if (now - last > wait) { last = now (this, args) } }
Since functions are reference types, all methods using subcomponent svgMark point to the same memory address, which means that the reDraw methods of all subcomponents are the same function.
Because all components share the same throttling function, of course, throttling will occur. So how to solve the problem? To prescribe the right medicine, each component must produce its own throttling function without sharing it. The code is as follows
Subcomponents:
<template> <div>{{ index }}</div> </template> <script> import { throttle } from 'lodash' export default { name: 'SvgMark', data() { return { index: 0 } }, mounted() { = throttle(() => { ++ }, 500) ('resize', ) }, beforeDestroy() { ('resize', ) } } </script>
We manually declare the reDraw function in the mounted declaration period function instead of reDraw in methods, so that each component will generate its own throttling function when it is initialized. It is necessary to note that the parameters of the throttling function use arrow functions at this time, because this will point to the component instance.
The above is the pitfall brought to me by the throttling function, and I will share it with you now. [Get off work][Applause]
The above is the detailed content of the failure and solution of the throttling function in the vue component. For more information about the throttling function of the vue component, please pay attention to my other related articles!