每次頁面渲染時,WordPress都會載入一系列外部引用JavaScript。
這些包括由WordPress新增的標準指令碼以及由使用wp_enqueue_scripts函式的主題和外掛新增的一些指令碼。 根據指令碼的型別,它可能位於網頁的頭部,正文或頁尾部分。
位於頁面頭部和主體部分內的指令碼可能會導致頁面載入延遲,因為瀏覽器甚至在頁面內容之前嘗試載入和執行這些指令碼。
這就是為什麼這些指令碼被稱為渲染阻塞javascripts。
解決此問題的最直接的方法是將所有指令碼移動到頁面的頁尾,但如果這種辦法不可行,則可以考慮為這些指令碼新增延遲或非同步屬性標記,就是我們常常掛在掛在嘴邊的延遲載入、非同步載入。
讓我們深入瞭解這些屬性以及它們如何幫助您改善頁面載入時間。
什麼是非同步和延遲屬性?
以下是async和defer屬性的作用:
- 非同步屬性:async屬性即非同步載入指令碼。 換句話說,確保指令碼與頁面的其他相關內容一起非同步載入。
- 延遲屬性:延遲屬性即延遲載入指令碼。 它確保僅在頁面的所有內容完成載入後才執行指令碼。
所有現代主流瀏覽器都支援這兩個屬性,包括Firefox,Chrome和Internet Explorer。 自IE10以來,Internet Explorer也已經新增了對這些屬性的支援。
具有async和defer屬性的指令碼標記示例如下:
<script src='http://sitename.com/js/scripts.js' async='async' type='text/javascript'></script> <script src='http://sitename.com/js/scripts.js' defer='defer' type='text/javascript'></script>
將“非同步/延遲”屬性新增到阻塞渲染指令碼
在這個章節中,我們將介紹三種不同的方法,將這些屬性新增到阻塞渲染javascripts中。 這些方法如下:
- 方法1:向所有指令碼新增延遲/非同步。
- 方法2:向大部分指令碼新增延遲/非同步,部分例外。
- 方法3:僅向選擇性指令碼新增延遲/非同步。 (最靈活的方法,因為它允許因地制宜地為指令碼新增延遲或者非同步屬性。)
您可以根據自己的實際情況使用適合您的方法。
方法1:向所有指令碼新增延遲/非同步屬性。
如果您想毫無例外地將async或defer屬性新增到所有指令碼,則可以使用以下程式碼。
開啟主題的functions.php頁面,將此程式碼新增到頁面底部。
/*function to add async to all scripts*/
function js_async_attr($tag){
# 新增非同步載入屬性到所有js指令碼
return str_replace( ' src', ' async="async" src', $tag );
}
add_filter( 'script_loader_tag', 'js_async_attr', 10 );
注意:上面的函式會將async屬性新增到所有指令碼中。 如果您想使用defer屬性,請使用defer =“defer”替換async =“async”。
方法2:向大部分指令碼新增延遲/非同步屬性,部分例外。
上述方法為所有指令碼新增了async或defer屬性。 如果您希望將這些屬性新增到大部分指令碼中,但有例外的,則可以使用以下程式碼:
/*function to add async to all scripts*/
function js_async_attr($tag){
# 不新增非同步載入屬性的例外列表(修改js檔名為你的網站js檔名)
$scripts_to_exclude = array('script-name1.js', 'script-name2.js', 'script-name3.js');
foreach($scripts_to_exclude as $exclude_script){
if(true == strpos($tag, $exclude_script ) )
return $tag;
}
# 新增非同步載入屬性到其餘js檔案
return str_replace( ' src', ' async="async" src', $tag );
}
add_filter( 'script_loader_tag', 'js_async_attr', 10 );
注意:如果您想使用defer,請在上面的程式碼中使用defer =“defer”替換async =“async”。
將script-name1.js,script-name2.js等替換為要排除的指令碼的名稱。 如果您不知道如何查詢指令碼名稱,請參閱下面的方法3。
方法3:僅向選擇性指令碼新增延遲/非同步屬性。
根據指令碼及其功能,您可能希望延遲載入或非同步載入它們。
如前所述,延遲指令碼僅在頁面完全載入後執行,因此如果您的指令碼需要在頁面載入期間執行,則非同步屬性更合適。
記住這一點,下面的函式將允許您向選擇性指令碼新增延遲或非同步屬性。
讓我們看看如何實現:
步驟1:第一步是查詢並列出要新增defer或async屬性的所有阻塞渲染指令碼的列表。
你可以使用Google Page Speed Tool或類似GTmetrix.com的工具來檢測這些指令碼。
訪問這些工具中的任何一個,並輸入任意一個頁面的URL,然後單擊“Analyze”。 稍等片刻,即會列出阻塞載入的javascript。
另一種方法是檢查網頁的HTML原始碼,然後使用“查詢”(CTRL + F)查詢所有.js檔案。
步驟2:第二步是找到需要新增延遲或非同步屬性的所有指令碼的指令碼名稱。
您可以使用Google PageSpeed insights完成此操作。
只需在“移除會阻止內容呈現的 JavaScript”部分下檢查您的指令碼。 您可以使用指令碼的名稱作為唯一名稱。
指令碼示例:
'https://sitename.com/wp-content/plugins/thrive/js/compat.min.js?ver=1.500.18
那麼上述的指令碼的唯一名稱是 compat.min.js.
你可以請參閱下面的Google PageSpeed insights分析的截圖以進一步瞭解:
您還可以通過檢查網站的HTML原始碼來查詢指令碼名稱:
要執行此操作,只需在瀏覽器中開啟部落格的頁面並檢查此頁面的HTML原始碼(您可以通過“CTRL + U”檢視頁面的HTML原始碼)。 然後,使用瀏覽器的查詢功能(CTRL + F)並搜尋關鍵字,script type=’text/javascript’,即可檢視所有指令碼檔案。 (參見下圖)
只需複製標記指令碼的名稱作為延遲或者非同步載入屬性的指令碼名稱即可。
步驟3:開啟主題的functions.php檔案,並將以下程式碼新增到檔案末尾。
$scripts_to_defer變數需包含所有要延遲的指令碼名稱,$scripts_to_async變數需包含所有要延遲的指令碼名稱。確保使用指令碼名稱編輯程式碼。
/*function to add async and defer attributes*/ function defer_js_async($tag){ ## 2: 延時載入js列表. (將js名稱改為你的js名稱) $scripts_to_defer = array('script-name1.js', 'script-name2.js', 'script-name3.js'); ## 2: 非同步載入js列表. (將js名稱改為你的js名稱) $scripts_to_async = array('script-name1.js', 'script-name2.js', 'script-name3.js'); #defer scripts foreach($scripts_to_defer as $defer_script){ if(true == strpos($tag, $defer_script ) ) return str_replace( 'src', ' defer="defer" src', $tag ); } #async scripts foreach($scripts_to_async as $async_script){ if(true == strpos($tag, $async_script ) ) return str_replace( 'src', ' async="async" src', $tag ); } return $tag; } add_filter( 'script_loader_tag', 'defer_js_async', 10 );
程式碼說明:此函式通過向WordPress的script_loader_tag新增過濾器,將defer或async屬性新增到指令碼標籤。
我們首先儲存需要在陣列中使用延遲和非同步的指令碼的唯一名稱,然後使用foreach迴圈來執行這些陣列。 每次迴圈執行時,它都會嘗試使用strpos(字串位置)函式在指令碼標記中查詢唯一檔名的位置。 如果strpos函式返回TRUE(表示在script標記中找到了唯一字串的位置),則使用PHP的 str_replace(字串替換)函式新增defer或async屬性。 如果沒有,則返回標籤而不做任何修改。
操作示例:
假設您要將延遲屬性新增到以下指令碼:
<script src='http://sitename.com/wp-content/plugins/contact-form-7/includes/js/scripts.js?ver=4.1.2'></script> <script src='http://sitename.com/wp-content/plugins/powerpress/player.min.js?ver=1429646074'></script>
並將async屬性新增到以下指令碼:
<script src='http://sitename.com/wp-includes/js/comment-reply.min.js?ver=4.2'></script> <script src='http://sitename.com/wp-content/themes/twentytwelve/js/navigation.js?ver=20140711'></script>
標識前兩個指令碼的唯一名稱是:contact-form-7和powerpress/player.min.js。 標識後兩個指令碼的唯一名稱是:comment-reply.min.js和twentytwelve/js/navigation.js
獲得這些指令碼的名稱後,即可安裝相應的位置新增到上面的程式碼中,如下所示:
## 1: 延時載入js列表. $scripts_to_defer = array('contact-form-7', 'powerpress/player.min.js'); ## 2: 非同步載入js列表. $scripts_to_async = array('twentytwelve/js/navigation.js', 'comment-reply.min.js');
注意:確保將指令碼名稱用單引號括起來並用逗號分隔。 您可以使用此方法新增任意數量的名稱。
如果您沒有任何指令碼要延遲載入,那麼您可以將其保留為空白陣列,如下所示,反之亦然:
## 1: 延時載入js列表. $scripts_to_defer = array(); ## 2: 非同步載入js列表. $scripts_to_async = array('twentytwelve/js/navigation.js', 'comment-reply.min.js');
關於WordPress的指令碼延時載入和非同步載入技術的分享,到此結束,如果你對這一塊還是有不瞭解的地方,歡迎留言交流。如果你覺得手動設定WordPress指令碼檔案的延遲載入或者非同步載入屬性比較麻煩,你也可以藉助一些外掛來實現,在這方面《如何做到Google PageSpeed Insights測試滿分/100分》的移除阻塞渲染的資源章節有詳細說明。
如果你要了解關於圖片或者視訊的懶載入技術,則可以閱讀《如何實現WordPress影象和視訊懶載入》深入瞭解。
評論留言
脣槍舌劍 (2)
迪亚莫外贸建站
2021.11.12 12:11
很好。不过对小白来说有点复杂,安装wp rocket 插件启用JS异步加载和JS延迟加载效果也不错。
奶爸建网站笔记
2019.7.18 22:07
坐个沙发。