
Aproximadamente una semana antes de lanzar WP Migra DB Pro 1.6, Ashley Rich me rompió el corazón en nuestro débil canal.Fue así: / – – Dramatización – – / @Bradt: ¿está listos 1.6?@JrGould: ¡Sí!¡Estamos listos para ir!Absolutamente nada podría salir mal.@a5hleyrich: Hola @JrGould, la nueva interfaz de usuario se ve muy bien, pero se atasca cuando tengo mucho contenido multimedia @JRGould: ¿Qué?No.Probé con aproximadamente 1000 archivos multimedia.Tome una nueva computadora portátil.@A5hleyrich: tengo 10k accesorios y Chrome está bloqueado.@JrGould: No … @a5hleyrich: Lo siento, amigo.@JrGould: 😢 Encontrar la fuga Lo que siguió fue bastante especulación de todos sobre lo que causó que los navegadores se ralentizaran hasta que se arrastren y a menudo se atasquen cuando se emigraron grandes cantidades de archivos multimedia.Está claro que es un problema de memoria, pero ¿qué lo causa?
En primer lugar, un fondo. Es posible que haya visto el nuevo uso de WP Migra DB Pro, pero probablemente no haya viajado el código. No lo haré a través de esto, pero para aquellos interesados, aquí hay un “boceto” temprano que hice en CodePen cuando comencé a trabajar en él: vea la columna vertebral de JRGould (@JrGould) en CodePen. La interfaz para usar el progreso de la migración se crea utilizando modelos y vistas de la red troncal. Cada barra de progreso estaba representada por una vista y un modelo. Cada “etapa” de una migración (copia de seguridad, migración, medios de comunicación) también está representada por una vista y un modelo de columna vertebral que contiene y administra todas las barras de progreso individuales. Finalmente, la migración en su conjunto es una visión única y una red troncal de modelo que contiene y administra los pasos. No usamos troncal para ejecutar la migración, por lo que los modelos se tratan en lugar de modelos de vista y no usamos colecciones o ninguna de las características más concentradas de la troncal, como los módulos de enrutador o sincronización. De progreso para cada archivo de medios que migra, que migra, que migra, que migra, que migra, que migra, que migra, que migra, que migra, que migra, que migra, que, que migra, que migra, lo cual, que migra, lo cual, que migra, que migra, lo cual, que migra, que migra, lo cual, que migra, que migra, que, que migran, que migran, que, que migran, que, que migran, que, que migran, que, que migran, que, que migran, que, que migran, que migramos, lo cual migra, lo cual, que migra. Incluye miniaturas, por lo que con 10,000 archivos promedio, es decir, 30-50,000 barras de progreso que se agregan al DOM. Pensando que debe ser lo que estaba usando tanta memoria y disminuí la velocidad, me arrojé al código y restauré la forma en que mis vistas mostraron las barras de progreso para que solo unos pocos cientos de nudos se agregaran al DOM en cualquier momento. El descanso se eliminaría del domo y se ocultaría para que puedan ser interrogados. Para mi sorpresa y consistencia, esto no ayudó mucho.
El siguiente paso fue culpar a la columna vertebral.Lo usé porque está incluido en el administrador de WordPress, pero es viejo y probablemente estúpido y solo usa demasiada memoria debido a su estupidez geriátrica.Entonces reescribo la columna vertebral.Ok, tal vez no reescribí la columna vertebral.Pero escribí un reemplazo para mi implementación del modelo de columna vertebral y la visión, que los envolvió en un solo objeto.Este nuevo prototipo de modelo me permitió reutilizar mucho mucho que escribí para extender el modelo y ver la columna vertebral, incluidos algunos métodos básicos como establecer, obtener, encender, apagar y disparar, se veía así:
Mymodel = function (userProps) {var retir = {atributes: {}, eventos: {}, get: function (prop) {return this.attributes [prop]; }, set: function (prop, wave) {this.rigger (‘cambio’, prop, this.attributes [prop], wave); This.Rigger (‘Change:’ + prop, prop, this.attributes [prop], val); devolver esto.Attributes [prop] = wave; }, ON: function (evento, devolución de llamada) {if (! this.events [event]) {this.events [event] = []; } Esto. Eventos if (‘function’ === typeof llamado) {var index = llameBacks.indexOf (llamado); if (-1! == index) {callbacks.splici (index, 1); this.events [evento] = Callbacks; devolver; }} else {this.events [event] = [] return; }}, disparador: function (event) {var self = this; var args = array.prototype.slici.aply (argumentos, [1]); if (this.events [event] && this.events [event] .length) {var eventCallbacks = this.events .slice (); While (eventCallbacks.length) {var ev = eventCallbacks.shift (); Ev.apply (yo, args); }},}; If (‘object’ === typeof userProps) {_.each (userProps, function (prop, index) {ret [index] = prop;}, this); } Return ret; }; Eso tampoco funcionó. Esto en realidad parecía correr más lento que cuando usé el modelo y la visualización de la columna vertebral, por lo que abandoné la idea y seguí buscando al culpable.
Esta es la basura porque la cantidad de nodos Dome no parecía tener un gran efecto, y la columna vertebral no pareció inflar el uso de la memoria, comencé a investigar lo que realmente causa pérdidas de memoria en JavaScript.Leí algunos artículos escritos por desarrolladores inteligentes que yo y aprendí mucho sobre algo llamado colección de basura.Los motores modernos de JavaScript, como el Chrome V8, están muy optimizados y pueden hacer frente a mucho más que a sus predecesores (todos hemos visto las manifestaciones locas).Uno de los trucos que uso, aunque no es muy nuevo, se llama Bassbage Collection, que es una característica del motor JS que trata de liberar tanta memoria de cosas como variables y funciones que se han utilizado en un punto, pero ya no se usan.
Entonces, ¿qué tiene esto que ver con la columna vertebral? Las repeticiones evitan que sus objetos principales sean recolectados por basura. Esto se debe al hecho de que, aunque se llama una llamada inversa fuera del objeto principal, aún conserva su contexto. Considere lo siguiente: var myView = backbone.view.extem ({init: function () {this.model.on (‘Change’, this.render, this);}, render: function () { /* Render la vista */}}); Una vez que se inicializa esa visualización, registra una llamada inversa al evento de cambio de modelo, todo el objeto se excluye de la recolección de basura hasta que se puede recolectar el modelo que lleva la llamada. En la mayoría de los casos, esto está bien, pero ¿qué sucede si tiene 50,000 vistas relacionadas con 50,000 modelos que, a su vez, están relacionados con el modelo de etapa? Esto causará algunos problemas … JavaScript: Las fiestas prácticas fueron muy agradables para tener cada barra de progreso representada por su propio modelo y objetos de visualización. Esto permitió que cada componente de la interfaz utilizara el progreso de la migración para administrar, mientras que cualquier otra cosa reaccionaría correctamente a los cambios realizados a un componente de nivel inferior. Eliminar estos objetos significa que el modelo de etapa y la visualización ahora deben heredar las responsabilidades del modelo y la barra de progreso. No debería ser demasiado pedir que JavaScript se ocupe de una matriz de 50,000 objetos simples que no contienen ningún método, pero ¿cómo hace un seguimiento de los cambios realizados a estos objetos?
¿Sabía que en JS, cualquier variable que contenga un objeto, como una matriz u objeto, se transmite más bien por referencia que por valor? Aquí hay un ejemplo: funciones cambiantes (var1, var2) {var1 = 12 * 2; var2.foo = ‘cambiado’; var2 = ”; console.log (var1, var2); } Logthings de funciones (var1, var2) {console.log (var1, var2); } Var myVal = 12; Var myobj = {foo: ‘bar’, base: ‘bing’} logthings (myval, myobj); // 12, objeto {foo: “bar”, base: “bing”} changethings (myval, myobj); // 24, “” Logthings (myval, myobj); // 12, objeto {foo: “cambiado”, baz: “bing”} Esto nos permite hacer algunas cosas muy hermosas que no tienen un gran costo de memoria. Según el Rectify, llegamos con una matriz que contiene objetos de barra de progreso, se ve así: elementos: [{nombre: ‘image001.jpg’, tamaño: 1024, transferido: 0}, {nombre: ‘image002.jpg’,, Tamaño: 1288, transferido: 0}, …] También tenemos un objeto de “búsqueda” que me permite acceder a los objetos desde esa matriz después del nombre, sin sacrificar la funcionalidad de la matriz: itmslookup: {‘image001.jpg’: 0, ‘Image002.jpg’ 1, …} Ahora podemos usar el hecho de que JavaScript transmite objetos por referencia para simplificar cómo nuestro modelo realiza un seguimiento del estado de los objetos. Por ejemplo, aquí le mostramos cómo mostrar la adición de una barra de progreso al modelo de etapa:

AddItem: function (itemobj) {var item = _.clone (itemobj); // rompa la referencia a original obj this.get (‘elementos’) .push (elemento); this.get (‘itemslookup’) [item.name] = this.get (‘elementos’) .length – 1; This.Rigger (‘Elemento: agregado’, elemento); } Incluso si el elemento se clasifica en el método AddItem (gracias a la lima de la palabra clave), podemos transmitirlo directamente a cualquier llamada inversa que se vincule al evento del elemento: porque solo tiene un puntero al objeto clonado. Esto permitirá que cualquier llamada inversa que vincule a este evento no solo tenga acceso a leer el objeto, sino que puede modificarlo directamente sin tener que obtener la matriz completa del elemento o usar el objeto ElementS Plookup para acceder al elemento Matrix. Esto es muy útil para hacer cosas en la visualización, como crear el elemento DOM real: // setView.init () {… this.model.on (‘item: agregado’, function (item) {if (! Item item: . $ el) {item., this); Otro aspecto interesante de los indicadores de objetos en JavaScript es que un solo objeto puede estar contenido en cualquier número de otros objetos. Esto es útil para realizar un seguimiento de las cosas sin tener que hacer demasiado en términos de filtrado o clasificación. Por ejemplo, cuando una barra de progreso se marca como completa, eliminaremos su elemento del DOM y lo pondremos en una cola si tenemos que mostrarlo más tarde. Así es como se hace esto: // setView.init () {… this.model.on (‘item: completado’, function (item) {item. $ El.remove ();
Cómo mi JavaScript casi bloqueó su navegador y cómo lo arreglé
Tags Cómo mi JavaScript casi ha bloqueado su navegador y cómo L
homefinance blog