¿Puedo desactivar la optimización para que las variables dentro del alcance de los cierres no estén "optimizadas"?

11

Como un subproducto de la optimización del código realizada por los navegadores modernos, mientras se depura, no se puede "ver" todas las variables que "objetivamente" están dentro del alcance. Esto es bien conocido y se ha abordado en una pregunta anterior aquí sobre SO . Esta característica, aunque sin duda útil en la producción, me molesta mucho durante el desarrollo, me ralentiza (eso debería ser obvio).

Ahora mi pregunta es, ¿hay alguna forma de desactivar este comportamiento? ¿Puedo editar algún archivo de configuración, o hay un complemento de navegador, o tal vez hay una "versión de compilación especial para desarrolladores" del ejecutable del navegador? Me encanta escribir mi código en la consola de inmediato cuando escribo un código nuevo, por lo que esto realmente me está molestando.

visualSummaryIffalseConsoleLog

ACTUALIZAR / EDITAR

Aquí hay una solución parcial, crédito a Paul1365972.

Debe iniciar el navegador Chrome desde la línea de comandos, con opciones especiales, como esta:

  1. Cierra Chrome completamente
  2. Ejecute Chrome desde la consola con "C:/Program Files (x86)/Google/Chrome/Application/chrome.exe" --js-flags="--allow-natives-syntax" Windows para otros sistemas operativos similares.
  3. Abra la consola del desarrollador y ejecútela "%GetHeapUsage()". Si inició correctamente Chrome con la opción, se registrará un número en la consola; de lo contrario, obtendrá un error de sintaxis.

Con este indicador de línea de comando, puede 'hablar con el motor V8' con comandos que comienzan %, que son errores de sintaxis en JavaScript simple. Se dio una lista de comandos V8 disponibles de este tipo en la respuesta de Paul .

Hay %NeverOptimizeFunction()en esa lista, que es algo que se parecía a lo que tendría que llamar y terminar con eso. Desafortunadamente, esa función no hace lo que esperaba, como se demuestra en la siguiente captura de pantalla.

lorem aún no está definido

(((El otro enlace de la respuesta de Paul (módulo de nodo v8-natives) no es importante para nosotros aquí en este contexto. Todo lo que hace es envolver las frases de función "%" para que el código no se bloquee) navegadores que no son v8.)))

(((Recuerdo un momento en que esto funcionó (cuando esta optimización aún no se inventó / implementó). No sé cuánto tiempo atrás. ¿Diez años? ¿15 años? Algo así. ¿Cuál fue la última versión de Chrome? cualquiera) y ¿cuál fue la última versión de Firefox (más seguro aquí de que existe) dónde podría hacer? No le dará la recompensa, pero le dará un voto positivo, si lo sabe y lo publica como respuesta .)))

LA SOLUCIÓN

GRACIAS PETR SRNICEK

arreglo hacky

NUEVA PREGUNTA

Si bien la solución de Petr ayuda mucho, no es perfecta. Esta pregunta se está haciendo demasiado larga, así que publiqué una nueva pregunta sobre cómo se puede mejorar la solución de Petr. (Por supuesto, podría editar esta pregunta aquí, pero eso sería "poco histórico", si sabes a lo que me refiero).

Mathheadinclouds
fuente
consecuencias no deseadas, capitulo carpa y nadie. Esta optimización tiene un efecto negativo en mi estilo de codificación. Me encuentro usando el bucle for antiguo (en lugar de .map, .forEach, .reduce) más de lo que lo haría de otro modo, para evitar evitar este problema.
mathheadinclouds
La v8-nativesbiblioteca simplemente envuelve las% llamadas importantes en el código en una biblioteca simple que debería estar noopsen un navegador o nodo que no se inició en el indicador especial --allow-natives-syntax ..
Nathanael
Ejecuté algunas pruebas, la función 'bodyOnLoad' no está optimizada de todos modos; así que usar los comandos internos para intentar forzarlo a que no se optimice no hace nada.
Nathanael
@Nathanael: La llamada importante es %NeverOptimizeFunction(foo)que acabo de llamarlo también para bodyOnload, "solo porque", pensando "bueno, no va a doler". El problema es que fooNO se desestimula de la manera que esperaba. La variable loremes invisible. Digamos que quiero escribir el código que debe entrar en la función foo. En lugar de escribirlo en mi editor de texto, lo escribo en la consola de desarrollo (mientras el depurador está sentado en foo), veo si hace lo que quiero y luego lo copio / pego desde la consola a mi editor de texto. Así es como me encanta trabajar. Y no puedo. Por la optimización. ¿Consíguelo?
mathheadinclouds
1
Pasé varios nuestros experimentando con varios --js-flags(incluidos varios relacionados con TurboFan ), así como con varios comandos nativos de V8 antes de que Paul1365972 publicara su respuesta, pero no pude lograr el comportamiento deseado. Creo que este enfoque podría ser un callejón sin salida. Puede valer la pena agregar una [v8]etiqueta a esta pregunta. Alguien con un profundo conocimiento del funcionamiento interno de V8 podría aclarar si este es el camino a seguir o quizás señalarle en la dirección correcta.
Petr Srníček

Respuestas:

2

Usted puede obtener acceso a todas las variables envolviendo la declaración depurador en una eval como esto: eval("debugger;");. Sin embargo, esta solución hacky agrega otra función anónima a la pila de llamadas y obviamente no sirve para los puntos de interrupción que se configuran manualmente en DevTools.

Esta no parece ser una muy buena solución, pero como es la única que logra el comportamiento deseado hasta ahora, la publico como respuesta.

Petr Srníček
fuente
me sorprende que esto funcione. Sabes, intenté escribir eval ("lorem"), y eso dio el mismo error "lorem no está definido". No tiene mucho sentido para mí que escribir eval ("lorem") en la consola (mientras está en la declaración del depurador en la función foo) debería hacer algo diferente de lo que está haciendo eval ("depurador"): espere, imprima "ipsum" a la consola Pero son muy diferentes. Extraño.
mathheadinclouds
Ese es un trabajo interesante. Es un poco hacky, ya que no puede salir de la declaración del depurador (solo tiene que cambiar manualmente al archivo de origen) de lo contrario, perderá toda la pila y volverá a la función que llamó eval; dejándote la pila reducida sin el otro contexto.
Nathanael el
uno puede modificar este truco así: en lugar de eval ("depurador"), coloque solo eval (""), pero muchos de ellos, distribuidos por todo el código, en todas partes donde cree que podría desear un 'punto de interrupción extendido'. A continuación, puede establecer un punto de interrupción (con las herramientas de desarrollo) donde se encuentra una de esas sentencias eval (''), y una vez que se detiene allí, "entra". Estoy considerando escribir un pequeño transpilador (una gran palabra para una pequeña cosa que estoy haciendo) poniendo esas declaraciones al comienzo de cada función. stackoverflow.com/questions/59159996/…
mathheadinclouds
Intenté reemplazar eval ("depurador") por eval (); depurador, y obtuve resultados diferentes, dependiendo del uso de Firefox o Chrome. i.stack.imgur.com/wy5WT.png
mathheadinclouds
3

Google Chrome utiliza el motor V8 JS, puede habilitar las llamadas nativas con el indicador --allow-natives-syntax, esto expone muchas funciones de depuración útiles (lista completa aquí ) como la que está buscando:% NeverOptimizeFunction () . Sin este indicador, estas llamadas serían una sintaxis ilegal, así que tenga cuidado al implementar (o use la biblioteca v8-Natives ).

Para habilitar esta función, solo abra Chrome con --js-flags = "- allow-natives-syntax" (solo use esto para la depuración de sitios web confiables, ya que esto puede dar acceso de código js no confiable a cosas que realmente no desea que haga) tener acceso a).

Paul1365972
fuente
gracias. Por favor lea mi pregunta actualizada. Parece bastante probable que tenga la solución aquí, pero necesito más aclaraciones para que funcione. Si esto funciona, seguro que mereces la recompensa.
mathheadinclouds
tl; dr use --js-flags = "- allow-natives-syntax" en su lugar. Para habilitar la función, el V8 JS-Engine debe iniciarse con el indicador --allow-natives-syntax, sin embargo, no puede iniciarlo directamente, este es un trabajo de cromos. Entonces, tienes que decirle a Chrome que arranque el motor con la bandera, ¿cómo lo haces? Simplemente pase la bandera del motor mencionada a través de --js-flags = <your flag here> a chrome.
Paul1365972
no Solo intenté eso una vez más, para ser uno del lado seguro. Lo he intentado tanto --allow-natives-syntaxy --js-flags="--allow-natives-syntax"varias veces como "lo que escribo después de 'chrome' en la consola del sistema operativo". Si no hubiera intentado todo esto yo mismo, yo también pensaría que un error tipográfico es la explicación más probable. Hice otra captura de pantalla. i.stack.imgur.com/7cpPP.png ¿ Ve un error tipográfico? Por favor, dame una respuesta honesta: ¿acabas de "leer y entender el artículo" (para ser claros, no hay nada de malo en eso, si no reclamas más), o has intentado todo eso en tu máquina? thx
mathheadinclouds
solo una suposición: ¿podría ser que no inicio el ejecutable de Chrome con esa opción, sino que compilo las fuentes de C ++ de Chrome (o lo que sea) con esa opción?
mathheadinclouds
1
Es extraño, lo acabo de probar y funcionó bien, no es necesario compilarlo. Simplemente escribiré exactamente lo que hice para que no haya malentendidos. 1. Cierre Chrome completamente 2. Ejecute Chrome desde la consola con "C: / Archivos de programa (x86) /Google/Chrome/Application/chrome.exe" --js-flags = "- allow-natives-syntax" 3. Abra consola de desarrollador y ejecute "% GetHeapUsage ()" para probar si todo funciona
Paul1365972
0

Realmente espero que esta pregunta tenga una respuesta REAL. Lo que sigue no es una respuesta real, es improvisado. Escribí una herramienta de ayuda con la que puedes crear un código de ayuda estúpido del formulario if (false) { console.log(variables, from, closures); }(ver captura de pantalla en cuestión) usando análisis estático: pegas tu código, se crea la declaración estúpida, puedes copiarlo, luego no necesitas para escribirlo No sé si eso ayuda mucho, ya que toda esta copia y pegado también lleva tiempo, pero eso es lo que obtuve.

captura de pantalla

violín

Mathheadinclouds
fuente