Dom iterando causando la mitad de renderizado de webview

Im usando android para abrir un archivo web local y luego iterar la dom y aplicar algunos cambios, pero mientras iterating la webview stop para hacer la página en alguna parte aleatoria, mira el gif:

Lo que ya hice

var elements = document.querySelectorAll("P"); for(var i = 0; i < elements.length;i++) { //just iterating at the gif im chaging //but i tried without changing, just iterating and the result still the same } 

Y ahora para evitar los problemas de procesamiento en cada cambio de dom, creé un documento y cambiar el dom en él (o simplemente iterar) y devolver su html al documento principal

 var x = document.getElementById('contentRoot'); //getting the element root from the DOCUMENT (not the fragment) var frag = document.createDocumentFragment(); //creating fragment var contentRoot = document.createElement("DIV"); // creating a new contentRoot html element contentRoot.id = 'contentRoot'; contentRoot.innerHTML = x.innerHTML; frag.appendChild( contentRoot ); var elements = frag.querySelectorAll("P"); for(var i = 0; i < elements.length;i++) { //just iterating at the gif im chaging //but i tried without changing, just iterating and the result still the same } document.body.innerHTML = frag.getElementById('contentRoot').innerHTML; //returning the edited html from the fragment so the webview will render/reflow just once everything not for each change 

¿Hay una manera de mantener la representación normal sin "cortarla"?

PS: im usando la función para iterar en el window.onload, por lo que sólo comienza DESPUÉS de todos los dom se carga en el navegador, ¿por qué seguir cortándolo? Y sólo volver a hacer al final de la iteración?

Introduzca aquí la descripción de la imagen

El problema con JavaScript es que mientras JavaScript está en ejecución, toda la página está congelada y no renderiza nada. Si usted tiene un muy grande para el funcionamiento del lazo, esto explica su edición.

La mayoría de los navegadores de computadoras de escritorio renderizarán el desplazamiento al mismo tiempo que renderizar la página (apuesto a que si ejecuta esta página en un navegador de escritorio, ni siquiera te permitiría desplazarte).

Sin embargo, la mayoría de los dispositivos móviles, en un esfuerzo por verse rápidos y lisos, harán que el desplazamiento se separe de la propia página. El problema con esto es que si JavaScript está atascado ejecutando un bucle muy largo, el usuario será capaz de desplazarse, pero la página no renderizará por delante de ellos, llegando finalmente a esta zona en blanco donde todavía no se ha procesado nada.

Apuesto a que si has intentado acercar la página mientras la función está en ejecución, se vería muy borrosa, porque no se está realizando ninguna renderización.

Una forma de solucionar este problema es utilizando temporizadores o la API requestAnimationFrame.

requestAnimationFrame es compatible con casi todos los navegadores modernos. Lo que hace es poner código hasta que el siguiente fotograma se procese y se utiliza comúnmente para hacer animaciones suaves.

Usando esta API, he creado el siguiente código …

 var elements = document.querySelectorAll("P"); var i = 0; var j = elements.length; function iterate(){ // this acts as the body of your for loop // do stuff with the current selected DOM element here... // select dom element with elements[i] i++; if(i < j){ requestAnimationFrame(iterate); } } iterate(); 

Ahora, el código anterior ejecuta una iteración de su bucle for cada marco de animación. Suponiendo que su dispositivo funcione a 60fps, esto hace un máximo de 60 iteraciones por segundo.

Para combatir esto y hacerlo aún más rápido, podemos reemplazar requestAnimationFrame(iterate) con el código alternativo window.setTimeout(iterate, 0) , que esencialmente le dice al navegador que haga una iteración cada milisegundo que pueda, mientras pueda procesar la página . Sin embargo, este método puede reducir la velocidad de fotogramas. (Para un navegador móvil que maneja scrolling separado como el tuyo, sin embargo, el framerate no debería ser un problema)

Editar:

Cuando ejecuté un bucle bastante simple, pero largo, en mi navegador de escritorio con mi método anterior, logré una 60fps medida con JavaScript, con alrededor de 150 a 200 iteraciones por segundo. Si estás en el móvil, tus resultados probablemente serán más lentos.

Sugerencia alternativa:

Si desea utilizar una API pre-construida para este tipo de cosas, hay una por ahí que se ve muy bien. El OP encontró uno llamado Turboid, que le permite gestionar este tipo de bucle más fácilmente. http://turboid.net/artikel/real-loops-in-javascript.php

Tal vez trate de esperar para el siguiente marco de javascript, puede ser útil cuando se trata de una gran cantidad de dom manipulación:

 setTimeout(function(){ document.body.innerHTML = frag.getElementById('contentRoot').innerHTML; }, 1 ); 
  • Autenticación NTLM en WebView sin proporcionar contraseña explícitamente
  • Cómo desactivar el efecto de rebote (tono azul cuando se desplaza hasta el final) de la vista web en android?
  • NullPointerException en webview.java (android.webkit.WebView $ PrivateHandler.handleMessage)
  • Desbordamiento de iframe de Webview
  • Cómo depurar javascript en webview en android
  • Android webview y loadData, ¿puedo obtener el botón de regreso para volver al contenido generado?
  • Obtener valor href de la etiqueta de anclaje en Android WebView cuando se hace clic en el enlace
  • Inyección de puente Javascript en WebView
  • ¿Por qué mi WebView no llena el ancho completo de mi pantalla?
  • WebViewClient que no llama shouldOverrideUrlLoading
  • Cómo ocultar unhide webview en android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.