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>
標籤靠前的位置中加入,否則可能達不到理想的加速效果