如何延迟或异步此 WordPress javascript 片段以最后加载以加快页面加载时间?

Posted

技术标签:

【中文标题】如何延迟或异步此 WordPress javascript 片段以最后加载以加快页面加载时间?【英文标题】:How do I defer or async this WordPress javascript snippet to load lastly for faster page load times? 【发布时间】:2013-09-27 10:49:06 【问题描述】:

我在我的一个 WordPress 域中有各种必要的插件,并且我知道它在 php 文件中的哪个位置被调用。

我正在采取一切措施来加快页面加载时间,并且网络上的每个速度测试人员都表示尽可能推迟 javascript

我已经阅读了关于 defer='defer'async 函数的 javascript 函数,我认为其中之一将完成我想要完成的任务。但我不明白如何在 php 文件中这样做。

例如,这里是来自一个特定插件的 php 文件的 sn-p,其中 javascript 文件被调用:

function add_dcsnt_scripts() 

    wp_enqueue_script( 'jquery' );
    wp_enqueue_script( 'dcsnt', dc_jqsocialtabs::get_plugin_directory() . '/js/jquery.social.media.tabs.1.7.1.min.js' );


我读到最好这样做以加快页面加载时间:

<script defer async src="..."></script>

但我不知道如何在 php 文件中实现这一点。我想对我所有的 javascript 文件执行此操作。

我如何将这个 javascript sn-p 延迟或异步到最后加载并加快页面加载时间?在所有浏览器中增加页面加载时间的理想方法是什么?感谢任何人都可以提供的任何指导!

【问题讨论】:

对于刚刚学习这个主题的人......“延迟”和“异步”是两个不同的东西。延迟脚本在处理完所有正常脚本后执行,并将按照它们遇到的顺序是单线程的。异步脚本在单独的后台线程中执行,立即开始,没有可预测的时间或完成顺序。你不会在同一个脚本上同时使用它们。 【参考方案1】:

或者更通用的方式:

function add_async_forscript($url)

    if (strpos($url, '#asyncload')===false)
        return $url;
    else if (is_admin())
        return str_replace('#asyncload', '', $url);
    else
        return str_replace('#asyncload', '', $url)."' async='async"; 

add_filter('clean_url', 'add_async_forscript', 11, 1);

因此您可以在不更改代码的情况下将异步添加到任何脚本,只需将#asyncload 添加到脚本网址:

wp_enqueue_script('dcsnt', '/js/jquery.social.media.tabs.1.7.1.min.js#asyncload' )

【讨论】:

感谢用户...假设插件作者使用 enqueue 方法正确编码了他们的插件。我越来越多地删除编码不正确的插件,并坚持使用编码更好的插件,即使它们不像更流行的插件那么古老和可信。 asyncdefer 之间有一个很小但很重要的区别:webkit.org/blog/1395/running-scripts-in-webkit 另请参阅:***.com/questions/10808109/script-tag-async-defer +1 这是一个不错的主题/插件作者友好的解决方案 非常聪明。谢谢,霍斯。 这应该是选择的答案,很好的解决方案【参考方案2】:

为了让事情在某种程度上保持模块化和包罗万象,下面的方法动态地选择如何通过在 $handle 名称上附加一个小标识符来嵌入带有 async 或 defer 属性的标签:

/**
* Add async or defer attributes to script enqueues
* @author Mike Kormendy
* @param  String  $tag     The original enqueued <script src="...> tag
* @param  String  $handle  The registered unique name of the script
* @return String  $tag     The modified <script async|defer src="...> tag
*/
// only on the front-end
if(!is_admin()) 
    function add_asyncdefer_attribute($tag, $handle) 
        // if the unique handle/name of the registered script has 'async' in it
        if (strpos($handle, 'async') !== false) 
            // return the tag with the async attribute
            return str_replace( '<script ', '<script async ', $tag );
        
        // if the unique handle/name of the registered script has 'defer' in it
        else if (strpos($handle, 'defer') !== false) 
            // return the tag with the defer attribute
            return str_replace( '<script ', '<script defer ', $tag );
        
        // otherwise skip
        else 
            return $tag;
        
    
    add_filter('script_loader_tag', 'add_asyncdefer_attribute', 10, 2);

示例用法:

function enqueue_my_scripts() 

    // script to load asynchronously
    wp_register_script('firstscript-async', '//www.domain.com/somescript.js', '', 2, false);
    wp_enqueue_script('firstscript-async');

    // script to be deferred
    wp_register_script('secondscript-defer', '//www.domain.com/otherscript.js', '', 2, false);
    wp_enqueue_script('secondscript-defer');


    // standard script embed
    wp_register_script('thirdscript', '//www.domain.com/anotherscript.js', '', 2, false);
    wp_enqueue_script('thirdscript');

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

输出:

<script async type='text/javascript' src='//www.domain.com/somescript.js'></script>
<script defer type='text/javascript' src='//www.domain.com/otherscript.js'></script>
<script type='text/javascript' src='//www.domain.com/anothercript.js'></script>

感谢@MattKeys @crissoca 在这里启发我的回答。

【讨论】:

简直太棒了。 我见过的最好的! 一个小的改进 - 脚本可以加载异步和延迟属性。您的加载器函数可以通过将“else if”更改为“if”来处理这个问题。 我认为这是一个干净的解决方案! (惊讶于 WP 不提供内置的异步/延迟......)【参考方案3】:

这个blog post 链接到两个感兴趣的插件:

Asynchronous Javascript通过使用 head.js 异步加载 javascript 来提高页面加载性能

WP Deferred Javascripts使用 LABJS(一个异步 javascript 库)延迟加载使用 wp_enqueue_scripts 添加的所有 javascript。

尚未对其进行测试,但检查了代码,他们在 WordPress 脚本排队过程中做了一些非常漂亮的事情。

然后WPSE comes to rescue:

// Adapted from https://gist.github.com/toscho/1584783
add_filter( 'clean_url', function( $url ) 
    if ( FALSE === strpos( $url, '.js' ) ) 
        // not our file
        return $url;
    
    // Must be a ', not "!
    return "$url' defer='defer";
, 11, 1 );

【讨论】:

感谢您花时间帮助我,brasofilo ...感谢您的时间,这基本上得到了我需要的 html 输出 @brasofilo 'clean_url' 现已被弃用,支持或 'esc_url' codex.wordpress.org/Function_Reference/clean_url 它已被弃用,但从 WP 4.1 开始,我现在将使用 'script_loader_tag' 而不是 'esc_url' 回到这个话题。 Async 插件已失去支持,defer 在旧版 Internet Explorer 之外可能不是很有帮助。只是把它扔在那里,以防有人在做研究。【参考方案4】:

另一种使用不同过滤器的解决方案,可用于针对特定脚本句柄:

function frontend_scripts()

    wp_enqueue_script( 'my-unique-script-handle', 'path/to/my/script.js' );

add_action( 'wp_enqueue_scripts', 'frontend_script' );

function make_script_async( $tag, $handle, $src )

    if ( 'my-unique-script-handle' != $handle ) 
        return $tag;
    

    return str_replace( '<script', '<script async', $tag );

add_filter( 'script_loader_tag', 'make_script_async', 10, 3 );

【讨论】:

异步插件脚本的完美解决方案。谢谢:)【参考方案5】:

一种简化的方法。添加到您的 functions.php 文件以使 JavaScript 在 Wordpress 中异步

// Make JavaScript Asynchronous in Wordpress
add_filter( 'script_loader_tag', function ( $tag, $handle )     
    if( is_admin() ) 
        return $tag;
    
    return str_replace( ' src', ' async src', $tag );
, 10, 2 );

【讨论】:

【参考方案6】:

非常少的修改代码Mike Kormendy,允许你一次添加2个属性:

// Async load
function add_asyncdefer_attribute($tag, $handle)

    $param = '';
    if ( strpos($handle, 'async') !== false ) $param = 'async ';
    if ( strpos($handle, 'defer') !== false ) $param .= 'defer ';
    if ( $param )
        return str_replace('<script ', '<script ' . $param, $tag);
    else
        return $tag;

结果:

<script async defer type='text/javascript' src='#URL'></script>

【讨论】:

我赞同这个! ;-) 请注意,浏览器只会遵循两个指令之一 - async 是首选。所以async defer和只加async的效果是一样的。通常的例外:IE9 及更早版本,只会处理defer【参考方案7】:

要控制要延迟的 js 文件并避免冲突,您可以将变量附加到 wp_register_script 函数中的 url,如下所示。

wp_register_script( 'menu', get_template_directory_uri() . '/js/script.js?defer', array('jquery'), '1.0', true );

然后换行:

if ( FALSE === strpos( $url, '.js' ))

收件人:

if ( FALSE === strpos( $url, '.js?defer' ))

新过滤器如下所示。

add_filter( 'clean_url', function( $url )

    if ( FALSE === strpos( $url, '.js?defer' ) )
     // not our file
    return $url;
    
    // Must be a ', not "!
    return "$url' defer='defer";
, 11, 1 );

【讨论】:

谢谢内森。尽管我已经使用了其中一种解决方案,但我将对此进行测试以供参考。 这是一个聪明的主意。我希望有一种不那么“hacky”的方法,但这实际上是我见过的最好的单独维护脚本控制的方法。【参考方案8】:

我认为延迟/异步 WordPress jQuery 是不好的做法。更好的解决方案是从过滤器中排除 jQuery

if (!is_admin()) 
    add_filter( 'script_loader_tag', function ( $tag, $handle )     
        if ( strpos( $tag, "jquery.js" ) || strpos( $tag, "jquery-migrate.min.js") ) 
            return $tag;
        
        return str_replace( ' src', ' async src', $tag );
    , 10, 2 );

您可以使用defer 代替async

【讨论】:

【参考方案9】:

async 属性合并到脚本中,以便它们仅在整个页面加载后才加载

<script type="text/javascript">
    function ngfbJavascript( d, s, id, url ) 
        var js, ngfb_js = d.getElementsByTagName( s )[0];
        if ( d.getElementById( id ) ) return;
        js = d.createElement( s );
        js.id = id;
        js.async = true;
        js.src = url;
        ngfb_js.parentNode.insertBefore( js, ngfb_js );
    ;
</script>

来源:Here

【讨论】:

虽然这种方法是正确的,并且多年来被认为是最佳实践,但应该注意的是,它不再是了。根据 Ilya Grigorik 的说法,异步属性的性能要好得多,更多信息可以在这里找到:igvita.com/2014/05/20/…【参考方案10】:

添加clean_url过滤器解决方案的东西,确保验证仅在字体端使用它可能使用if( ! is_admin() )像ACF这样的流行插件可能会让你头疼。

更新

这是我修改后的解决方案:

if( ! is_admin() )
  add_filter( 'clean_url', 'so_18944027_front_end_defer', 11, 1 );
  function so_18944027_front_end_defer( $url ) 
    if ( FALSE === strpos( $url, '.js' ) )
     // not our file
        return $url;
    
    // Must be a ', not "!
    return "$url' defer='defer";
  

【讨论】:

这应该是评论,而不是答案。多一点代表,you will be able to post comments。在此之前,请不要使用答案作为解决方法。 谢谢伙计们,我只是想为正确答案添加额外的帮助,因为我遇到了这个问题,正如你所说,我没有足够的代表来为正确答案添加评论,但我认为这是一个有效的补充,我不是在添加评论家,而是试图扩展正确的答案

以上是关于如何延迟或异步此 WordPress javascript 片段以最后加载以加快页面加载时间?的主要内容,如果未能解决你的问题,请参考以下文章

在构造函数或 ngOnInit 中加载异步函数

高性能异步SRAM技术角度

在异步延迟问题上运行多个脚本[重复]

如何异步加载 CSS - WordPress

如何对使用 Axios(或其他异步更新)的 Vue 组件进行单元测试?

扭曲的延迟/回调和异步执行