banner
Jason

Jason的碎碎念

Jason的碎碎念
github

serviceworkers首屏优化

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>标签靠前的位置中加入,否则可能达不到理想的加速效果

加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。