我有一个PWA,本质上是一本书的读者。结果,它需要大量数据(即书籍文本)进行操作。由Lighthouse分析时,它在页面加载检查中得分很低。
我的问题是:在确保离线功能的同时,我可以采用哪些方法来改善页面负载?
我的起始页面可能很小(例如,仅显示“请稍等,正在下载文本”消息),然后动态地(通过注入的脚本标签或AJAX)下载JSON数据文件。但是,我不确定随后如何确保从缓存中提取数据。
只是想知道其他人如何处理此问题...
答案 0 :(得分:0)
由于这个问题风风雨雨,我决定发布尝试的结果。
基于Jake's article,我使用以下脚本和Chrome DevTools研究服务工作者事件:
'use strict';
let container = null;
let updateFound = false;
let newInstall = false;
window.onload = () => {
container = document.querySelector('.container');
let loading = document.createElement('div');
loading.classList.add('loading');
loading.innerHTML = 'Downloading application.<br>Please wait...';
container.appendChild(loading);
console.log(`window.onload: ${Date.now()}`);
swEvents();
};
let swEvents = () => {
if (navigator.serviceWorker) {
navigator.serviceWorker.ready.then(() => {
console.log(`sw.ready: ${Date.now()}`);
if (!updateFound) {
loadApp();
return;
}
newInstall = true;
console.log(`new install: ${Date.now()}`);
}).catch((error) => {
console.log(`sw.ready error: ${error.message}`);
});
}
navigator.serviceWorker.register('/sw.js').then((reg) => {
reg.onupdatefound = () => {
updateFound = true;
console.log(`reg.updatefound: ${Date.now()}`);
const newWorker = reg.installing;
newWorker.onstatechange = (event) => {
if (event.target.state === 'activated') {
console.log(`nw.activated: ${Date.now()}`);
if (newInstall) {
loadApp();
return;
}
refresh();
}
};
};
}).catch((error) => {
console.log(`reg.error: ${error.message}`);
});
};
let refresh = () => {
console.log(`refresh(): ${Date.now()}`);
// window.location.reload(true);
};
let loadApp = () => {
console.log(`loadApp(): ${Date.now()}`);
let child;
while (child = container.firstChild) {
container.removeChild(child);
}
let message = document.createComment('p');
message.textContent = 'Application loading';
container.appendChild(message);
let tag = document.createElement('script');
tag.src = './app.js';
document.body.appendChild(tag);
};
在整个过程中,我了解到注册了服务工作者后,它将立即开始下载所有缓存的资源。我以为资源仅在页面加载后才被缓存。我还发现了一些确定的事件模式,以指示发生了哪个生命周期阶段。
对于新安装,上述脚本中记录了以下事件:
window.onload -> reg.updatefound -> sw.ready -> nw.activated
在这种情况下,当sw.ready
触发时,所有资源都已缓存。此时,我可以从“请稍候”阶段切换应用程序,并动态加载缓存的资源并启动应用程序。
要进行简单的页面刷新,将记录以下事件:
window.onload -> sw.ready
如果已经下载了该应用并且没有可用的更新,则将是事件序列。此时,我可以再次切换相位并启动应用程序。
要在更新Service Worker脚本后刷新页面,将记录以下事件:
window.onload -> sw.ready -> reg.updatefound -> nw.activated
在这种情况下,当nw.activated
触发时,所有缓存的资源都已更新。需要重新刷新页面才能实际加载更改。此时,可以提示用户进行更新。否则,该应用将在下次启动时自行更新。
通过跟踪这些事件模式,很容易知道服务人员处于哪个生命周期阶段并采取适当的措施。