Como dividir JS por páginas con wp_enqueue_script condicional en WordPress

Contents

Introducción

Dividir y cargar archivos JavaScript por página en WordPress es una técnica esencial para mejorar el rendimiento, reducir el peso de las páginas y minimizar la ejecución de código innecesario. En este tutorial se muestra con todo lujo de detalles cómo usar wp_register_script y wp_enqueue_script de forma condicional, cómo pasar datos de PHP a JS, estrategias de versionado y cómo añadir atributos async/defer cuando haga falta. Incluye ejemplos prácticos listos para colocar en functions.php o en un plugin personalizado.

Por qué cargar JS por página (beneficios)

  • Menos bytes transferidos: solo se descarga lo que la página realmente necesita.
  • Menos procesamiento en el cliente: menor tiempo de ejecución y mejor experiencia de usuario.
  • Mejor caché: archivos estáticos con versionado permiten un caching eficiente.
  • Orden y mantenimiento: scripts separados por responsabilidad facilitan el desarrollo y las pruebas.

Fundamentos: hooks y funciones clave

  • Action hook principal: wp_enqueue_scripts para frontend, admin_enqueue_scripts para admin, login_enqueue_scripts para login.
  • Registrar vs Encolar: wp_register_script permite definir nombre, ruta, dependencias, versión y si se carga en footer wp_enqueue_script encola para impresión.
  • Condicionales: funciones como is_page(), is_single(), is_front_page(), is_singular(post_type), is_admin(), get_post_type(), get_queried_object() permiten decidir cuándo encolar.
  • Versionado: pasar filemtime() del archivo evita problemas de caché en desarrollo/producción.

Buenas prácticas (resumen)

  • Usar wp_register_script para declarar y luego encolar según condición.
  • Cargar scripts en el footer cuando sea posible (último parámetro true).
  • Declarar dependencias correctamente (por ejemplo, [jquery]).
  • Usar filemtime() para versión en entorno de desarrollo usar versionado estático o digest en producción.
  • Minificar y agrupar en build step (Webpack, Vite, Rollup) y aprovechar HTTP/2 o concatenación según infraestructura.
  • Pasar datos PHP a JS con wp_localize_script o wp_add_inline_script.

Ejemplo 1: Encolar un script solo en una página concreta

En este ejemplo se encola un archivo javascript llamado promo.js únicamente en la página con slug promocion. Pegar en functions.php o en un plugin.

add_action(wp_enqueue_scripts, function() {
    // Solo en la página con slug promocion
    if ( is_page(promocion) ) {
        wp_register_script(
            theme-promo, // handle
            get_stylesheet_directory_uri() . /js/promo.js, // src
            array(), // dependencias
            filemtime( get_stylesheet_directory() . /js/promo.js ), // versión usando filemtime
            true // cargar en footer
        )
        wp_enqueue_script(theme-promo)
    }
})

Ejemplo 2: Encolar por tipo de post y con dependencias

Si necesitas cargar un script solo para un CPT (custom post type) y dependiente de jQuery:

add_action(wp_enqueue_scripts, function() {
    if ( is_singular(producto) ) {
        wp_register_script(
            producto-gallery,
            get_template_directory_uri() . /assets/js/producto-gallery.js,
            array(jquery),
            1.0.0,
            true
        )
        wp_enqueue_script(producto-gallery)
    }
})

Ejemplo 3: Formulario de contacto – AJAX y wp_localize_script

Un caso típico: solo la página de contacto necesita el JS que maneja AJAX. Se mostrará cómo registrar, encolar, y pasar el admin-ajax URL y un nonce.

add_action(wp_enqueue_scripts, function() {
    if ( is_page(contacto) ) {
        handle = contact-form
        src = get_stylesheet_directory_uri() . /js/contact-form.js
        path = get_stylesheet_directory() . /js/contact-form.js

        wp_register_script(handle, src, array(jquery), filemtime(path), true)
        wp_enqueue_script(handle)

        // Pasar datos seguros a JS
        wp_localize_script(handle, ContactFormData, array(
            ajax_url => admin_url(admin-ajax.php),
            nonce    => wp_create_nonce(contact_form_nonce)
        ))
    }
})

// Callback del AJAX (ejemplo)
add_action(wp_ajax_nopriv_send_contact, handle_send_contact)
add_action(wp_ajax_send_contact, handle_send_contact)
function handle_send_contact() {
    check_ajax_referer(contact_form_nonce, security)

    name = sanitize_text_field(_POST[name] ?? )
    email = sanitize_email(_POST[email] ?? )
    message = sanitize_textarea_field(_POST[message] ?? )

    // Lógica de envío (ejemplo)
    wp_send_json_success(array(message => Mensaje recibido))
}
// Archivo: js/contact-form.js
jQuery(function(){
    (#contact-form).on(submit, function(e){
        e.preventDefault()
        var data = {
            action: send_contact,
            security: ContactFormData.nonce,
            name: (#name).val(),
            email: (#email).val(),
            message: (#message).val()
        }
        .post(ContactFormData.ajax_url, data, function(resp){
            if (resp.success) {
                alert(resp.data.message)
            } else {
                alert(Error)
            }
        })
    })
})

Ejemplo 4: Cargar un script solo en la home y con filemtime para versionado

add_action(wp_enqueue_scripts, function() {
    if ( is_front_page() ) {
        file = get_template_directory() . /assets/js/home-slider.js
        wp_enqueue_script(
            home-slider,
            get_template_directory_uri() . /assets/js/home-slider.js,
            array(),
            file_exists(file) ? filemtime(file) : 1.0.0,
            true
        )
    }
})

Ejemplo 5: Añadir atributos async o defer a un script específico

WordPress no ofrece parámetros nativos para async/defer en wp_enqueue_script, pero se puede filtrar la tag generada con script_loader_tag.

add_filter(script_loader_tag, function(tag, handle, src) {
    // Solo modificar el handle analytics
    if ( analytics === handle ) {
        // Añadir defer (o async según necesidad)
        return str_replace(type=text/javascript, type=text/javascript defer, tag)
    }
    return tag
}, 10, 3)

// Ejemplo de registro
add_action(wp_enqueue_scripts, function() {
    wp_enqueue_script(analytics, get_template_directory_uri() . /js/analytics.js, array(), 1.0.0, true)
})

Ejemplo 6: Scripts en el área de administración solo para ciertas pantallas

En el admin, el hook admin_enqueue_scripts recibe como parámetro el hook_suffix otra forma es usar get_current_screen(). A continuación un ejemplo para cargar scripts solo en el editor de un CPT llamado evento.

add_action(admin_enqueue_scripts, function(hook_suffix) {
    screen = get_current_screen()
    if ( screen  screen->post_type === evento ) {
        wp_enqueue_script(
            evento-admin,
            plugin_dir_url(__FILE__) . admin/js/evento-admin.js,
            array(jquery),
            1.0.0,
            true
        )
    }
})

Consejos de depuración y errores comunes

  • Hook incorrecto: usar wp_enqueue_scripts para frontend. No funcionará si se ejecuta demasiado pronto o en admin.
  • Ruta errónea: comprobar get_template_directory_uri() vs get_stylesheet_directory_uri() si se usa child theme.
  • Handle duplicado: si otro plugin o theme usa el mismo handle, puede colisionar. Elegir prefijos únicos (ej.: mi_theme_contact-form).
  • Dependencias no declaradas: si tu script necesita jQuery, declarar [jquery] para garantizar orden correcto de carga.
  • Versionado y caché: al desplegar en producción, usar versiones fijas, no filemtime si los archivos son construidos en CI/CD con hashes.

Estrategias avanzadas

  • Concatenación y build tools: usar bundlers (Webpack, Rollup, Vite) para generar bundles por ruta o por «entry points» y encolar esos bundles condicionalmente.
  • Split code y lazy-load: cargar funcionalidades pesadas bajo demanda (dynamic import, IntersectionObserver para módulos que se activan en scroll).
  • Preload/Prefetch: añadir recursos críticos con link rel=preload o prefetch si es necesario (esto requiere imprimir etiquetas en head con wp_head o usando wp_resource_hints).
  • Third-party scripts: cargar asíncronamente y diferir hasta interacción del usuario cuando sea posible.

Resumen y flujo recomendado

  1. Identificar scripts por página/feature y sus dependencias.
  2. Registrar scripts globalmente con wp_register_script o directamente encolar con wp_enqueue_script.
  3. Usar condicionales (is_page, is_singular, get_post_type, etc.) para encolar solo donde haga falta.
  4. Pasar datos con wp_localize_script o wp_add_inline_script para evitar inline JS incontrolado.
  5. Usar filemtime en desarrollo y versión con hash en producción.
  6. Agregar async/defer solo cuando sea seguro para el comportamiento del script.

Ejemplo final compacto: múltiples scripts condicionales

add_action(wp_enqueue_scripts, function() {
    // Slider home
    if ( is_front_page() ) {
        wp_enqueue_script(home-slider, get_template_directory_uri() . /js/home-slider.js, array(jquery), filemtime(get_template_directory() . /js/home-slider.js), true)
    }

    // Gallery en CPT producto
    if ( is_singular(producto) ) {
        wp_enqueue_script(producto-gallery, get_template_directory_uri() . /js/producto-gallery.js, array(jquery), 1.2.0, true)
    }

    // Contacto con AJAX
    if ( is_page(contacto) ) {
        wp_enqueue_script(contact-form, get_template_directory_uri() . /js/contact-form.js, array(jquery), filemtime(get_template_directory() . /js/contact-form.js), true)
        wp_localize_script(contact-form, ContactFormData, array(
            ajax_url => admin_url(admin-ajax.php),
            nonce => wp_create_nonce(contact_form_nonce)
        ))
    }
})

Conclusión

Controlar la carga de JavaScript por página con wp_enqueue_script condicional es una técnica básica pero poderosa para optimizar un sitio WordPress. Aplicando las prácticas mostradas —registro, encolado condicional, versionado, localización de datos y atributos async/defer cuando proceda— se mejora significativamente la velocidad y la calidad del código del proyecto. Combinar estos patrones con un buen flujo de construcción y pruebas resulta en sitios más rápidos, más mantenibles y con mejores métricas de rendimiento.



Acepto donaciones de BAT's mediante el navegador Brave 🙂



Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *