JavaScript Dom Modificación -- javascript campo con jquery campo con html camp codereview Relacionados El problema

JavaScript DOM modification


0
vote

problema

Español

Estoy pensando en el rendimiento de la modificación DOM.

De una manera perfecta, alteramos cada elemento, pero la modificación DOM es realmente pesada y alteramos muchos elementos al mismo tiempo congelado el navegador. No hice ninguna prueba de rendimiento, pero quiero saber si la segunda forma puede ser más poderosa.

En mi cabeza, la primera forma le pedirá al navegador que actualice la pantalla para cada div. Así que lógicamente, con la segunda forma, el navegador se actualizará solo una vez por inyección. ¿Es eso correcto?

html:

  <body>  <header></header>  <div id="container">     <div id="test1" alt="test1alt"></div>     <div id="test2" alt="test2alt"></div>     <div id="test3" alt="test3alt"></div>     <div id="test4" alt="test4alt"></div>     <div id="test5" alt="test5alt"></div>     <div id="test6" alt="test6alt"></div>     <!--[...200 more div]--> </div>  </body> <script>   

js primera forma: altere cada elemento

  $(document).ready(function() {     setInterval(function() {         var value;          $('#container div').each(function() {             if(randNum(0, 10) != 1) {                 return true;             }              value = randString();              if($(this).attr('alt') != value) {                 $(this).attr('alt', value);             }         });     }, 100); });   

js Second Way: Reescribir la base HTML e inyectarse cuando se modifique

  var myDOM = {};  function domConstruct(obj) {     $('> div', obj).each(function() {         myDOM[$(this).attr('id')] = $(this).attr('alt');     }); } function domAlter(id, value) {     if(myDOM[id] == value) {         return;     }      myDOM[id] = value;      return true; } function domUpdate(obj) {     var buf = '';      $.each(myDOM, function(id, value) {         buf += '<div id="'+id+'" alt="'+value+'"></div>';     });      obj.html(buf); }  $(document).ready(function() {     domConstruct($('#container'));      setInterval(function() {         var inject = false;          $.each(myDOM, function(id) {             if(randNum(0, 10) != 1) {                 return true;             }              if(domAlter(id, randString())) {                 inject = true;             }         });          if(inject) {             domUpdate($('#container'));         }     }, 100); });   

js utils funcions:

  function randNum(a, b) {     var argc = arguments.length;      if(argc == 1) {         return 1;        }      if(argc == 0) {         a = 0;         b = 2147483647;     }      return Math.floor(Math.random() * (b - a + 1))+a; } function randString() {     return Math.random().toString(36).replace(/[^a-z]+/g, ''); } </script>   
Original en ingles

I'm thinking about DOM modification performance.

In a perfect way, we alter each element but DOM modification is really heavy and alter many elements at same time froze the browser. I didn't make any performance tests but I want to know if the second way can be more powerful.

In my head, the first way will ask the browser to refresh the display for each div. So logically, with the second way, the browser will refresh only once per injection. Is that correct?

HTML:

<body>  <header></header>  <div id="container">     <div id="test1" alt="test1alt"></div>     <div id="test2" alt="test2alt"></div>     <div id="test3" alt="test3alt"></div>     <div id="test4" alt="test4alt"></div>     <div id="test5" alt="test5alt"></div>     <div id="test6" alt="test6alt"></div>     <!--[...200 more div]--> </div>  </body> <script> 

JS first way: alter each element

$(document).ready(function() {     setInterval(function() {         var value;          $('#container div').each(function() {             if(randNum(0, 10) != 1) {                 return true;             }              value = randString();              if($(this).attr('alt') != value) {                 $(this).attr('alt', value);             }         });     }, 100); }); 

JS second way: rewrite base HTML and inject when modified

var myDOM = {};  function domConstruct(obj) {     $('> div', obj).each(function() {         myDOM[$(this).attr('id')] = $(this).attr('alt');     }); } function domAlter(id, value) {     if(myDOM[id] == value) {         return;     }      myDOM[id] = value;      return true; } function domUpdate(obj) {     var buf = '';      $.each(myDOM, function(id, value) {         buf += '<div id="'+id+'" alt="'+value+'"></div>';     });      obj.html(buf); }  $(document).ready(function() {     domConstruct($('#container'));      setInterval(function() {         var inject = false;          $.each(myDOM, function(id) {             if(randNum(0, 10) != 1) {                 return true;             }              if(domAlter(id, randString())) {                 inject = true;             }         });          if(inject) {             domUpdate($('#container'));         }     }, 100); }); 

JS Utils funcs:

function randNum(a, b) {     var argc = arguments.length;      if(argc == 1) {         return 1;        }      if(argc == 0) {         a = 0;         b = 2147483647;     }      return Math.floor(Math.random() * (b - a + 1))+a; } function randString() {     return Math.random().toString(36).replace(/[^a-z]+/g, ''); } </script> 
        

Lista de respuestas

2
 
vote

Si tiene problemas de rendimiento, entonces creo que primero debe intentar perforar su script, para identificar qué funciones se ejecutan lentamente. Hay perfiles incorporados en la mayoría de las consolas de scripting.

Con respecto a su pregunta: Dado que su código no debe desencadenar ningún repintado, creo que el método 1 estaría bien. Desafortunadamente, no he podido reproducir el problema en mi máquina, por lo que no puedo confirmar esta respuesta.

Para mejorar el rendimiento, supongo que podría probar lo siguiente:

  • en lugar de usar setInterval , considere la encadenamiento setTimeout Llamadas, para que el navegador permanezca responsive.
  • intente eliminar su biblioteca, para usar JavaScript nativo. Parece que no necesita nada más que getElementById , getElementsByTagName4 , 99887766555443310 99887766555443311 - Así debería poder poder Para eliminar de forma segura cualquier biblioteca por encima.
  • Posiblemente caché la recuperación de todo el created_vm_1 = UsdDBActions().create_ci(vm_1, vm_payload(validated_data, vm_1)) created_vm_1 = UsdDBActions().create_ci(vm_2, vm_payload(validated_data, vm_2)) 2 , como solo necesita realizarlo una vez.

Así que básicamente, intente ejecutar lo siguiente (no probado) en created_vm_1 = UsdDBActions().create_ci(vm_1, vm_payload(validated_data, vm_1)) created_vm_1 = UsdDBActions().create_ci(vm_2, vm_payload(validated_data, vm_2)) 3 :

  created_vm_1 = UsdDBActions().create_ci(vm_1, vm_payload(validated_data, vm_1)) created_vm_1 = UsdDBActions().create_ci(vm_2, vm_payload(validated_data, vm_2)) 4  
 

If you have performance issues, then I believe you should first try and profile your script, to identify which function(s) run slowly. There are profilers embedded in most scripting consoles.

Regarding your question: since your code should not trigger any repaint, I believe that method 1 would be fine. Unfortunately, I have not been able to reproduce the issue on my machine, so cannot confirm this answer.

To improve performance, I suppose you could try the following:

  • Rather than using setInterval, consider chaining setTimeout calls, so that the browser remains responsive.
  • Try and remove your library, to use native Javascript. It looks like you do not need anything more than getElementById, getElementsByTagName, getAttribute and setAttribute - so should be able to safely eliminate any library overhead.
  • Possibly cache the retrieval of all the div, as you only need to perform it once.

So basically, try and run the following (untested) on window.onload:

function update() {     var delay = 100;     var container = document.getElementById("container");     var divs = container.getElementsByTagName("div");      function updateDivs() {         for (var ii = 0; ii < divs.length; ii++) {             var div = divs[ii];             if (randNum(0, 10) == 1) {                 var value = randString();                 if (div.getAttribute("alt") != value) {                     div.setAttribute("alt", value);                 }             }         }         setTimeout(arguments.callee, delay);     }      updateDivs(); } 
 
 
 
 

Relacionados problema

2  Limpiando una galería de imágenes rotativas  ( Cleaning up a rotating image gallery ) 
He creado una pequeña galería de imágenes para la web. Me propuse querer 3 cosas. 1. Toda la galería tenía una capacidad de respuesta a nivel básica. 2. La ga...

1  Enviando la página web actual a un sitio de marcadores  ( Submitting the current webpage to a bookmarking site ) 
Me gustaría escuchar sus comentarios sobre el siguiente enlace que permite a los usuarios agregar un enlace a un sitio web. Leí que join()5 es sugerido en...

-1  Buscar una transacción  ( Search for a transaction ) 
¿Podría tener una revisión rápida de mi código para ver si está a salvo de la inyección de SQL, etc. y sugerir alguna enmienda? <html> <head><title>Retriev...

3  Bootstrap: HTML Markup Review  ( Bootstrap html markup review ) 
Estoy usando bootstrap para un proyecto de front-end. Quisiera comentarios sobre mi marcado HTML. He pasado bastante tiempo puliéndolo, y siento que es algo "...

8  Div en la lista desordenada - buena práctica?  ( Div in unordered list good practice ) 
Quiero hacer un formulario que se parece a esto: public interface IAds { void ShowVideoAd(); void PreLoadVideoAd(); bool IsAdAvailable(); } 3...

3  Construyendo una tabla HTML utilizando JavaScript  ( Building an html table using javascript ) 
¿Una forma más legible para hacer esto? renderHtmlTable(function(tableItems) { var tableArray,_i,item,_len; tableArray = ['<table id = sampleTable ><...

2  Animaciones de la línea de tiempo  ( Timeline animations ) 
Hice recientemente esta línea de tiempo del campus para mi universidad. Al ver la línea de tiempo en un dispositivo móvil (no una tableta), la barra de nave...

3  MVC correcto en CodeIgner  ( Correct mvc in codeigniter ) 
En mi proyecto CODIGNITERITE, tengo un controlador de inicio de sesión que carga esta vista: autoConnect.py2 El controlador: autoConnect.py3 , FUNCIÓN:...

1  Sitio web construido con HTML y CSS  ( Website built with html and css ) 
Por favor revise esto: 99887766555443312 ...

6  Vuelos divectores de división vue.js  ( Resizable split divs vue js ) 
Acabo de empezar a desarrollar la aplicación web (VUE.JS) para mi empresa por alrededor de 1-2 meses. Por lo tanto, mi conocimiento y experiencia en HTML, CSS...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos