Mover todos los archivos JS al pie de página|footer, de la manera correcta

17 feb 2015, 05:19:04
Vistas: 24.5K
Votos: 2

Para acelerar la carga de mi sitio y evitar que los scripts bloqueen el renderizado de la página, estoy tratando de mover todos los scripts posibles (archivos JS) del head al footer. Después de investigar, creé este código:

function footer_enqueue_scripts() {
    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('after_setup_theme', 'footer_enqueue_scripts');

Pero no está funcionando ya que algunos scripts siguen cargándose en el head, ver la salida a continuación:

<head>
<link rel="stylesheet" type="text/css" href="http://elclarin.dev/wp-content/cache/minify/000000/d4587/default.include.993ea9.css" media="all" />
<script type="text/javascript" src="http://elclarin.dev/wp-content/cache/minify/000000/d4587/default.include.0fe0ac.js"></script>
....
<!-- Metas -->
<meta charset="utf-8">

 <!-- Archivos JS -->
<script type="text/javascript" src="http://elclarin.dev/wp-content/themes/elclarin_v2/js/jquery-1.7.2.min.js"></script>
<script type="text/javascript" src="http://elclarin.dev/wp-content/themes/elclarin_v2/js/jquery.tools-1.2.7.min.js"></script>
<script type="text/javascript" src="http://elclarin.dev/wp-content/themes/elclarin_v2/js/prefixfree-1.0.6.min.js"></script>
<script type="text/javascript" src="http://elclarin.dev/wp-content/themes/elclarin_v2/js/modernizr.js"></script>
<!--[if lt IE 9]>
<script type="text/javascript" src="http://elclarin.dev/wp-content/themes/elclarin_v2/js/html5shiv.js"></script>
<![endif]-->
<!--[if (gte IE 6)&(lte IE 8)]>
<script type="text/javascript" src="http://elclarin.dev/wp-content/themes/elclarin_v2/js/selectivizr-1.0.2.min.js"></script>
<![endif]-->
<script type="text/javascript">
    var TEMPLATEURL = 'http://elclarin.dev/wp-content/themes/elclarin_v2';
</script>


<!-- Generated by OpenX 2.8.9 -->
<script type='text/javascript' src='http://openx.elclarinweb.com/www/delivery/spcjs.php?id=2&amp;target=_blank'></script>

<!-- Archivos de Analytics -->
<script type="text/javascript">
    var _gaq = _gaq || [];
    _gaq.push(['_setAccount', 'UA-29394358-3']);
    _gaq.push(['_trackPageview']);
    _gaq.push(['elclarin._setAccount', 'UA-36592785-1']);
    _gaq.push(['elclarin._trackPageview']);
    _gaq.push(['elclarin._setAccount', 'UA-49334701-1']);
    _gaq.push(['elclarin._trackPageview']);

    (function () {
        var ga = document.createElement('script');
        ga.type = 'text/javascript';
        ga.async = true;
        ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
        var s = document.getElementsByTagName('script')[0];
        s.parentNode.insertBefore(ga, s);
    })();

</script>
</head>
 ...
</footer>
    <script type='text/javascript' src='http://elclarin.dev/wp-includes/js/admin-bar.min.js?ver=4.1'></script>
    <script type='text/javascript' src='http://elclarin.dev/wp-includes/js/jquery/jquery-migrate.min.js?ver=1.2.1'></script>
    <script type='text/javascript' src='http://elclarin.dev/wp-includes/js/hoverIntent.min.js?ver=r7'></script>
...

¿Alguna solución alternativa sobre este tema? El sitio en vivo para pruebas está aquí

Actualización

Después del consejo de @Milo, encontré que los scripts, como él dijo, no están encolados correctamente en el tema en el archivo header.php ya que puedo ver esto:

<!-- Archivos JS -->
<script type="text/javascript" src="<?php echo TEMPLATEURL ?>/js/jquery-1.7.2.min.js"></script>
<script type="text/javascript" src="<?php echo TEMPLATEURL ?>/js/jquery.tools-1.2.7.min.js"></script>
<script type="text/javascript" src="<?php echo TEMPLATEURL ?>/js/prefixfree-1.0.6.min.js"></script>
<script type="text/javascript" src="<?php echo TEMPLATEURL ?>/js/modernizr.js"></script>
<!--[if lt IE 9]>
<script type="text/javascript" src="<?php echo TEMPLATEURL ?>/js/html5shiv.js"></script>
<![endif]-->
<!--[if (gte IE 6)&(lte IE 8)]>
<script type="text/javascript" src="<?php echo TEMPLATEURL ?>/js/selectivizr-1.0.2.min.js"></script>
<![endif]-->
<script type="text/javascript">
    var TEMPLATEURL = '<?php echo TEMPLATEURL; ?>';
</script>
<script type="text/javascript" src="<?php echo TEMPLATEURL ?>/js/acciones.js"></script>

<!-- Generado por OpenX 2.8.9 -->
<script type='text/javascript' src='http://openx.elclarinweb.com/www/delivery/spcjs.php?id=2&amp;target=_blank'></script>

<!-- Archivos de Analytics -->
<script type="text/javascript">
    var _gaq = _gaq || [];
    _gaq.push(['_setAccount', 'UA-29394358-3']);
    _gaq.push(['_trackPageview']);
    _gaq.push(['elclarin._setAccount', 'UA-36592785-1']);
    _gaq.push(['elclarin._trackPageview']);
    _gaq.push(['elclarin._setAccount', 'UA-49334701-1']);
    _gaq.push(['elclarin._trackPageview']);

    (function () {
        var ga = document.createElement('script');
        ga.type = 'text/javascript';
        ga.async = true;
        ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
        var s = document.getElementsByTagName('script')[0];
        s.parentNode.insertBefore(ga, s);
    })();

</script>
<!-- Archivos WP -->
<?php wp_head(); ?>

Mi pregunta sobre estas inclusiones (no soy el desarrollador del tema pero estoy seguro de que esto se puede arreglar): ¿cuál es la forma correcta de cargarlos sin romper el tema y teniendo en cuenta el rendimiento y la velocidad de carga de la página?

5
Comentarios

¿Estás seguro de que tu tema está encolando esos scripts? Supongo que probablemente no.

Milo Milo
17 feb 2015 05:49:05

@Milo, tienes razón, todos están mal incluidos en header.php (ver mi edición), ¿algún consejo para solucionar esto?

ReynierPM ReynierPM
17 feb 2015 06:40:43

Bueno, el método correcto sería encolar todas las librerías JS en functions.php, pero lo más fácil sería cortar y pegar todos los archivos JS de header.php a footer.php

Robert hue Robert hue
17 feb 2015 07:08:07

@Roberthue funcionará pero definitivamente no es recomendable :-)

Pieter Goosen Pieter Goosen
17 feb 2015 07:13:04

Sí, por eso lo dije. Mover los archivos JS de header.php a footer.php será mucho más fácil pero no es una solución adecuada. :)

Robert hue Robert hue
17 feb 2015 07:30:26
Todas las respuestas a la pregunta 2
3

IMHO, I still think that loading scripts and styles directly in the header is bad practice as it is always a problem removing them and loading them coditionally.

The best way to work around this is to create a [child theme] and then copy header.php to your child theme. Wordpress will load your child theme's header instead of the parent theme's header.

You can now delete all the scripts from your header and properly enqueue and register them through the wp_enqueue_scripts hook in your child theme functions.php. Just remember to set the $in_footer parameter in the wp_enqueue_script() and wp_register_script() functions to `true

EDIT

From your linked header.php, your scripts is added between lines 56 - 95. This you will need to delete. If you visit the site, you will not see any jquery being loaded.

Thenbuild in jquery library is already being loaded, no need to worry about that. The rest you need to enqueue yourself. Here is an example (Remember, each script should have a unique handle, so name them something that is unique that will not create conflict)

add_action('wp_enqueue_scripts', 'enqueue_my_scripts');

function enqueue_my_scripts() 
{
    wp_enqueue_script('jquery-tools', get_template_directory_uri() . '/js/jquery.tools.js-1.2.7.min.js', array('jquery'), false, true);
    //Do the same for the other scripts
}

Notice I have used get_template_directory_uri() here as you will be leaving your js folder in your parent theme. You can, however, move your js folder to your child theme, but then you will need to use get_stylesheet_directory_uri()

NOTES ON THE CONDITIONAL SCRIPTS

There is still, after four years after being raised, no build in way to load scripts conditionally according to IE browser like there is for styles. You can check out the trac ticket and another question raising this same issue here

I have never tried loading scripts conditionally according to browser, so I cannot comment on this section or state whether any solution work which is mentioned in the linked answer or trac ticket. What I can tell you, if the solutions don't work, you will need to copy footer.php to your child theme and then move lines 61 -66 from your header to your footer

NOTES ON THE SCRIPT LINES 67 -69

This sections passes a php variable to jquery. The correct way to do this will be to use wp_localize_script(). You will need to contact the developer here for assistance as this is frankly theme related, and I do really not know where this is actually used in your scripts. Check out the link also for usage and info

NOTES ON THE ANALYTICS SCRIPT LINES 75 - 94

You will need to create a js file for this section. If you haven't copied the js folder from the parent to your child theme, create a new js folder for your child theme. Open it up and create a new js file and call it what you like, something like analytics.script.js.

Next you will move everything inside the script tags to this folder, this is lines 77 - 92. Be sure to use the no conflict wrapper to wrap this script in as described here

You can just enqueue this script as normal as described earlier, just remember to use get_stylesheet_directory_uri() and not get_template_directory_uri()

EDIT 2

The patch from the linked answer under NOTES ON THE CONDITIONAL SCRIPTS does not work, it is not yet implemented and as I said in comments, it will most probably not be included in version 10 in a 100 years time :-). Unfortunately you will need to live with this, there is just no way to achieve this at present. This is really the draw back for supporting IE6 - 8. Well, to be honest, if you still support IE6 and 7, you are fighting a battle that was lost long ago. All major software developers has dropped IE6 (this includes Wordpress), IE7 was dropped by Microsoft themselves, so software developers will follow soon, and IE 8 will not live to see end 2016 IMHO

To overcome this compatibility issue with jquery, it might be better to stick with what the theme itself offers

You can try something like this

add_action('wp_enqueue_scripts', 'enqueue_my_scripts', PHP_INT_MAX);

function enqueue_my_scripts() 
{

    /**
     * Make sure, get_template_directory_uri() if script stays in parent theme
     * Use get_stylesheet_directory_uri() if script is in child theme
    */ 
    wp_enqueue_script('jquery-min', get_template_directory_uri() . '/js/jquery-1.7.2.min.js', array(), false, true);
    wp_enqueue_script('jquery-tools', get_template_directory_uri() . '/js/jquery.tools.js-1.2.7.min.js', array('jquery-min'), false, true);
    wp_enqueue_script('prefixfree', get_template_directory_uri() . '/js/prefixfree-1.0.6.min.js', array(), false, true);
    wp_enqueue_script('modernizr', get_template_directory_uri() . '/js/modernizr.js', array(), false, true);

    /**
     * The two conditional scripts which there is no work around for, load them or drop support
    */ 
    wp_enqueue_script('html5shiv', get_template_directory_uri() . '/js/html5shiv.js', array(), false, true);
    wp_enqueue_script('selectivizr', get_template_directory_uri() . '/js/selectivizr-1.0.2.min.js', array(), false, true);

    wp_enqueue_script('acciones', get_template_directory_uri() . '/js/acciones.js', array(), false, true);
    wp_enqueue_script('openx', 'http://openx.elclarinweb.com/www/delivery/spcjs.php?id=2&amp;target=_blank', array(), false, true);
    wp_enqueue_script('analytics', get_stylesheet_directory_uri() . '/js/analytics.script.js', array(), false, true);

}

EDIT 3

This is how your child theme header.php should look like

<!DOCTYPE html>
<html itemscope itemtype="http://schema.org/Blog">
<head>
    <!-- Metas -->
    <meta charset="utf-8">
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta name="google-site-verification" content="V022hygXU9AHEdTBX2BFnTBYeo4SsaTjC7aGdoIMPL4"/>
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport" content="width=device-width">
    <meta name="description" content="<?php bloginfo( 'description' ); ?>">
    <?php if (is_single()) { ?>
        <meta property="og:title" content="<?php the_title(); ?>"/>
        <meta itemprop="name" content="<?php the_title(); ?>">
        <meta property="og:type" content="article"/>
        <meta property="og:url" content="<?php the_permalink(); ?>"/>
        <?php
        if (has_post_thumbnail()) {
            $src = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), array( 490, 290 ), false );
            ?>
            <meta property="og:image" content="<?php echo $src[0]; ?>"/>
            <meta itemprop="image" content="<?php echo $src[0]; ?>">
        <?php } else { ?>
            <meta property="og:image" content="<?php echo TEMPLATEURL; ?>/images/logo.png"/>
            <meta itemprop="image" content="<?php echo TEMPLATEURL; ?>/images/logo.png">
        <?php } ?>
        <meta property="og:site_name" content="<?php bloginfo( 'name' ); ?>"/>
        <meta itemprop="description" content="<?php the_excerpt(); ?>">
    <?php } ?>

    <!-- Title -->
    <title>
        <?php
        if (isset($wp_query->query_vars['b'])) {
            echo str_replace( "+", " ", $wp_query->query_vars['b'] )." | ";
        }
        wp_title( '|', true, 'right' );
        bloginfo( 'name' );
        if (isset($paged) && $paged >= 2 || isset($page) && $page >= 2 || isset($page_alt) && $page_alt >= 2) {
            echo ' | '.sprintf( 'Página %s', max( $paged, $page, $page_alt ) );
        }
        ?>
    </title>

    <!-- Stylesheets & others -->
    <link rel="stylesheet" type="text/css" media="all" href="<?php bloginfo( 'stylesheet_url' ); ?>?version=4"/>
    <link rel="pingback" href="<?php bloginfo( 'pingback_url' ); ?>"/>
    <link rel="alternate" type="application/rss+xml" title="RSS" href="<?php echo SITEURL; ?>/feed/"/>
    <link rel="alternate" type="application/atom+xml" title="Atom" href="<?php echo SITEURL; ?>/feed/atom/"/>

    <link rel="shortcut icon" href="<?php echo TEMPLATEURL ?>/images/favicon.ico"/>
    <link rel="shortcut icon" href="<?php echo TEMPLATEURL ?>/images/favicon.png"/>
    <link rel="apple-shortcut icon" href="<?php echo TEMPLATEURL ?>/images/favicon_iphone.png"/>
    <link rel="apple-touch-icon-precomposed" href="<?php echo TEMPLATEURL ?>/images/favicon_iphone.png">
    <link rel="apple-touch-icon" href="<?php echo TEMPLATEURL ?>/images/favicon_iphone.png">

    <!-- WP Files -->
    <?php wp_head(); ?>
</head>
<body>
<div class="for_overlays">
    <?php
    if (is_front_page()) {
        $prepost      = $post;
        $normal_args  = Array(
            'post_type'      => 'portadadeldia',
            'post_status'    => 'publish',
            'posts_per_page' => 1
        );
        $normal_query = new WP_Query( $normal_args );
        if ($normal_query->have_posts()) {
            while ($normal_query->have_posts()) {
                $normal_query->the_post();
                ?>
                <?php
                if (has_post_thumbnail()) {
                    $large_image_url = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), 'full' );
                    ?>
                    <div id="portadadeldia" class="from_overlay">
                        <a href="<?php echo $large_image_url[0]; ?>" target="_blank">
                            <?php echo get_the_post_thumbnail(
                                $post->ID,
                                'portadadeldia_frontpage_overlay',
                                array( 'alt' => trim( get_the_title() ), 'title' => trim( get_the_title() ) )
                            ); ?>
                        </a>
                    </div>
                <?php } ?>
            <?php
            }
        }
        $post = $prepost;
        wp_reset_postdata();
    }
    ?>
    <svg>
        <filter id="firefoxblur">
            <feGaussianBlur stdDeviation="4"/>
        </filter>
    </svg>
</div>
<header>
    <div class="center_content">
        <div id="header_publicity" class="publicity">
            <span>Publicidad</span>

            <div>
                <script type='text/javascript'><!--// <![CDATA[
                    /* [id18] Header Top */
                    OA_show(18);
                    // ]]> --></script>
                <noscript><a target='_blank' href='http://openx.elclarinweb.com/www/delivery/ck.php?n=1073df0'><img
                            border='0' alt=''
                            src='http://openx.elclarinweb.com/www/delivery/avw.php?zoneid=18&amp;n=1073df0'/></a>
                </noscript>
            </div>
        </div>
        <h1 id="header_logo"><a href="<?php echo SITEURL; ?>">
                <?php
                $prepost      = $post;
                $normal_args  = Array(
                    'post_status'    => 'publish',
                    'posts_per_page' => 1,
                    'post_type'      => 'logos',
                );
                $normal_query = new WP_Query( $normal_args );
                if ($normal_query->have_posts()) {
                    $normal_query->the_post();
                    $thumbnail_id     = get_post_thumbnail_id( $post->ID );
                    $thumbnail_object = get_post( $thumbnail_id );
                    $url              = $thumbnail_object->guid;
                    ?><img src="<?PHP echo $url; ?>" alt="<?php bloginfo( 'name' ); ?>"><?php
                } else {
                    ?><img src="<?PHP echo TEMPLATEURL; ?>/images/logo.png" alt="<?php bloginfo( 'name' ); ?>"><?php
                }
                $post = $prepost;
                wp_reset_postdata();
                ?>
            </a></h1>
        <?php custom_secondary_nav( "executive_menu", 'header_lateral_superior', 'Menú corporativo' ); ?>
        <div id="header_lateral_inferior">
            <div id="header_buscador" role="search" title="Buscar">
                <div id="header_buscador_inner">
                    <form method="get" action="<?php echo SITEURL; ?>">
                        Buscar
                        <input title="Buscar" type="text" name="s"
                               value="<?php echo str_replace( "+", " ", $wp_query->query_vars['s'] ); ?>">
                    </form>
                </div>
            </div>
            <div id="header_redes">
                <a href="http://twitter.com/elclarin_aragua" target="_blank"><img
                        src="<?php echo TEMPLATEURL ?>/images/icons/tw.png"></a>
                <a href="<?php echo SITEURL; ?>/rss" target="_blank"><img
                        src="<?php echo TEMPLATEURL ?>/images/icons/rs.png"></a>
                <a href="<?php echo SITEURL; ?>"><img src="<?php echo TEMPLATEURL ?>/images/icons/ho.png"></a>
            </div>
        </div>
        <div id="header_menu">
            <?php wp_nav_menu( array( 'theme_location' => 'primary', 'menu_id' => 3 ) ); ?>
        </div>
    </div>
</header>
<div role="main" id="main" class="main">
    <div class="center_content">
17 feb 2015 07:11:27
Comentarios

Esto es un poco avanzado para mí @Pieter, ¿podrías proporcionar junto a tu pregunta un ejemplo simple para uno o dos scripts? Leí tu respuesta pero no sé por dónde continuar

ReynierPM ReynierPM
17 feb 2015 07:25:38

Bien, una última cosa, ¿qué hay acerca del archivo header.php en el tema hijo? ¿Cómo debería ser el contenido de este archivo? Actualmente esto es exactamente lo que tengo y creo que está completamente mal, así que...

ReynierPM ReynierPM
17 feb 2015 18:06:31

Mira mi actualización. ¿Puedo pedirte un favor? Por favor borra todos tus comentarios, ya que esta respuesta activará una bandera en el panel del moderador por demasiados comentarios. Gracias :-)

Pieter Goosen Pieter Goosen
17 feb 2015 18:12:34
0

Creo que tu script es correcto, pero quizás debas corregir este elemento

add_action('after_setup_theme', 'footer_enqueue_scripts');

Cambia a

add_action( 'wp_enqueue_scripts', 'oiw_remove_head_scripts' );

Puedes encontrar la referencia aquí y lo he probado y funciona

25 ene 2020 04:38:23