1, componentes funcionales
Para el primer truco, componentes funcionales, puede consultar este ejemplo en vivo .
El código del componente antes de la optimización es el siguiente:
<template>
<div class="cell">
<div v-if="value" class="on"></div>
<section v-else class="off"></section>
</div>
</template>
<script>
export default {
props: ['value'],
}
</script>
El código del componente optimizado es el siguiente:
<template functional>
<div class="cell">
<div v-if="props.value" class="on"></div>
<section v-else class="off"></section>
</div>
</template>
Luego, renderizamos 800 componentes antes y después de la optimización en cada componente principal y activamos las actualizaciones de los componentes modificando los datos dentro de cada marco, abrimos el panel Rendimiento de Chrome para registrar su rendimiento y obtenemos los siguientes resultados.
Antes de la optimización:
Optimizado:
Al comparar estas dos cifras, podemos ver que el tiempo script
de ejecución es más largo que después de la optimización, y sabemos que el motor JS es un mecanismo operativo de un solo subproceso, y el subproceso JS bloqueará el subproceso de la interfaz de usuario, por lo que cuando el script el tiempo de ejecución es demasiado largo, bloqueará el procesamiento y la página se congelará. Y el tiempo script
de ejecución es corto, por lo que su rendimiento es mejor.
Entonces, ¿por qué el tiempo de ejecución es más corto con el componente funcional JS? Esto comienza con el principio de implementación de los componentes funcionales. Puede entenderlo como una función que puede representar y generar una parte de DOM de acuerdo con los datos de contexto que pasa.
Los componentes funcionales son diferentes de los componentes ordinarios de tipo objeto. No se considerarán como un componente real. Sabemos que en patch
el proceso si un nodo es un componente vnode
, ejecutará recursivamente el proceso de inicialización de los subcomponentes; mientras que los componentes funcionales Lo render
generado es normal vnode
, no habrá proceso de subcomponentes recursivos, por lo que la sobrecarga de representación será mucho menor.
Por lo tanto, los componentes funcionales tampoco tendrán estado, datos de respuesta y funciones de enlace de ciclo de vida. Puede pensar en ello como quitar parte del DOM de la plantilla de componente común y representarlo a través de una función, que es una especie de reutilización a nivel de DOM.
2, división de componentes secundarios
Para el segundo truco, la división de subcomponentes, puede consultar este ejemplo en línea .
El código del componente antes de la optimización es el siguiente:
<template>
<div :style="{ opacity: number / 300 }">
<div>{
{ heavy() }}</div>
</div>
</template>
<script>
export default {
props: ['number'],
methods: {
heavy () {
const n = 100000
let result = 0
for (let i = 0; i < n; i++) {
result += Math.sqrt(Math.cos(Math.sin(42)))
}
return result
}
}
}
</script>
El código del componente optimizado es el siguiente:
<template>
<div :style="{ opacity: number / 300 }">
<ChildComp/>
</div>
</template>
<script>
export default {
components: {
ChildComp: {
methods: {
heavy () {
const n = 100000
let result = 0
for (let i = 0; i < n; i++) {
result += Math.sqrt(Math.cos(Math.sin(42)))
}
return result
},
},
render (h) {
return h('div', this.heavy())
}
}
},
props: ['number']
}
</script>
Luego, renderizamos 300 componentes antes y después de la optimización en cada componente principal y activamos las actualizaciones de los componentes modificando los datos dentro de cada marco, abrimos el panel Rendimiento de Chrome para registrar su rendimiento y obtenemos los siguientes resultados.
Antes de la optimización:
Optimizado:
Comparando estas dos cifras, podemos ver que el tiempo script
de ejecución es significativamente menor que antes de la optimización, por lo que la experiencia de rendimiento es mejor.
Entonces, ¿por qué hay una diferencia? Veamos el componente antes de la optimización. El ejemplo simula una tarea que requiere mucho tiempo a través de una heavy
función , y esta función se ejecutará cada vez que se renderice, por lo que cada renderizado del componente consumirá mucho tiempo. hora de ejecutar JavaScript.
La forma optimizada heavy
es ChildComp
encapsular la lógica de ejecución de esta función de tarea que consume mucho tiempo con subcomponentes. Dado que la actualización de Vue se realiza en la granularidad de los componentes, aunque cada cuadro provocará la re-renderización del componente principal a través de la modificación de datos ChildComp
, se vuelve a renderizar porque tampoco tiene ningún cambio de datos de respuesta interna. Por lo tanto, el componente optimizado no realizará tareas que consumen mucho tiempo cada vez que se renderice y, naturalmente, se reducirá el tiempo de ejecución de JavaScript.
Sin embargo, he presentado algunas opiniones diferentes sobre este método de optimización. Para más detalles, puede hacer clic en este problema . Creo que calcular las propiedades para la optimización en este escenario es mejor que dividir los subcomponentes. Gracias a la función de almacenamiento en caché de las propiedades calculadas, la lógica que consume mucho tiempo solo se ejecutará en la primera representación, y no hay sobrecarga adicional para la representación de subcomponentes cuando se utilizan propiedades calculadas.
En el trabajo real, hay muchos escenarios donde las propiedades informáticas se utilizan para optimizar el rendimiento.Después de todo, también refleja una idea de optimización de intercambiar espacio por tiempo.
3, Variables locales
El tercer truco, las variables locales, puede consultar este ejemplo en línea .
El código del componente antes de la optimización es el siguiente:
<template>
<div :style="{ opacity: start / 300 }">{
{ result }}</div>
</template>
<script>
export default {
props: ['start'],
computed: {
base () {
return 42
},
result () {
let result = this.start
for (let i = 0; i < 1000; i++) {
result += Math.sqrt(Math.cos(Math.sin(this.base))) + this.base * this.base + this.base + this.base * 2 + this.base * 3
}
return result
},
},
}
</script>
El código del componente optimizado es el siguiente:
<template>
<div :style="{ opacity: start / 300 }">{
{ result }}</div>
</template>
<script>
export default {
props: ['start'],
computed: {
base () {
return 42
},
result ({ base, start }) {
let result = start
for (let i = 0; i < 1000; i++) {
result += Math.sqrt(Math.cos(Math.sin(base))) + base * base + base + base * 2 + base * 3
}
return result
},
},
}
</script>
Luego, renderizamos 300 componentes antes y después de la optimización en cada componente principal y activamos las actualizaciones de los componentes modificando los datos dentro de cada marco, abrimos el panel Rendimiento de Chrome para registrar su rendimiento y obtenemos los siguientes resultados.
Antes de la optimización:
Optimizado:
Comparando estas dos cifras, podemos ver que el tiempo script
de ejecución es significativamente menor que antes de la optimización, por lo que la experiencia de rendimiento es mejor.
Esto se debe principalmente a la diferencia en la implementación result
de . Se accede muchas veces a los componentes antes de la optimización durante el proceso de cálculo this.base
, mientras que los componentes optimizados utilizarán variables locales antes del cálculo base
, caché this.base
y luego acceder directamente a ellos más tarde base
.
Entonces, ¿por qué esta diferencia causa una diferencia en el rendimiento? La razón es que cada vez que this.base
visita , dado que this.base
es un objeto receptivo, se activará getter
y luego se ejecutará el código lógico relacionado con la recopilación de dependencias. Si se ejecuta demasiada lógica similar, como en el ejemplo, cientos de ciclos actualizan cientos de componentes, cada componente activa computed
el recálculo y luego ejecuta la lógica relacionada con la recopilación de dependencias varias veces, el rendimiento caerá naturalmente.
En términos de requisitos, this.base
basta con ejecutar la recopilación de dependencias una vez y devolver su resultado getter
de evaluación a una variable local. No se activará cuando se vuelvabase
a acceder más tarde, y no se seguirá la lógica de la recopilación de dependencias, y el rendimiento naturalmente se mejorará. .base
getter
Esta es una técnica de optimización del rendimiento muy útil. Porque cuando muchas personas desarrollan proyectos Vue.js, habitualmente this.xxx
escriben , porque la mayoría de la gente no se da cuenta this.xxx
de lo que se hace detrás del acceso. Cuando la cantidad de visitas es pequeña, el problema de rendimiento no es importante, pero una vez que aumenta la cantidad de visitas, como varias visitas en un bucle grande, similar al escenario de ejemplo, se producirán problemas de rendimiento.
Cuando estaba optimizando el rendimiento del componente Table de ZoomUI, render table body
utilicé técnicas de optimización de variables locales y escribí un punto de referencia para la comparación del rendimiento: al renderizar una tabla de 1000 * 10, el rendimiento de volver a renderizar los datos actualizados de la tabla de ZoomUI debería ser Ha casi duplicó el rendimiento de la tabla de ElementUI.
4、Reutilizar DOM con v-show
El cuarto truco, usando v-show
Reuse DOM, puede consultar este ejemplo en línea .
El código del componente antes de la optimización es el siguiente:
<template functional>
<div class="cell">
<div v-if="props.value" class="on">
<Heavy :n="10000"/>
</div>
<section v-else class="off">
<Heavy :n="10000"/>
</section>
</div>
</template>
El código del componente optimizado es el siguiente:
<template functional>
<div class="cell">
<div v-show="props.value" class="on">
<Heavy :n="10000"/>
</div>
<section v-show="!props.value" class="off">
<Heavy :n="10000"/>
</section>
</div>
</template>
Luego, renderizamos 200 componentes antes y después de la optimización en cada componente principal y activamos las actualizaciones de los componentes modificando los datos dentro de cada marco, y abrimos el panel Rendimiento de Chrome para registrar su rendimiento y obtener los siguientes resultados.
Antes de la optimización:
Optimizado:
Comparando estas dos cifras, podemos ver que el tiempo script
de ejecución es significativamente menor que antes de la optimización, por lo que la experiencia de rendimiento es mejor.
La principal diferencia antes y después de la optimización es que v-show
el comando en lugar v-if
del comando para reemplazar la claridad del componente. Aunque es similarv-show
en términos de rendimiento, controla la claridad del componente, pero todavía hay una gran brecha. en la implementación interna.v-if
v-if
Las instrucciones se compilarán en un operador ternario y una representación condicional durante la fase de compilación. Por ejemplo, la plantilla del componente antes de la optimización se compila para generar la siguiente función de representación:
function render() {
with(this) {
return _c('div', {
staticClass: "cell"
}, [(props.value) ? _c('div', {
staticClass: "on"
}, [_c('Heavy', {
attrs: {
"n": 10000
}
})], 1) : _c('section', {
staticClass: "off"
}, [_c('Heavy', {
attrs: {
"n": 10000
}
})], 1)])
}
}
Cuando el valor props.value
de cambia, activará la actualización del componente correspondiente. Para v-if
el nodo renderizado, debido a que los nodos antiguo y nuevo vnode
son inconsistentes , durante el proceso de comparación del algoritmo de diferencia central, el vnode
nodo antiguo se eliminará y se se creará un nuevo vnode
nodo El nuevo Heavy
componente pasará por el proceso de Heavy
inicialización del componente, renderizado vnode
, patch
etc.
Por lo tanto, v-if
cada vez que se actualice un componente, Heavy
se creará un nuevo subcomponente. Cuando hay muchos componentes actualizados, naturalmente causará presión en el rendimiento.
Y cuando usamos v-show
la directiva , la plantilla del componente optimizado se compila para generar la siguiente función de representación:
function render() {
with(this) {
return _c('div', {
staticClass: "cell"
}, [_c('div', {
directives: [{
name: "show",
rawName: "v-show",
value: (props.value),
expression: "props.value"
}],
staticClass: "on"
}, [_c('Heavy', {
attrs: {
"n": 10000
}
})], 1), _c('section', {
directives: [{
name: "show",
rawName: "v-show",
value: (!props.value),
expression: "!props.value"
}],
staticClass: "off"
}, [_c('Heavy', {
attrs: {
"n": 10000
}
})], 1)])
}
}
Cuando el valor props.value
de cambia, activará la actualización del componente correspondiente. Para v-show
los nodos renderizados, dado que el antiguo y el nuevo vnode
son consistentes , solo necesitan patchVnode
serlo todo el tiempo. Entonces, ¿cómo hace que se muestren los nodos DOM? y ocultar?
Resulta que en patchVnode
el proceso , v-show
la función de enlace correspondiente a la instrucción se ejecutará internamente update
, y luego v-show
establecerá style.display
el valor del elemento DOM sobre el que actúa para controlar la visualización y la ocultación de acuerdo con el valor vinculado por la instrucción.
Por lo tanto, en comparación con la eliminación v-if
constante y la creación de nuevas funciones DOM, v-show
solo actualiza los valores explícitos e implícitos del DOM existente, por lo que v-show
la sobrecarga v-if
de es mucho menor que la de , y cuanto más compleja es la estructura DOM interna, mayor. la diferencia de rendimiento será.
Pero v-show
en comparación con v-if
la ventaja de rendimiento de está en la fase de actualización del componente, si solo está en la fase de inicialización, v-if
el rendimiento es mayor que v-show
eso, porque solo representa una rama, v-show
representa ambas ramas y style.display
controla la correspondencia a través de The visibilidad del DOM.
Al v-show
usar , se renderizarán todos los componentes internos de la rama y v-if
se ejecutarán las funciones de enlace del ciclo de vida correspondientes, mientras que al usar , los componentes dentro de la rama no afectada no se renderizarán y las funciones de enlace del ciclo de vida correspondientes no se ejecutarán .
Por lo tanto, debe comprender sus principios y diferencias para utilizar las instrucciones adecuadas en diferentes escenarios.
5, mantener vivo
El quinto truco, usar KeepAlive
componentes para almacenar en caché el DOM, puede consultar este ejemplo en línea .
El código del componente antes de la optimización es el siguiente:
<template>
<div id="app">
<router-view/>
</div>
</template>
El código del componente optimizado es el siguiente:
<template>
<div id="app">
<keep-alive>
<router-view/>
</keep-alive>
</div>
</template>
Cuando hacemos clic en el botón para cambiar entre la página simple y la página pesada, se renderizarán diferentes vistas, y la renderización de la página pesada requiere mucho tiempo. Abrimos el panel Rendimiento de Chrome para registrar su rendimiento y luego realizamos las operaciones anteriores antes y después de la optimización, y obtendremos los siguientes resultados.
Antes de la optimización:
Optimizado:
Comparando estas dos cifras, podemos ver que el tiempo script
de ejecución es significativamente menor que antes de la optimización, por lo que la experiencia de rendimiento es mejor.
En el escenario no optimizado, cada vez que hagamos clic en el botón para cambiar la vista de enrutamiento, el componente se volverá a procesar y el componente procesado pasará por la inicialización del componente y otros procesos. Si el componente es más render
complicado patch
o anidado profundamente, todo el tiempo de renderizado se reducirá será muy largo.
KeepAlive
Después de usar , KeepAlive
después de la primera representación del componente envuelto, vnode
el DOM se almacenará en caché, y luego, cuando el componente se vuelva a representar la próxima vez, el vnode
DOM correspondiente se obtendrá directamente del caché y luego se procesará. No es necesario. pasar por una serie de procesos como la inicialización de componentes render
, patch
etc. , lo que reduce script
el tiempo de ejecución y mejora el rendimiento.
Pero el uso KeepAlive
de componentes no está libre de costos, ya que requerirá más memoria para el almacenamiento en caché, que es una aplicación típica de las ideas de optimización de espacio por tiempo.
6, Funciones diferidas
La sexta técnica, usar Deferred
componentes para renderizar componentes en lotes de manera retrasada, puede consultar este ejemplo en línea .
El código del componente antes de la optimización es el siguiente:
<template>
<div class="deferred-off">
<VueIcon icon="fitness_center" class="gigantic"/>
<h2>I'm an heavy page</h2>
<Heavy v-for="n in 8" :key="n"/>
<Heavy class="super-heavy" :n="9999999"/>
</div>
</template>
El código del componente optimizado es el siguiente:
<template>
<div class="deferred-on">
<VueIcon icon="fitness_center" class="gigantic"/>
<h2>I'm an heavy page</h2>
<template v-if="defer(2)">
<Heavy v-for="n in 8" :key="n"/>
</template>
<Heavy v-if="defer(3)" class="super-heavy" :n="9999999"/>
</div>
</template>
<script>
import Defer from '@/mixins/Defer'
export default {
mixins: [
Defer(),
],
}
</script>
Cuando hacemos clic en el botón para cambiar entre la página simple y la página pesada, se renderizarán diferentes vistas, y la renderización de la página pesada requiere mucho tiempo. Abrimos el panel Rendimiento de Chrome para registrar su rendimiento y luego realizamos las operaciones anteriores antes y después de la optimización, y obtendremos los siguientes resultados.
Antes de la optimización:
Optimizado:
Al comparar estas dos imágenes, podemos encontrar que cuando cambiamos de Página simple a Página pesada antes de la optimización, cuando un Render está cerca del final, la página aún se muestra como Página simple, lo que dará a las personas una sensación de congelación de página. Después de la optimización, cuando cambiamos de la página simple a la página pesada, la página pesada ya se ha renderizado una vez al frente del renderizado, y la página pesada se renderiza progresivamente.
La diferencia antes y después de la optimización se debe principalmente a que esta última usa Defer
this mixin
, entonces, ¿cómo funciona? Averigüemos:
export default function (count = 10) {
return {
data () {
return {
displayPriority: 0
}
},
mounted () {
this.runDisplayPriority()
},
methods: {
runDisplayPriority () {
const step = () => {
requestAnimationFrame(() => {
this.displayPriority++
if (this.displayPriority < count) {
step()
}
})
}
step()
},
defer (priority) {
return this.displayPriority >= priority
}
}
}
}
Defer
La idea principal de es dividir una renderización de un componente en varias veces. Mantiene displayPriority
las variables y luego requestAnimationFrame
se incrementa al renderizar cada cuadro, hasta count
. Luego Defer mixin
use el interior del componente v-if="defer(xxx)"
para displayPriority
controlar xxx
la representación de ciertos bloques cuando se agreguen a .
Cuando tiene componentes que tardan en renderizarse, es una buena idea Deferred
utilizar el renderizado progresivo para evitar render
que el renderizado se atasque debido al largo tiempo de ejecución de JS.
7, división de tiempo
La séptima técnica, utilizando Time slicing
la técnica de corte de tiempo , puede consultar este ejemplo en línea .
El código antes de la optimización es el siguiente:
fetchItems ({ commit }, { items }) {
commit('clearItems')
commit('addItems', items)
}
El código optimizado es el siguiente:
fetchItems ({ commit }, { items, splitCount }) {
commit('clearItems')
const queue = new JobQueue()
splitArray(items, splitCount).forEach(
chunk => queue.addJob(done => {
// 分时间片提交数据
requestAnimationFrame(() => {
commit('addItems', chunk)
done()
})
})
)
await queue.start()
}
Primero creamos 10,000 piezas de datos falsos haciendo clic Genterate items
en el botón y luego Time-slicing
hacemos clic en Commit items
el botón para enviar los datos cuando se enciende y apaga, y abrimos el panel Rendimiento de Chrome para registrar su rendimiento, y se obtendrán los siguientes resultados.
Antes de la optimización:
Optimizado:
Al comparar estas dos cifras, podemos encontrar que el script
tiempo total de ejecución antes de la optimización es menor que después de la optimización, pero desde la apariencia real, haga clic en el botón Enviar antes de la optimización, la página se congelará durante aproximadamente 1,2 segundos, después de la optimización, el la página no se atascará por completo, pero aún habrá una sensación de retraso en el procesamiento.
Entonces, ¿por qué la página se bloquea antes de la optimización? Debido a que se envían demasiados datos a la vez, el tiempo de ejecución interno de JS es demasiado largo, lo que bloquea el subproceso de la interfaz de usuario y hace que la página se congele.
Después de la optimización, la página aún se congela porque la granularidad de los datos que dividimos es 1000. En este caso, todavía hay presión para volver a renderizar el componente. Observamos que los fps son solo una docena, y habrá una sensación de congelar. Por lo general, siempre que los fps de la página alcancen los 60, la página será muy fluida. Si cambiamos la granularidad de división de datos a 100, básicamente los fps pueden llegar a más de 50. Aunque la representación de la página se vuelve más fluida, el envío total de Se han completado 10.000 datos. El tiempo sigue siendo más largo.
El uso Time slicing
de la tecnología puede evitar que la página se atasque, por lo general agregaremos un efecto de carga al procesar esta tarea que requiere mucho tiempo, en este ejemplo, podemos abrirla loading animation
y luego enviar los datos. La comparación encontró que antes de la optimización, debido a que se enviaron demasiados datos a la vez, JS se ha estado ejecutando durante mucho tiempo, bloqueando el subproceso de la interfaz de usuario, esta animación de carga no se mostrará, pero después de la optimización, porque la dividimos en varias veces cortes para enviar datos, un solo El tiempo de ejecución de JS se acorta para que la animación de carga tenga la oportunidad de mostrarse.
Una cosa a tener en cuenta aquí es que, aunque usamos
requestAnimationFrame
la API para dividir el intervalo de tiempo, el usorequestAnimationFrame
en sí mismo no puede garantizar el funcionamiento de fotograma completo.requestAnimationFrame
Lo que se garantiza es que la función de devolución de llamada entrante correspondiente se ejecutará después de cada redibujado del navegador. Si quiere asegurarse de que los marcos completos solo puedan hacer que el tiempo de ejecución de JS dentro de un Tick no supere los 17 ms.
8, datos no reactivos
El octavo consejo, utilizando datos Non-reactive data
que no responden, puede consultar este ejemplo en línea .
El código antes de la optimización es el siguiente:
const data = items.map(
item => ({
id: uid++,
data: item,
vote: 0
})
)
El código optimizado es el siguiente:
const data = items.map(
item => optimizeItem(item)
)
function optimizeItem (item) {
const itemData = {
id: uid++,
vote: 0
}
Object.defineProperty(itemData, 'data', {
// Mark as non-reactive
configurable: false,
value: item
})
return itemData
}
Aún en el ejemplo anterior, primero creamos 10,000 piezas de datos falsos haciendo clic Genterate items
en el botón y luego Partial reactivity
hacemos clic en Commit items
el botón encendido y apagado respectivamente, y abrimos el panel Rendimiento de Chrome para registrar su rendimiento, y los siguientes resultados serán Ser obtenido.
Antes de la optimización:
Optimizado:
Comparando estas dos cifras, podemos ver que el tiempo script
de ejecución es significativamente menor que antes de la optimización, por lo que la experiencia de rendimiento es mejor.
El motivo de esta diferencia es que cuando los datos se envían internamente, los nuevos datos enviados también se definirán como sensibles de forma predeterminada.Si el subatributo de los datos tiene la forma de un objeto, recursivamente hará que el sub- El atributo también se vuelve receptivo. Por lo tanto, al enviar una gran cantidad de datos, este proceso se convierte en un proceso que consume mucho tiempo.
Después de la optimización, cambiamos data
manualmente configurable
para que sea , de modo que la matriz de atributos del objeto obtenida false
internamente walk
hasta cuándo se ignorará y no será este atributo , porque apunta a un objeto, por lo que también será be Reducir la lógica de la capacidad de respuesta recursiva es equivalente a reducir la pérdida de rendimiento de esta parte. Cuanto mayor sea la cantidad de datos, más evidente será el efecto de esta optimización.Object.keys(obj)
data
data
defineReactive
data
De hecho, hay muchos otros métodos de optimización como este, por ejemplo, algunos datos que definimos en componentes pueden no estar necesariamente definidos data
en . No usamos algunos datos en la plantilla, y no necesitamos monitorear sus cambios. Solo queremos compartir estos datos en el contexto del componente. En este momento, solo podemos montar los datos this
en
export default {
created() {
this.scroll = null
},
mounted() {
this.scroll = new BScroll(this.$el)
}
}
De esta manera podemos compartir scroll
el objeto , aunque no sea un objeto reactivo.
9, Desplazamiento virtual
Para el noveno consejo, utilizando el componente de desplazamiento Virtual scrolling
virtual , puede consultar este ejemplo en vivo .
El código del componente antes de la optimización es el siguiente:
<div class="items no-v">
<FetchItemViewFunctional
v-for="item of items"
:key="item.id"
:item="item"
@vote="voteItem(item)"
/>
</div>
El código optimizado es el siguiente:
<recycle-scroller
class="items"
:items="items"
:item-size="24"
>
<template v-slot="{ item }">
<FetchItemView
:item="item"
@vote="voteItem(item)"
/>
</template>
</recycle-scroller>
Aún en el ejemplo anterior, debemos abrirlo View list
y luego hacer clic en Genterate items
el botón para crear 10000 datos falsos (tenga en cuenta que el ejemplo en línea solo puede crear hasta 1000 datos, de hecho, 1000 datos no reflejan bien el efecto de optimización, así que Se modificó la limitación del código fuente, se ejecutó localmente, se crearon 10 000 piezas de datos y Unoptimized
luego RecycleScroller
hizo clic en Commit items
el botón para enviar los datos y, respectivamente, se desplazó por la página, se abrió el panel Rendimiento de Chrome para registrar su rendimiento y se obtendrán los siguientes resultados.
Antes de la optimización:
Optimizado:
Al comparar estas dos imágenes, encontramos que en el caso de no optimización, los fps de 10,000 piezas de datos son solo dígitos individuales en el caso de desplazamiento, y solo una docena en el caso de no desplazamiento. hay demasiados DOM renderizados en la escena no optimizada. La presión en sí es muy alta. Después de la optimización, incluso con 10.000 datos, los fps pueden ser más de 30 en el caso de desplazamiento y pueden llegar a 60 fotogramas completos en el caso de no rodar.
El motivo de esta diferencia es que la implementación del desplazamiento virtual es solo para renderizar el DOM en la ventana gráfica, de modo que la cantidad total de DOM renderizado es muy pequeña y el rendimiento natural será mucho mejor.
El componente de desplazamiento virtual también está escrito por Guillaume Chau , los estudiantes interesados pueden estudiar su implementación de código fuente . Su principio básico es monitorear eventos de desplazamiento, actualizar dinámicamente los elementos DOM que se mostrarán y calcular su desplazamiento en la vista.
El componente de desplazamiento virtual no está exento de costes, ya que debe calcularse en tiempo real durante el proceso de desplazamiento, por lo que habrá un cierto coste script
de ejecución . Por lo tanto, si la cantidad de datos en la lista no es muy grande, nos basta con usar el desplazamiento ordinario.
Resumir
A través de este artículo, espero que pueda comprender las nueve técnicas de optimización del rendimiento de Vue.js y aplicarlas a proyectos de desarrollo reales. Además de las técnicas anteriores, también existen métodos de optimización del rendimiento de uso común, como la carga diferida de imágenes, la carga diferida de componentes y los componentes asincrónicos.
Antes de realizar la optimización del rendimiento, debemos analizar dónde está el cuello de botella del rendimiento para que podamos adaptarnos a las condiciones locales. Además, la optimización del rendimiento requiere soporte de datos. Antes de realizar cualquier optimización del rendimiento, debe recopilar los datos antes de la optimización, de modo que pueda ver el efecto de la optimización a través de la comparación de datos después de la optimización.
Espero que en el proceso de desarrollo futuro, no solo esté satisfecho con los requisitos de implementación, sino que también piense en el impacto que puede tener en el rendimiento al escribir cada línea de código.
Este artículo se publicó por primera vez en la cuenta pública "Cocina privada frontal de Lao Huang" , bienvenido a prestar atención.
Autor: Huang Yi
Enlace: https://juejin.cn/post/6922641008106668045
Fuente: Rare Earth Nuggets
Los derechos de autor pertenecen al autor. Para reimpresión comercial, comuníquese con el autor para obtener autorización, para reimpresión no comercial, indique la fuente.