2

In order to speedup my site load and prevent scripts from render the page I'm trying to move all the possible scripts (meaning JS files) from head to footer. After read and do some research I made this code:

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');

But it's not working since some scripts still loaded at head, see the output below:

<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">

 <!-- JS Files -->
<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>

<!-- Analytics Files -->
<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>
...

Any workaround on this topic? Live site for testing purposes is here

Update

After @Milo tip I found that scripts as he said are not enqueued properly at theme in header.php file since I can see this:

<!-- JS Files -->
<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>

<!-- 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>

<!-- Analytics Files -->
<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>
<!-- WP Files -->
<?php wp_head(); ?>

My question regarding those includes (I'm not the developer of theme but I'm pretty sure this can be fixed): what's the right|proper way to load them without break the theme and keeping performance and page speedup in mind?

5
  • Are you sure your theme is enqueueing those scripts? I'll guess it's probably not.
    – Milo
    Feb 17, 2015 at 3:49
  • @Milo, you're right all of them are bad included in header.php (see my edit), any advice around a fix for this?
    – ReynierPM
    Feb 17, 2015 at 4:40
  • Well the proper method would be to enqueue all JS libraries in functions.php but if would be easiest if you cut and paste all JS files from header.php to footer.php
    – Robert hue
    Feb 17, 2015 at 5:08
  • @Roberthue it will work but definitely not recommended :-) Feb 17, 2015 at 5:13
  • Yes, that's why I said. Moving JS files from header.php to footer.php will be alot easier but not a proper solution. :)
    – Robert hue
    Feb 17, 2015 at 5:30

2 Answers 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);

}

As I said before, there is a php variable passed to a script which you should talk to the theme author about. Also, any compatibility issues should be further discussed with the them authors. This is the correct layout and should in theory work. For any other theme related and compatibility issues, feel free to contact the theme author for support

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_timthumbnail(
                                $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">
3
  • This is kind of advanced for me @Pieter, can you provide among your question a simple example for one or two scripts? I read you answer but do not know where to go from here
    – ReynierPM
    Feb 17, 2015 at 5:25
  • Fine, one last thing, what about the header.php file at child theme? What the content of this file should looks like? Right now this is exactly what I've and I think is completely wrong, so...
    – ReynierPM
    Feb 17, 2015 at 16:06
  • 1
    See my update. Can I ask one favor. Please delete all your comments, as this answer will trigger a flag no in the moderator dashboard for too many comments. Thank you :-) Feb 17, 2015 at 16:12
0

I think your script is correct, but maybe you must fix this element

add_action('after_setup_theme', 'footer_enqueue_scripts');

Change to

add_action( 'wp_enqueue_scripts', 'oiw_remove_head_scripts' );

You can find reference here and I've tested it and work`

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.