几天以来我一直在尝试使用 workbox 提供离线功能到我的 Django Web 应用程序但没有成功。
我已关注get started guide我成功地注册了服务 worker ,并从缓存中保存/提供静态和媒体资源。
完成的代码存档描述:
url.py
...
url(r'^service-worker.js', cache_control(max_age=60*60*24)(TemplateView.as_view(
template_name="sw.js",
content_type='application/javascript',
)), name='sw.js'),
...
base.html 模板
...
<!-- bottom of body -->
<script>
// Check that service workers are registered
if ('serviceWorker' in navigator) {
// Use the window load event to keep the page load performant
window.addEventListener('load', () => {
navigator.serviceWorker.register('{% url 'sw.js' %}');
});
}
</script>
...
sw.js(服务 worker )
importScripts('https://storage.googleapis.com/workbox-cdn/releases/3.2.0/workbox-sw.js');
if (workbox) {
console.log(`Yay! Workbox is loaded 🎉`);
} else {
console.log(`Boo! Workbox didn't load 😬`);
}
workbox.setConfig({
debug: false
});
// workbox.core.setLogLevel(workbox.core.LOG_LEVELS.debug);
workbox.routing.registerRoute(
/\.(?:js|css)$/,
workbox.strategies.staleWhileRevalidate({
cacheName: 'static-resources',
}),
);
workbox.routing.registerRoute(
/\.(?:png|gif|jpg|jpeg|svg)$/,
workbox.strategies.cacheFirst({
cacheName: 'images',
plugins: [
new workbox.expiration.Plugin({
maxEntries: 60,
maxAgeSeconds: 30 * 24 * 60 * 60, // 30 Days
}),
],
}),
);
workbox.routing.registerRoute(
new RegExp('https://fonts.(?:googleapis|gstatic).com/(.*)'),
workbox.strategies.cacheFirst({
cacheName: 'googleapis',
plugins: [
new workbox.expiration.Plugin({
maxEntries: 30,
}),
],
}),
);
此后,我决定检查性能,看看服务工作线程是否帮助我的应用比以前更快地提供缓存文件。
我在这里留下 2 个屏幕截图供您检查(加载时间在右下角以红色显示):
516m,没有服务 worker ,使用默认的 django 缓存
在此之后我不得不说我很震惊,我期待着改进,但我得到了相反的结果(我在前面的步骤中做错了什么?)
之后我做了更多测试,在大多数其他情况下,加载时间是相似的,但我仍然没有看到有利于服务 worker 的大差异,特别是在第一次访问时
但对于另一部分,我在想,好吧,500ms~如果我获得离线功能,这是一个合理的价格,但甚至不是......
我将以下几行添加到服务工作人员中,以便在没有网络时为页面提供服务:
workbox.precaching.precacheAndRoute(
[
'/',
'/offline',
],
{
directoryIndex: null,
}
);
workbox.routing.registerRoute(
/* my urls doesn't end in html, so i didn't found another way to
store only the html document except using the main route of my app as reg ex
example: http://localhost:8000/participation/id/title -> html for article
http://localhost:8000/participation/ -> html for list of articles */
new RegExp('participation/'),
workbox.strategies.networkFirst({
cacheName: 'html-resources',
})
);
所以现在,如果我在某些参与页面处于离线状态,我仍然可以看到它们,但这导致我遇到了实际问题。
好吧,所以如果用户现在尝试在没有网络的情况下访问以前从未访问过的页面,我想将他发送到我的离线页面,我只是向他显示他处于离线状态,并且他可以转到他已经访问过的 X 个页面访问
我没有找到解决这个问题的方法,我尝试一下:
workbox.routing.registerRoute(
({ event }) => event.request.mode === 'navigate', //if the requests is to go to a new url
({ url }) => fetch(url.href,{credentials: 'same-origin'}).catch(() => caches.match('/offline')) //in case of not match send my to the offline page
);
但是根本不起作用,我该如何做到这一点?
最佳答案
我通过将其添加到服务工作线程中解决了问题
// Fallback to offline page if nothing is found in cache
var networkFirstHandler = workbox.strategies.networkFirst({
cacheName: 'default',
plugins: [
new workbox.expiration.Plugin({
maxEntries: 10
}),
new workbox.cacheableResponse.Plugin({
statuses: [200]
})
]
});
const matcher = ({event}) => event.request.mode === 'navigate';
const handler = (args) => networkFirstHandler.handle(args).then((response) => (!response) ? caches.match('/offline') : response);
workbox.routing.registerRoute(matcher, handler);
// End fallback offline
关于python - Service Worker 让我的网络速度变慢! 、如何使用workbox为Django work添加离线功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50901503/