Skip to content

Commit a8025a8

Browse files
committed
👌 优化 SW 性能
1 parent 6b7302b commit a8025a8

File tree

14 files changed

+480
-95
lines changed

14 files changed

+480
-95
lines changed

_config.butterfly.yml

+9-7
Original file line numberDiff line numberDiff line change
@@ -947,9 +947,9 @@ pjax:
947947
enable: true
948948
exclude:
949949
- /music/
950-
- /blogroll/
951-
- /moments/
952-
- /essay/
950+
# - /blogroll/
951+
# - /moments/
952+
# - /essay/
953953
# - /about/
954954

955955
# Inject the css and script (aplayer/meting)
@@ -1026,16 +1026,16 @@ inject:
10261026
# - <script src="https://cdn.staticfile.org/jquery/3.5.1/jquery.min.js"></script>
10271027
# - <div id="music" key="6208da041a763" api="https://music.mx142.ltd"></div><script id="xplayer" src="https://music.mx142.ltd/Static/player4/js/player.js" ></script>
10281028

1029+
# CDN
10291030
# Don't modify the following settings unless you know how they work
10301031
# 非必要請不要修改
1031-
10321032
CDN:
10331033
# The CDN provider of internal scripts (主題內部 js 的 cdn 配置)
1034-
# option: local/jsdelivr
1035-
# Dev version cannot choose jsdelivr (dev版的主題不能設置為 jsdelivr)
1034+
# option: local/jsdelivr/unpkg
1035+
# Dev version cannot choose jsdelivr/unpkg (dev版的主題不能設置為 jsdelivr/unpkg)
10361036
internal_provider: local
10371037
# The CDN provider of third party scripts (第三方 js 的 cdn 配置)
1038-
# option: local/jsdelivr
1038+
# option: local/jsdelivr/unpkg
10391039
# when set it to local, you need to install hexo-butterfly-extjs
10401040
third_party_provider: jsdelivr
10411041
option:
@@ -1045,6 +1045,7 @@ CDN:
10451045
# translate:
10461046
# local_search:
10471047
# algolia_js:
1048+
10481049
# algolia_search_v4:
10491050
# instantsearch_v4:
10501051
# pjax:
@@ -1089,6 +1090,7 @@ CDN:
10891090
# prismjs_js:
10901091
# prismjs_lineNumber_js:
10911092
# prismjs_autoloader:
1093+
10921094
# other
10931095
statuspage: https://ccknbc.statuspage.io/embed/script.js
10941096
pace: https://gcore.jsdelivr.net/gh/CodeByZach/pace/pace.min.js

gulpfile.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ gulp.task('generate-service-worker', () => {
5454
swSrc: './sw.js',
5555
swDest: './public/sw.js',
5656
globDirectory: './public',
57-
globPatterns: ['index.html','**/*.{css,js}'],
57+
globPatterns: ['{index,404}.html'],
5858
modifyURLPrefix: {
5959
'': './'
6060
}

sw.js

+145-10
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ workbox.precaching.precacheAndRoute(self.__WB_MANIFEST, {
5151

5252
// CDN
5353
workbox.routing.registerRoute(
54-
/\.(?:js|css)$/,
54+
/\.(?:js|css|json)$/,
5555
new workbox.strategies.StaleWhileRevalidate({
5656
cacheName: 'assets',
5757
plugins: [
@@ -87,13 +87,13 @@ workbox.routing.registerRoute(
8787
);
8888

8989
// Catch routing errors, like if the user is offline
90-
// setCatchHandler(async ({ event }) => {
91-
// // Return the precached offline page if a document is being requested
92-
// if (event.request.destination === 'document') {
93-
// return matchPrecache('/404.html');
94-
// }
95-
// return Response.error();
96-
// });
90+
workbox.routing.setCatchHandler(async ({ event }) => {
91+
// Return the precached offline page if a document is being requested
92+
if (event.request.destination === 'document') {
93+
return matchPrecache('/404.html');
94+
}
95+
return Response.error();
96+
});
9797

9898
// Fonts
9999
// workbox.routing.registerRoute(
@@ -152,8 +152,143 @@ workbox.routing.registerRoute(
152152
// })
153153
// );
154154

155+
workbox.precaching.cleanupOutdatedCaches();
155156

157+
// workbox.googleAnalytics.initialize();
156158

157-
workbox.precaching.cleanupOutdatedCaches();
159+
const cdn = {
160+
gh: {
161+
jsdelivr: 'https://cdn.jsdelivr.net/gh',
162+
fastly: 'https://fastly.jsdelivr.net/gh',
163+
gcore: 'https://gcore.jsdelivr.net/gh',
164+
testingcf: 'https://testingcf.jsdelivr.net/gh',
165+
test1: 'https://test1.jsdelivr.net/gh',
166+
tianli: 'https://cdn1.tianli0.top/gh'
167+
},
168+
combine: {
169+
jsdelivr: 'https://cdn.jsdelivr.net/combine',
170+
fastly: 'https://fastly.jsdelivr.net/combine',
171+
gcore: 'https://gcore.jsdelivr.net/combine',
172+
testingcf: 'https://testingcf.jsdelivr.net/combine',
173+
test1: 'https://test1.jsdelivr.net/combine',
174+
tianli: 'https://cdn1.tianli0.top/combine'
175+
},
176+
npm: {
177+
jsdelivr: 'https://cdn.jsdelivr.net/npm',
178+
fastly: 'https://fastly.jsdelivr.net/npm',
179+
gcore: 'https://gcore.jsdelivr.net/npm',
180+
testingcf: 'https://testingcf.jsdelivr.net/npm',
181+
test1: 'https://test1.jsdelivr.net/npm',
182+
eleme: 'https://npm.elemecdn.com',
183+
unpkg: 'https://unpkg.com',
184+
tianli: 'https://cdn1.tianli0.top/npm'
185+
}
186+
}
187+
188+
// self.addEventListener('install', async () => {
189+
// await self.skipWaiting()
190+
// })
191+
192+
// self.addEventListener('activate', async () => {
193+
// await self.clients.claim()
194+
// })
195+
196+
self.addEventListener('fetch', async (event) => {
197+
try {
198+
// 如果用户当前网速慢,或是开启了省流模式,则不使用sw处理请求
199+
const nav = navigator
200+
const { saveData, effectiveType } = nav.connection || nav.mozConnection || nav.webkitConnection || {}
201+
if (saveData || /2g/.test(effectiveType)) return
202+
203+
// 劫持请求
204+
event.respondWith(handleRequest(event.request))
205+
// eslint-disable-next-line
206+
} catch (e) { }
207+
})
208+
209+
// 返回响应
210+
async function progress(res) {
211+
return new Response(await res.arrayBuffer(), {
212+
status: res.status,
213+
headers: res.headers
214+
})
215+
}
216+
217+
function handleRequest(req) {
218+
const urls = []
219+
const urlStr = req.url
220+
let urlObj = new URL(urlStr)
221+
// 为了获取 cdn 类型
222+
// 例如获取gh (https://cdn.jsdelivr.net/gh)
223+
const path = urlObj.pathname.split('/')[1]
158224

159-
// workbox.googleAnalytics.initialize();
225+
// 匹配 cdn
226+
for (const type in cdn) {
227+
if (type === path) {
228+
for (const key in cdn[type]) {
229+
const url = cdn[type][key] + urlObj.pathname.replace('/' + path, '')
230+
urls.push(url)
231+
}
232+
}
233+
}
234+
235+
// 如果上方 cdn 遍历 匹配到 cdn 则直接统一发送请求
236+
if (urls.length) return fetchAny(urls)
237+
throw new Error('failure')
238+
}
239+
240+
// Promise.any 的 polyfill
241+
function createPromiseAny() {
242+
Promise.any = function (promises) {
243+
return new Promise((resolve, reject) => {
244+
promises = Array.isArray(promises) ? promises : []
245+
let len = promises.length
246+
let errs = []
247+
if (len === 0) return reject(new AggregateError('All promises were rejected'))
248+
promises.forEach((p) => {
249+
if (p instanceof Promise) {
250+
p.then(
251+
(res) => resolve(res),
252+
(err) => {
253+
len--
254+
errs.push(err)
255+
if (len === 0) reject(new AggregateError(errs))
256+
}
257+
)
258+
} else {
259+
reject(p)
260+
}
261+
})
262+
})
263+
}
264+
}
265+
266+
// 发送所有请求
267+
function fetchAny(urls) {
268+
// 中断一个或多个请求
269+
const controller = new AbortController()
270+
const signal = controller.signal
271+
272+
// 遍历将所有的请求地址转换为promise
273+
const PromiseAll = urls.map((url) => {
274+
return new Promise((resolve, reject) => {
275+
fetch(url, { signal })
276+
.then(progress)
277+
.then((res) => {
278+
const r = res.clone()
279+
if (r.status !== 200) reject(null)
280+
controller.abort() // 中断
281+
resolve(r)
282+
})
283+
.catch(() => reject(null))
284+
})
285+
})
286+
287+
// 判断浏览器是否支持 Promise.any
288+
if (!Promise.any) createPromiseAny()
289+
290+
// 谁先返回"成功状态"则返回谁的内容,如果都返回"失败状态"则返回null
291+
return Promise.any(PromiseAll)
292+
.then((res) => res)
293+
.catch(() => null)
294+
}

themes/butterfly/.github/stale.yml

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Number of days of inactivity before an issue becomes stale
2+
daysUntilStale: 30
3+
# Number of days of inactivity before a stale issue is closed
4+
daysUntilClose: 7
5+
# Issues with these labels will never be considered stale
6+
exemptLabels:
7+
- pinned
8+
- security
9+
- bug
10+
- enhancement
11+
- documentation
12+
# Label to use when marking an issue as stale
13+
staleLabel: stale
14+
# Comment to post when marking an issue as stale. Set to `false` to disable
15+
markComment: >
16+
This issue has been automatically marked as stale because it has not had
17+
recent activity. It will be closed if no further activity occurs. Thank you
18+
for your contributions.
19+
# Comment to post when closing a stale issue. Set to `false` to disable
20+
closeComment: false
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
name: npm publish
2+
3+
on:
4+
release:
5+
types: [created]
6+
jobs:
7+
build:
8+
runs-on: ubuntu-latest
9+
steps:
10+
- uses: actions/checkout@v2
11+
# Setup .npmrc file to publish to npm
12+
- uses: actions/setup-node@v1
13+
with:
14+
node-version: '12.x'
15+
registry-url: 'https://registry.npmjs.org'
16+
- run: npm install
17+
- run: npm publish
18+
env:
19+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

0 commit comments

Comments
 (0)