From 68d57da1d9ce805a2af40094a2e7b72d73de780c Mon Sep 17 00:00:00 2001 From: Pig Fang Date: Tue, 19 May 2020 17:02:54 +0800 Subject: [PATCH] use service worker to cache resources --- .gitignore | 2 +- app/Http/View/Composers/HeadComposer.php | 3 +- package.json | 3 ++ resources/assets/src/scripts/sw.ts | 62 ++++++++++++++++++++++++ resources/views/shared/foot.twig | 1 - resources/views/shared/head.twig | 5 ++ scripts/build.ps1 | 1 + webpack.config.js | 12 ++++- yarn.lock | 27 +++++++++++ 9 files changed, 110 insertions(+), 6 deletions(-) create mode 100644 resources/assets/src/scripts/sw.ts diff --git a/.gitignore b/.gitignore index 5e371b9f..bf8e112b 100644 --- a/.gitignore +++ b/.gitignore @@ -26,4 +26,4 @@ storage/options.php .phpunit.result.cache .php_cs.cache resources/views/overrides -public/bg +public/sw.js diff --git a/app/Http/View/Composers/HeadComposer.php b/app/Http/View/Composers/HeadComposer.php index 6775113f..68c13ec7 100644 --- a/app/Http/View/Composers/HeadComposer.php +++ b/app/Http/View/Composers/HeadComposer.php @@ -84,14 +84,12 @@ class HeadComposer 'rel' => 'preload', 'as' => 'font', 'href' => 'https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@5.13.0/webfonts/fa-solid-900.woff2', - 'integrity' => 'sha256-f00/0KcF2/hAMpiq2R1d5pcua11TYGjrqLJJVKWgqMc=', 'crossorigin' => 'anonymous', ]; $links[] = [ 'rel' => 'preload', 'as' => 'font', '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', ]; $links[] = [ @@ -103,6 +101,7 @@ class HeadComposer $links[] = ['rel' => 'stylesheet', 'href' => $this->webpack->url('style.css')]; $view->with('links', $links); $view->with('inline_css', option('custom_css')); + $view->with('workbox', $this->webpack->url('workbox.js')); } public function addExtra(View $view) diff --git a/package.json b/package.json index 470512c8..f8a0db64 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,9 @@ "skinview3d": "^1.2.1", "spectre.css": "^0.5.8", "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-addon-fit": "^0.4.0" }, diff --git a/resources/assets/src/scripts/sw.ts b/resources/assets/src/scripts/sw.ts new file mode 100644 index 00000000..8397120e --- /dev/null +++ b/resources/assets/src/scripts/sw.ts @@ -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', + }, + }), +) diff --git a/resources/views/shared/foot.twig b/resources/views/shared/foot.twig index 00b2babe..69b5d11f 100644 --- a/resources/views/shared/foot.twig +++ b/resources/views/shared/foot.twig @@ -1,7 +1,6 @@ {% for script in scripts %} {% endfor %} - diff --git a/resources/views/shared/head.twig b/resources/views/shared/head.twig index 46324768..73160618 100644 --- a/resources/views/shared/head.twig +++ b/resources/views/shared/head.twig @@ -6,6 +6,11 @@ {{ seo.extra|striptags('')|raw }} + {% for link in links %} {% endfor %} diff --git a/scripts/build.ps1 b/scripts/build.ps1 index ffde505a..1ee9a983 100644 --- a/scripts/build.ps1 +++ b/scripts/build.ps1 @@ -12,6 +12,7 @@ if (Test-Path ./public/app) { # Run webpack yarn build +Move-Item -Path ./public/app/sw.js -Destination ./public -Force if ($Simple) { exit diff --git a/webpack.config.js b/webpack.config.js index b0d4f912..99036c05 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -11,6 +11,7 @@ const config = { mode: devMode ? 'development' : 'production', entry: { app: ['react-hot-loader/patch', '@/index.tsx'], + sw: '@/scripts/sw.ts', style: ['@/styles/common.css'], home: '@/styles/home.css', spectre: [ @@ -21,7 +22,12 @@ const config = { }, output: { 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', }, module: { @@ -84,7 +90,9 @@ const config = { }, ), optimization: { - minimizer: [new TerserJSPlugin({})], + minimizer: [ + /*new TerserJSPlugin({})*/ + ], }, devtool: devMode ? 'cheap-module-eval-source-map' : false, devServer: { diff --git a/yarn.lock b/yarn.lock index 5f1a3232..c3ca16ab 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9320,6 +9320,33 @@ wordwrap@~1.0.0: resolved "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" 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: version "1.7.0" resolved "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8"