每次页面加载的时候,都会加载一系列的 css 和 js,这些资源如果加载的方式处理不当,就会造成渲染阻塞。在 Google 的排名中,网站性能被做为了很重要的一项评判指标之一,较慢的网站也会导致用户的跳出率非常高。所以,为了你网站的排名也为了更好的用户体验,优化这些资源的加载势在必行。下面会介绍在 WordPress 系统中,如何推迟这些资源的加载,加快网站的解析。
1. 延迟非必要 CSS 加载
网上有推荐使用 LoadCSS.js 库来实现 CSS 延迟加载的,但这种使用 JS 的方法有个缺点,它会造成渲染阻塞。那么,我们如何在不使用 Javascript 渲染阻塞资源的情况下加载 CSS 文件?
我们可以使用 WordPress 的函数 style_loader_tag 来实现,将下方代码添加在主题文件目录下的 functions.php 即可,根据需要修改你不想要添加延迟加载的列表名。
add_filter('style_loader_tag', function ($html, $handle, $href, $media) {
if(!is_admin()){
#不添加延迟加载的列表 (login.min,style...修改为你不想延迟加载的文件名)
$styles_to_exclude = ['login.min.css', 'style.css']
foreach($styles_to_exclude as $exclude_style){
if(true == strpos($html, $exclude_style)) return $html;
}
$html = '<link rel="preload" href="' . $href . '" as="style" id="' . $handle . '" media="' . $media . '" onload="this.onload=null;this.rel=\'stylesheet\'">' . '<link rel="stylesheet" href="' . $href . '" id="' . $handle . '" media="print" onload="this.media=\'all\'">' . '<noscript>' . $html . '</noscript>';
}
return $html;
}, 10, 4);
使用该方法除了排除指定的样式列表外,后期即使添加新的 CSS 加载,亦不会造成渲染阻塞问题,延迟加载动作会自动作用后续添加的 CSS 文件,加载出来的结构效果如下:
<link rel="preload" href="#" as="style" id="#" media="#" onload="this.onload=null;this.rel='stylesheet'">
<link href="#" id="#" media="print" onload="this.media='all'">
<noscript><link rel="stylesheet" href="#" id="#" media="#"></noscript>
解析:
- 它的工作原理:
link rel="preload" as="style"
异步请求样式表,但仅支持 Chrome, Safari, Edge 等浏览器,添加第二个 <link> 是因为 Firefox 不支持 preload 属性,如果浏览器支持 preload 特性,它将只使用第一行代码,如果它不支持 “preload” 浏览器提示,那么它将获取具有 “print” 媒体属性的 CSS 文件并异步加载它。 - 链接中的 onload 属性允许在完成加载时处理 CSS
- noscript 标签确保如果浏览器不支持 “javascript”,它仍然可以向用户显示文件的内容,为了防止使用旧浏览器的用户看到没有实际样式的网页,使用 noscript 标签作为延迟加载 CSS 的后备很重要。
PageSpeed Insights 测试效果如下:
2. 推迟或异步加载 JS 脚本
我们可以通过为 JS 文件添加 async 或 defer 这两个属性来达到延迟加载的目的,所有现代主流浏览器包括 Chrome, Firefox 和 Edge 均已支持这两个属性。自 IE10 以来,Internet Explorer 也已经添加了对这些属性的支持。
以下是 async 和 defer 属性的作用:
- async 属性:即异步加载脚本,浏览器在继续解析 HTML 文档的同时异步下载脚本。当脚本完成下载时,即开始执行脚本,同时阻止 HTML 解析。
- defer 属性:即延迟加载脚本,浏览器在继续解析 HTML 文档的同时异步下载脚本。在 HTML 解析完成之前,脚本不会执行。
方式和前面延迟 JS 的方法类似,我们可以使用 WordPress 的函数 script_loader_tag 来为网站加载的一些 JS 添加相应的属性。将下方代码添加在主题文件目录下的 functions.php 即可,根据你的需要修改 defer 和 async 列表名。
// Add defer and async attributes in specify js
add_filter('script_loader_tag', function ($tag) {
#添加 defer 属性的 js 列表,自行修改为你的 js 文件名
$scripts_to_defer = ['search-form.js', 'comment_count.js', 'comment_embed.js'];
#添加 async 属性的 js 列表,自行修改为你自己的 js 文件名
$scripts_to_async = [
'wp-embed.min.js',
'responsive-embeds.js',
'jquery-migrate.min',
'single.js',
'about.js',
'category.js'
];
foreach($scripts_to_defer as $defer_script){
if(true == strpos($tag, $defer_script)) return str_replace(' async async async async async src', ' defer="defer" async async async async async src', $tag);
}
foreach($scripts_to_async as $async_script){
if(true == strpos($tag, $async_script)) return str_replace(' async async async async async src', ' async="async" async async async async async src', $tag);
}
return $tag;
}, 10);
加载出来的结构效果如下:
<script async src="#" async="async" type="text/javascript"></script>
<script async src="#" defer="defer" type="text/javascript"></script>
PageSpeed Insights 测试效果如下:
参考文档:
写下你的评论