use service worker to cache resources

This commit is contained in:
Pig Fang 2020-05-19 17:02:54 +08:00
parent 6d84747458
commit 68d57da1d9
9 changed files with 110 additions and 6 deletions

2
.gitignore vendored
View File

@ -26,4 +26,4 @@ storage/options.php
.phpunit.result.cache .phpunit.result.cache
.php_cs.cache .php_cs.cache
resources/views/overrides resources/views/overrides
public/bg public/sw.js

View File

@ -84,14 +84,12 @@ class HeadComposer
'rel' => 'preload', 'rel' => 'preload',
'as' => 'font', 'as' => 'font',
'href' => 'https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@5.13.0/webfonts/fa-solid-900.woff2', 'href' => 'https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@5.13.0/webfonts/fa-solid-900.woff2',
'integrity' => 'sha256-f00/0KcF2/hAMpiq2R1d5pcua11TYGjrqLJJVKWgqMc=',
'crossorigin' => 'anonymous', 'crossorigin' => 'anonymous',
]; ];
$links[] = [ $links[] = [
'rel' => 'preload', 'rel' => 'preload',
'as' => 'font', 'as' => 'font',
'href' => 'https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@5.13.0/webfonts/fa-regular-400.woff2', 'href' => 'https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@5.13.0/webfonts/fa-regular-400.woff2',
'integrity' => 'sha256-aoyOnh5/aSwhrxlW3hY/PQJneOZEn+k6CaZxhHyhrmU=',
'crossorigin' => 'anonymous', 'crossorigin' => 'anonymous',
]; ];
$links[] = [ $links[] = [
@ -103,6 +101,7 @@ class HeadComposer
$links[] = ['rel' => 'stylesheet', 'href' => $this->webpack->url('style.css')]; $links[] = ['rel' => 'stylesheet', 'href' => $this->webpack->url('style.css')];
$view->with('links', $links); $view->with('links', $links);
$view->with('inline_css', option('custom_css')); $view->with('inline_css', option('custom_css'));
$view->with('workbox', $this->webpack->url('workbox.js'));
} }
public function addExtra(View $view) public function addExtra(View $view)

View File

@ -40,6 +40,9 @@
"skinview3d": "^1.2.1", "skinview3d": "^1.2.1",
"spectre.css": "^0.5.8", "spectre.css": "^0.5.8",
"use-immer": "^0.4.0", "use-immer": "^0.4.0",
"workbox-expiration": "^5.1.3",
"workbox-routing": "^5.1.3",
"workbox-strategies": "^5.1.3",
"xterm": "^4.6.0", "xterm": "^4.6.0",
"xterm-addon-fit": "^0.4.0" "xterm-addon-fit": "^0.4.0"
}, },

View File

@ -0,0 +1,62 @@
import { registerRoute } from 'workbox-routing'
import { CacheFirst, StaleWhileRevalidate } from 'workbox-strategies'
import { ExpirationPlugin } from 'workbox-expiration'
registerRoute(
/\/preview\/\d+/,
new CacheFirst({
cacheName: 'texture-preview-v1',
fetchOptions: {
credentials: 'omit',
},
plugins: [new ExpirationPlugin({ maxAgeSeconds: 7 * 24 * 60 * 60 })],
}),
)
registerRoute(
/\/app\/.*\.png/,
new StaleWhileRevalidate({
cacheName: 'png-resource-v1',
fetchOptions: {
credentials: 'omit',
},
}),
)
registerRoute(
/\/avatar\/user\/\d+/,
new StaleWhileRevalidate({
cacheName: 'png-resource-v1',
fetchOptions: {
credentials: 'omit',
},
}),
)
registerRoute(
({ request }) => request.destination === 'script',
new StaleWhileRevalidate({
cacheName: 'javascript-v1',
fetchOptions: {
credentials: 'omit',
},
}),
)
registerRoute(
({ request }) => request.destination === 'style',
new StaleWhileRevalidate({
cacheName: 'stylesheet-v1',
fetchOptions: {
credentials: 'omit',
},
}),
)
registerRoute(
({ request }) => request.destination === 'font',
new StaleWhileRevalidate({
cacheName: 'font-v1',
fetchOptions: {
credentials: 'omit',
},
}),
)

View File

@ -1,7 +1,6 @@
{% for script in scripts %} {% for script in scripts %}
<script{% for attribute, value in script %} {{ attribute }}="{{ value }}"{% endfor %}></script> <script{% for attribute, value in script %} {{ attribute }}="{{ value }}"{% endfor %}></script>
{% endfor %} {% endfor %}
<script> <script>
{{ inline_js|striptags('<div><span><ul><li><p><a><img><i>')|raw }} {{ inline_js|striptags('<div><span><ul><li><p><a><img><i>')|raw }}
</script> </script>

View File

@ -6,6 +6,11 @@
<meta name="keywords" content="{{ seo.keywords }}"> <meta name="keywords" content="{{ seo.keywords }}">
<meta name="description" content="{{ seo.description }}"> <meta name="description" content="{{ seo.description }}">
{{ seo.extra|striptags('<meta>')|raw }} {{ seo.extra|striptags('<meta>')|raw }}
<script>
window.addEventListener('load', () => {
navigator.serviceWorker.register('/sw.js')
})
</script>
{% for link in links %} {% for link in links %}
<link{% for attribute, value in link %} {{ attribute }}="{{ value }}"{% endfor %}> <link{% for attribute, value in link %} {{ attribute }}="{{ value }}"{% endfor %}>
{% endfor %} {% endfor %}

View File

@ -12,6 +12,7 @@ if (Test-Path ./public/app) {
# Run webpack # Run webpack
yarn build yarn build
Move-Item -Path ./public/app/sw.js -Destination ./public -Force
if ($Simple) { if ($Simple) {
exit exit

View File

@ -11,6 +11,7 @@ const config = {
mode: devMode ? 'development' : 'production', mode: devMode ? 'development' : 'production',
entry: { entry: {
app: ['react-hot-loader/patch', '@/index.tsx'], app: ['react-hot-loader/patch', '@/index.tsx'],
sw: '@/scripts/sw.ts',
style: ['@/styles/common.css'], style: ['@/styles/common.css'],
home: '@/styles/home.css', home: '@/styles/home.css',
spectre: [ spectre: [
@ -21,7 +22,12 @@ const config = {
}, },
output: { output: {
path: `${__dirname}/public/app`, path: `${__dirname}/public/app`,
filename: devMode ? '[name].js' : '[name].[contenthash:7].js', filename: ({ chunk }) =>
chunk.name === 'sw'
? 'sw.js'
: devMode
? '[name].js'
: '[name].[contenthash:7].js',
chunkFilename: devMode ? '[id].js' : '[id].[contenthash:7].js', chunkFilename: devMode ? '[id].js' : '[id].[contenthash:7].js',
}, },
module: { module: {
@ -84,7 +90,9 @@ const config = {
}, },
), ),
optimization: { optimization: {
minimizer: [new TerserJSPlugin({})], minimizer: [
/*new TerserJSPlugin({})*/
],
}, },
devtool: devMode ? 'cheap-module-eval-source-map' : false, devtool: devMode ? 'cheap-module-eval-source-map' : false,
devServer: { devServer: {

View File

@ -9320,6 +9320,33 @@ wordwrap@~1.0.0:
resolved "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" resolved "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=
workbox-core@^5.1.3:
version "5.1.3"
resolved "https://registry.yarnpkg.com/workbox-core/-/workbox-core-5.1.3.tgz#0607acd0018c149162777fe4aae08553bd1559f5"
integrity sha512-TFSIPxxciX9sFaj0FDiohBeIKpwMcCyNduydi9i3LChItcndDS6TJpErxybv8aBWeCMraXt33TWtF6kKuIObNw==
workbox-expiration@^5.1.3:
version "5.1.3"
resolved "https://registry.yarnpkg.com/workbox-expiration/-/workbox-expiration-5.1.3.tgz#c793eef17513de86c9c1b8254eb2c9ba3ed17568"
integrity sha512-8YhpmIHqIx+xmtxONADc+di4a3zzCsvVHLiKq6T3vJZUPnqV2jzx+51+UHMUh3T5w5Z5SFC14l0V/jesRbuMKg==
dependencies:
workbox-core "^5.1.3"
workbox-routing@^5.1.3:
version "5.1.3"
resolved "https://registry.yarnpkg.com/workbox-routing/-/workbox-routing-5.1.3.tgz#9946da0e9ace45af3db09cc0b4bdc4696723e1f7"
integrity sha512-F+sAp9Iy3lVl3BEG+pzXWVq4AftzjiFpHDaZ4Kf4vLoBoKQE0hIHet4zE5DpHqYdyw+Udhp4wrfHamX6PN6z1Q==
dependencies:
workbox-core "^5.1.3"
workbox-strategies@^5.1.3:
version "5.1.3"
resolved "https://registry.yarnpkg.com/workbox-strategies/-/workbox-strategies-5.1.3.tgz#220cc9f5519ed76f2452ccb9407a5fd967c37110"
integrity sha512-wiXHfmOKnWABeIVW+/ye0e00+2CcS5y7SIj2f9zcdy2ZLEbcOf7B+yOl5OrWpBGlTUwRjIYhV++ZqiKm3Dc+8w==
dependencies:
workbox-core "^5.1.3"
workbox-routing "^5.1.3"
worker-farm@^1.7.0: worker-farm@^1.7.0:
version "1.7.0" version "1.7.0"
resolved "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8" resolved "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8"