WordPress下用jQuery延迟加载font-face CSS优化PageSpeed得分
核心问题说明
原有代码无法生效有两个核心原因:
jQuery(document).ready触发时DOM已完成解析,浏览器早已开始请求对应的字体CSS文件,此时删除操作无法绕过PageSpeed的检测- 第一处匹配规则的删除语法错误:
jQuery(this).attr('href').remove()是对字符串类型的href属性调用remove方法,属于无效语法,正确写法应为直接对DOM元素执行remove操作
方案1:jQuery实现(适配WordPress环境,无$标识符冲突)
需要将这段脚本插入到head标签的最顶部,放在所有link样式表之前加载,才能在浏览器解析字体CSS前完成拦截:
// 存储匹配到的字体CSS链接 const fontCSSList = []; // 监听DOM节点插入,实时拦截字体CSS const observer = new MutationObserver(function(mutations) { mutations.forEach(function(mutation) { if (mutation.addedNodes.length) { mutation.addedNodes.forEach(function(node) { // 匹配所有sgf-css目录下的字体CSS,无需逐个写路径判断 if (node.tagName === 'LINK' && node.getAttribute('href') && node.getAttribute('href').includes('/sgf-css/font-')) { fontCSSList.push(node.getAttribute('href')); // 直接移除节点,阻止浏览器发起请求 node.remove(); } }); } }); }); // 开启全局DOM监听 observer.observe(document.documentElement, { childList: true, subtree: true }); // 页面完全加载后再插入字体CSS jQuery(window).on('load', function() { fontCSSList.forEach(function(cssUrl) { jQuery('head').append(`<link rel="stylesheet" href="${cssUrl}">`); }); // 停止监听,避免不必要的性能损耗 observer.disconnect(); });
方案2:纯原生JavaScript实现(无第三方依赖)
同样放在head标签最顶部加载即可,兼容所有现代浏览器:
const fontCSSList = []; const observer = new MutationObserver(function(mutations) { mutations.forEach(function(mutation) { if (mutation.addedNodes.length) { mutation.addedNodes.forEach(function(node) { if (node.tagName === 'LINK' && node.getAttribute('href') && node.getAttribute('href').includes('/sgf-css/font-')) { fontCSSList.push(node.getAttribute('href')); node.remove(); } }); } }); }); observer.observe(document.documentElement, { childList: true, subtree: true }); window.addEventListener('load', function() { fontCSSList.forEach(function(cssUrl) { const link = document.createElement('link'); link.rel = 'stylesheet'; link.href = cssUrl; document.head.appendChild(link); }); observer.disconnect(); });
优化建议
- 可以额外给字体CSS对应的
@font-face规则添加font-display: swap属性,避免字体加载延迟导致的文字不可见问题 - 若担心JS异常导致字体不加载,也可以在WordPress的
wp_enqueue_scripts钩子中调整字体CSS的加载优先级,给标签添加media="print"属性,页面加载完成后再修改为media="all",也能实现同等效果
内容的提问来源于stack exchange,提问作者Asif Baloch
相关产品推荐
相关产品推荐

