Note
本片文章默认你已经会使用 sw 来加速网站了
前言#
前阵子,我开始用 cyf 大佬的 sw 加速方案,前前后后我使用了三个不同作者所开发的 sw 加速,但是因 cyf 的代码过于难以了解(我菜),而去使用了 yfun 大佬的代码,以便网页在前端被更新
为什么要首屏优化#
在使用 cyf 大佬的方案是我发现了 cyf 的首屏优化方案
事实上,ServiceWorker 最显著的缺点是要在第一次加载网页安装后,刷新一次才能激活。即访客第一次访问是不受 sw 控制的。换句话说,访客首屏不受加速,其加载速度与你的服务器有直接联系
[虽然安装完成后就起飞了,但安装前就是屑]。
更加令人抓狂的是,在首屏加载时,静态资源会被直接获取,并且不缓存,而 sw 激活后又会强制第二次获取,拉跨速度。不过我们可以尽可能弱化这一劣势。我们可以用 js 打断所有的请求,以确保首屏只加载一个 html 和一个 sw.js,其余资源都不会加载,降低首屏加载延迟。
所以我尝试使用了 cyf 大佬的首屏优化,而且有一个帅气的 sw 安装页面谁不爱呢
我前后使用了两种首屏优化样式这里都分享出来
方案 1(by cyfan)#
<!-- sw前端竞速 -->
<script>
(async () => {//使用匿名函数确保body已载入
/*
QYBlogHelper_Set 存储在LocalStorage中,用于指示sw安装状态
0 或不存在 未安装
1 已打断
2 已安装
3 已激活,并且已缓存必要的文件(此处未写出,无需理会)
*/
if ('serviceWorker' in navigator) { //如果支持sw
if (Number(window.localStorage.getItem('QYBlogHelper_Set')) < 1) {
setTimeout(async () => {
console.log('检测到您的浏览器没有安装QYBlogHelper,开始注册')
window.stop()
window.localStorage.setItem('QYBlogHelper_Set', 1)
const replacehtml = await fetch('https://npm.elemecdn.com/chenyfan-blog@1.0.13/public/notice.html')
document.body.innerHTML = await replacehtml.text()
$('#info').innerText = '尝试安装QYBlogHelper...';
}, 0);
}
const $ = document.querySelector.bind(document);//语法糖
navigator.serviceWorker.register(`/sw.js?time=${new Date().getTime()}`)//随机数,强制更新
.then(async () => {
if (Number(window.localStorage.getItem('QYBlogHelper_Set')) < 2) {
setTimeout(() => {
$('#info').innerText = '安装成功,稍等片刻...';
}, 0);
setTimeout(() => {
window.localStorage.setItem('QYBlogHelper_Set', 2)
console.log('准备跳转')
window.location.reload()//刷新,以载入sw
}, 500)//安装后等待500ms使其激活
}
})
.catch(err => console.error(`QYBlogHelperError:${err}`))
} else {
setTimeout(() => {
$('#info').innerText = '很抱歉,我们已不再支持您的浏览器.';
}, 0);
}
})()
</script>
方案 2(by yfun)#
<!-- sw前端竞速 -->
<script>
(async () => {//使用匿名函数确保body已载入
/*
QYBlogHelper_Set 存储在LocalStorage中,用于指示sw安装状态
0 或不存在 未安装
1 已打断
2 已安装
3 已激活,并且已缓存必要的文件(此处未写出,无需理会)
*/
if ('serviceWorker' in navigator) { //如果支持sw
if (Number(window.localStorage.getItem('QYBlogHelper_Set')) < 1) {
setTimeout(async () => {
console.log('检测到您的浏览器没有安装QYBlogHelper,开始注册')
window.stop()
window.localStorage.setItem('QYBlogHelper_Set', 1)
const replacehtml = await fetch('https://npm.elemecdn.com/qycdn@0.9.13/html/swinstall.html')
document.body.innerHTML = await replacehtml.text()
}, 0);
}
const $ = document.querySelector.bind(document);//语法糖
navigator.serviceWorker.register(`/sw.js?time=${new Date().getTime()}`)//随机数,强制更新
.then(async () => {
if (Number(window.localStorage.getItem('QYBlogHelper_Set')) < 2) {
setTimeout(() => {
window.localStorage.setItem('QYBlogHelper_Set', 2)
console.log('准备跳转')
window.location.reload()//刷新,以载入sw
}, 500)//安装后等待500ms使其激活
}
})
.catch(err => console.error(`QYBlogHelperError:${err}`))
} else {
setTimeout(() => {
console.log('很抱歉,我们已不再支持您的浏览器');
}, 0);
}
})()
</script>
注意事项#
Warning
我们尽可能将打断代码提到<head>
以确保不被其他资源堵塞,对于 hexo 来说打开主题的 head.ejs,在<head>
标签靠前的位置中加入,否则可能达不到理想的加速效果