From afb06d988e955b54da9a5b89ed3a16821e9e0617 Mon Sep 17 00:00:00 2001 From: Nolan Lawson Date: Mon, 14 Oct 2019 20:00:57 -0700 Subject: [PATCH] perf: use webpack contenthash for better caching (#1573) --- src/routes/_api/stream/TimelineStream.js | 2 +- src/routes/_database/databaseLifecycle.js | 2 +- src/routes/_database/knownInstances.js | 2 +- src/routes/_store/LocalStorageStore.js | 2 +- src/routes/_utils/asyncModules.js | 4 ++++ src/routes/_utils/lifecycle.js | 21 +++++++++++++++++++++ src/routes/_utils/scheduleInterval.js | 2 +- webpack/client.config.js | 11 +++++++---- webpack/server.config.js | 1 - webpack/terser.config.js | 2 +- 10 files changed, 38 insertions(+), 11 deletions(-) create mode 100644 src/routes/_utils/lifecycle.js diff --git a/src/routes/_api/stream/TimelineStream.js b/src/routes/_api/stream/TimelineStream.js index 93de679e..a6cb158c 100644 --- a/src/routes/_api/stream/TimelineStream.js +++ b/src/routes/_api/stream/TimelineStream.js @@ -1,5 +1,5 @@ import { WebSocketClient } from '../../_thirdparty/websocket/websocket' -import lifecycle from 'page-lifecycle/dist/lifecycle.mjs' +import { lifecycle } from '../../_utils/lifecycle' import { getStreamUrl } from './getStreamUrl' import { EventEmitter } from 'events-light' import { eventBus } from '../../_utils/eventBus' diff --git a/src/routes/_database/databaseLifecycle.js b/src/routes/_database/databaseLifecycle.js index 5bd89a98..30d05f7c 100644 --- a/src/routes/_database/databaseLifecycle.js +++ b/src/routes/_database/databaseLifecycle.js @@ -2,7 +2,7 @@ import { DB_VERSION_CURRENT } from './constants' import { addKnownInstance, deleteKnownInstance } from './knownInstances' import { migrations } from './migrations' import { clearAllCaches } from './cache' -import lifecycle from 'page-lifecycle/dist/lifecycle.mjs' +import { lifecycle } from '../_utils/lifecycle' const openReqs = {} const databaseCache = {} diff --git a/src/routes/_database/knownInstances.js b/src/routes/_database/knownInstances.js index 81f529bb..8d917a25 100644 --- a/src/routes/_database/knownInstances.js +++ b/src/routes/_database/knownInstances.js @@ -1,5 +1,5 @@ import { set, keys, del, close } from '../_thirdparty/idb-keyval/idb-keyval' -import lifecycle from 'page-lifecycle/dist/lifecycle.mjs' +import { lifecycle } from '../_utils/lifecycle' const PREFIX = 'known-instance-' diff --git a/src/routes/_store/LocalStorageStore.js b/src/routes/_store/LocalStorageStore.js index 9cbe7836..d5644b61 100644 --- a/src/routes/_store/LocalStorageStore.js +++ b/src/routes/_store/LocalStorageStore.js @@ -1,6 +1,6 @@ import { Store } from 'svelte/store' import { safeLocalStorage as LS } from '../_utils/safeLocalStorage' -import lifecycle from 'page-lifecycle/dist/lifecycle.mjs' +import { lifecycle } from '../_utils/lifecycle' import { safeParse } from './safeParse' export class LocalStorageStore extends Store { diff --git a/src/routes/_utils/asyncModules.js b/src/routes/_utils/asyncModules.js index 9436ade2..60743c1b 100644 --- a/src/routes/_utils/asyncModules.js +++ b/src/routes/_utils/asyncModules.js @@ -55,3 +55,7 @@ export const importTesseractWorker = () => import( export const importVirtualListStore = () => import( /* webpackChunkName: 'virtualListStore.js' */ '../_components/virtualList/virtualListStore.js' ) + +export const importPageLifecycle = () => import( + /* webpackChunkName: 'page-lifecycle' */ 'page-lifecycle/dist/lifecycle.mjs' +).then(getDefault) diff --git a/src/routes/_utils/lifecycle.js b/src/routes/_utils/lifecycle.js new file mode 100644 index 00000000..673e076c --- /dev/null +++ b/src/routes/_utils/lifecycle.js @@ -0,0 +1,21 @@ +// the page-lifecycle package causes some problems (doesn't work in node), +// and plus it's not needed immediately, so lazy-load it +import { importPageLifecycle } from './asyncModules' + +function addEventListener (event, func) { + if (process.browser) { + importPageLifecycle().then(lifecycle => { + lifecycle.addEventListener(event, func) + }) + } +} + +function removeEventListener (event, func) { + if (process.browser) { + importPageLifecycle().then(lifecycle => { + lifecycle.removeEventListener(event, func) + }) + } +} + +export const lifecycle = { addEventListener, removeEventListener } diff --git a/src/routes/_utils/scheduleInterval.js b/src/routes/_utils/scheduleInterval.js index 6df23eae..323285cd 100644 --- a/src/routes/_utils/scheduleInterval.js +++ b/src/routes/_utils/scheduleInterval.js @@ -1,4 +1,4 @@ -import lifecycle from 'page-lifecycle/dist/lifecycle.mjs' +import { lifecycle } from './lifecycle' /** * Schedule a callback, similar to setInterval but disables itself when the page is not active to save battery/CPU. diff --git a/webpack/client.config.js b/webpack/client.config.js index 0badbb41..d80f6e36 100644 --- a/webpack/client.config.js +++ b/webpack/client.config.js @@ -13,8 +13,8 @@ const output = Object.assign(config.client.output(), { // enables HMR in workers globalObject: 'this', // Zeit does not like filenames with "$" in them, so just keep things simple - filename: '[hash]/[id].js', - chunkFilename: '[hash]/[id].js' + filename: dev ? '[hash]/[id].js' : '[id].[contenthash].js', + chunkFilename: dev ? '[hash]/[id].js' : '[id].[contenthash].js' }) module.exports = { @@ -29,7 +29,7 @@ module.exports = { use: { loader: 'worker-loader', options: { - name: 'blurhash.[hash].[name].[ext]' + name: dev ? '[hash]/blurhash.[name].[ext]' : 'blurhash.[contenthash].[name].[ext]' } } }, @@ -43,7 +43,7 @@ module.exports = { use: { loader: 'file-loader', options: { - name: 'tesseract-asset.[hash].[name].[ext]' + name: dev ? '[hash]/tesseract-asset.[name].[ext]' : 'tesseract-asset.[contenthash].[name].[ext]' } } }, @@ -90,6 +90,9 @@ module.exports = { minimizer: [ terser() ], + // TODO: we should be able to enable this, but Sapper breaks if we do so + // // isolate runtime chunk to avoid excessive cache invalidations https://webpack.js.org/guides/caching/ + // runtimeChunk: 'single', splitChunks: { chunks: 'async', minSize: 5000, diff --git a/webpack/server.config.js b/webpack/server.config.js index 609578ce..c8aa3133 100644 --- a/webpack/server.config.js +++ b/webpack/server.config.js @@ -6,7 +6,6 @@ const { mode, dev, resolve, inlineSvgs, allSvgs } = require('./shared.config') // modules that the server should ignore, either because they cause errors or warnings // (because they're only used on the client side) const NOOP_MODULES = [ - 'page-lifecycle/dist/lifecycle.mjs', '../_workers/blurhash', 'tesseract.js/dist/worker.min.js', 'tesseract.js/dist/worker.min.js.map', diff --git a/webpack/terser.config.js b/webpack/terser.config.js index d8ec091f..6409e474 100644 --- a/webpack/terser.config.js +++ b/webpack/terser.config.js @@ -1,7 +1,7 @@ const TerserWebpackPlugin = require('terser-webpack-plugin') module.exports = () => new TerserWebpackPlugin({ - exclude: /tesseract-asset/, + exclude: /(tesseract-asset|page-lifecycle)/, // tesseract causes problems, page-lifecycle is pre-minified cache: !process.env.TERSER_DISABLE_CACHE, parallel: true, sourceMap: true,