Una de las principales cosas a hacer cuando se optimiza una web es chequear que no hayan scripts en el <head> de los cuales se puedan prescindir.
Nota: Esto lo podemos hacer si fuese necesario para la optimización, pero el mismo javascript.info nos informa que no es la mejor manera, ya que de una u otra el script va a tener que ser descargado. Si la idea es que el navegador lea el script luego que cargue el DOM, JavaScript propone que se usen los parámetros defer o async.
Creo que muchos temas colocan los scripts al final de cuerpo de la página para que los scripts que no son necesario no interrumpan el renderizado porque por alguna razón o motivo no es buena práctica que añadan atributos o quizás WordPress no lo permite.
En todo caso, de ser necesario, aquí he analizado qué es lo que puedo hacer si encuentro un script en el head y quiero moverlo al footer.
jQuery
La librería de JS jQuery es uno de los scripts que entra en consideración para no ser movido al final de la página. Esto es así porque jQuery es una librería de la que dependen otros scripts y colocarlo al final podría traer problemas. A mi mismo me ha pasado en machoalfa.org que cuando se carga en dispositivos móviles hay pestañeo en el desplegable del menú flotante, esto es así porque tengo (para el momento de escribir esto, ya lo arreglaré en algún momento) el jQuery al final de la página y es necesario ya que ese menú desplegable está hecho con JS.
No obstante, la norma algo aceptada pero no lo correcto del todo es que se mueva este script al final pero haciendo luego pruebas, si no pasa nada entonces se deja, si rompe algo entonces se regresa al inicio.
El script para mover scripts
La metodología que estoy usando para mover un script desde el inicio de la página al final de la misma es colocando un código en el archivo functions.php del tema secundario de wordpress.
Se usa wp_enqueue_scrips() en conjunto con wp_register_enqueue.
Estas funciones incorporan el script en los códigos de WordPress, si se desean modificar entonces hay que quitarlos y volverlos a poner.
Quiero mover el script bootstrap.bundle.js del header al final del body.

El tema tiene una versión minificada el archivo: bootstrap.bundle.min.js. Ese es el que está insertando en la cabecera del tema.

El código queda de la siguiente manera:
QUITAR SCRIPTS Y VOLVERLOS A CREAR CON NUEVOS PARÁMETROS
function brigzen_deregister_scripts() {
wp_deregister_script( 'bootstrap-js-bundle' );
}
add_action( 'wp_enqueue_scripts', 'brigzen_deregister_scripts' );
function brigzen_enqueue_scripts() {
wp_enqueue_script( 'bootstrap-js-bundle', get_template_directory_uri() . '/vendor/ayecode/wp-ayecode-ui/assets/js/bootstrap.bundle.min.js', array('jquery-core','jquery-migrate','select2'), '4.5.3', true );
}
add_action( 'wp_enqueue_scripts', 'brigzen_enqueue_scripts' );
Creo una función, aquí la llamé brigzen_deregister(), que ejecuta la función wp_deregister_script() con el o los script que quiero desregistrar.
Luego incluyo esa función para que sea tomada en cuenta por wp_enqueue_scripts.
Luego hago todo a la inversa, vuelvo a registrar el script usando wp_enqueue_script. Pero esta vez tengo que suministrar todos los parámetros nuevamente. Se añade el id, la url con ayuda de la función get_template_directory_uri(), luego el siguiente parámetro es una array donde se colocan los id de los scripts que son dependencia.
En este caso los script jquery-core y jquery-migrate son script que están registrados en el core de WordPress y en el código del script wp_deregister_scrip() está desabilitado los scripts asociados a jQuery, habría que entrar en el core, encontrar el script y quitar ese dependencia de la lista de scripts desabilitados. Aún cuando se podría hacer, no es ideal, en la próxima actualización el código se reescribiría y dejaría eso como estaba.
Si se quiere quitar jQuery de header y pasarlo al footer lo único que conozco es pasar la ejecución de todo el wp_enqueue_scripts para que no se ejecute en el loop de wp_head(), si no en wp_footer().
//SCRIPT PARA MOVER LOS JAVASCRIPT AL FOOTER
function scripts_footer() {
remove_action('wp_head', 'wp_print_scripts');
remove_action('wp_head', 'wp_print_head_scripts', 9);
remove_action('wp_head', 'wp_enqueue_scripts', 1);
add_action('wp_footer', 'wp_print_scripts', 5);
add_action('wp_footer', 'wp_enqueue_scripts', 5);
add_action('wp_footer', 'wp_print_head_scripts', 5);
}
add_action( 'wp_enqueue_scripts', 'scripts_footer' );
//FIN DEL SCRIPT PARA MOVER LOS JAVASCRIPT AL FOOTER
El caso especial de moverlo de sitio
Para mover un script que está en el head de la página y que a su vez le voy a cambiar los parámetros, incluso si no, entonces debo tener en cuenta que si aplico un denqueue quizás lo esté sacando de cola pero no lo esté removiendo del registro:
Las instrucciones de WordPress con respecto a esto en el apartado sobre wp_enqueue_script() dice lo siguiente: «If you try to register or enqueue an already registered handle with different parameters, the new parameters will be ignored. Instead, use wp_deregister_script() and register the script again with the new parameters.»
Esto me hace entender que al usar deregister entonces, a parte de eliminar el register también lo saco del enqueue, es decir, no me hace falta aplicar el denqueue. Asumo que si aplico el denqueue entonces lo saco de cola pero se mantiene registrado.
Mover un script que no puede deregistrarse
Hay script como los de jQuery que están bloqueados para quitarlos del registro. Pero aún así, quiero poder tener la facultad de moverlos al final de la página si así lo requiero. No tengo una manera, estos scripts están bloqueados para usarse con el deregister. Entonces para pasarlos solo me queda el gancho remove_action con add_acction. Pero esto pasaría todos los scripts al footer.
Eliminate render blocking resources
Procedimiento
La mayoría de lo que causa este problema es el CSS. Los scripts parecen estar arrojando como resultado que se mueven al footer solo y solo si no rompen el código pero que lo mejor es dejarlos en el header.
El razonamiento es el siguiente, el tema debe estar optimizado, si lo está entonces los scripts deberíamos encontrarlos en el footer. Y si encontramos algunos scripts en el header es que el creador del tema los dejó allí para el correcto renderizado.
Si el tema no está bien hecho, eso lo determinamos podría ser observando que todos los scrips están en el header o con algunos otros criterios, entonces podemos hacer dos cosas:
- Mover todos los scripts al footer y hacer prueba de funcionamiento, si todo funciona correctamente se dejan allí. Con las librerías jQuery esto no lo recomiendan. No obstante creo que si se cargan antes del script del cual dependen, aún en el footer, no debería pasar nada. Solo no es aplicable si al mover todos los scripts algo se rompe, que suele pasar por meter a jquery en eso.
- Mover los scripts seleccionando los que vamos a mover, solo que esto se hace con wp_deregister_scrips y luego wp_enqueue_script, pero el primero tiene negado los jQuery. Esto quiere decir que podríamos mover cualquiera menos el jQuery.
- La tercera opción es cambiar los parámetros del script para que se cargue de manera diferida o asíncrona, de esta manera no es necesario mover los scripts al footer.
Por eso creo que respecto a esto si tengo que mover jQuery al footer, entonces los muevo todos. Me pregunto en qué situación podría mover jQuery al footer y tener que dejar otro script en el header, sería la panacea. Estaría obligado a dejar jQuery en el header porque de moverlo, los muevo a todos.
No he probado y no quisiera pensar meterme en el core del WordPress y quitar la id del jQuery que deseo mover de los jQuery que están inhabilitados.
NOTA:
Este artículo lo hice fundamentado en que la mejor práctica para resolver el problema de los scripts es moverlos al footer. Ahora veo que no. De hecho, si están en el footer debería pasarlos al header.
¿Por qué?
Porque en el header puedo colocar fácilmente el parámetro <defer> o <async>. Al agregar estos parámetros va a suceder lo mismo que si estuvieses al final del cuerpo. Pero con la salvedad de que no van a empezar a descargarse cuando el navegador llegue hasta allí, sino que se descargarán en paralelo con el index.
El código para mover todos los scripts al final del <body>.
Nota el 3 de agosto:
Hay casos donde el procedimiento correcto no funciona para mover, editar o eliminar un script. Esto ya se escapa de las manos de quien está haciendo ajustes. Entonces en estos casos es buena práctica consultar con el desarrollador del tema. En un caso ejemplo, estaba practicando moviendo scripts con el tema Directory Starter, pero el script font-awesome era imposible alterarlo. La única manera que se quitaba era deregistrando el script que lo usaba como dependencia. En una consulta que le hicieron al autor del tema, él menciona que el script es cargado por un plugin (imagino que lo tiene integrado) imprescindible para el uso del tema. Ya no me quedó ganas de ir a los archivos de ese complemento a seguir indagando.