aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Moon Flower <mforoud86@gmail.com> 2026-01-01 11:14:09 +0330
committerGravatar Moon Flower <mforoud86@gmail.com> 2026-01-01 11:14:09 +0330
commit91e0f2f93ee44922ad0d58fc6d7d3b92a5a2f30d (patch)
treec637ca16f7c5a031b4242eae09652b78ee6c4bfd
parenttimestamp (diff)
first-paint cache + sw
-rw-r--r--index.html32
-rw-r--r--serviceWorker.js52
2 files changed, 80 insertions, 4 deletions
diff --git a/index.html b/index.html
index 350f379..04f7bc3 100644
--- a/index.html
+++ b/index.html
@@ -63,7 +63,9 @@
</noscript>
<div id='warnings'></div>
- <div id='content'></div>
+ <div id='content'>
+ rendering content...
+ </div>
<div>
tempo is licensed under creative-commons.
<br>
@@ -79,6 +81,17 @@
</a>
</div>
<script>
+ if ('serviceWorker' in navigator) {
+ window.addEventListener('load', () => {
+ navigator.serviceWorker.register('/serviceWorker.js')
+ .then(reg => console.log('Service Worker registered'))
+ .catch(err => console.log('SW registration failed', err))
+ })
+ } else {
+ console.log('[warn] no service worker support')
+ }
+ </script>
+ <script>
function escapeHTML(str) {
if (!str) return ''
const a = []
@@ -334,7 +347,7 @@
const defPattern = /^def\s+(\S+)/gm
while ((match = defPattern.exec(text)) !== null) {
- console.log('defined:', match[1])
+ // console.log('defined:', match[1])
definedSymbols.add(match[1].replace(/^\\/g, '').replace(/\\$/g, ''))
}
@@ -371,15 +384,26 @@
parser.tokenize()
const html = parser.render()
+ // store first 4kb of website in local storage
document.getElementById('content').innerHTML = html
-
+ try {
+ localStorage.setItem('rendered', html.substring(0, 32768))
+ } catch (err) {
+ console.log('[warn] localStorage caching failed. subsequent loads will not benefit from first-paint rendering.')
+ }
} catch (err) {
console.error("failed to load tempo file:", err)
document.getElementById('content').innerHTML = "<p>error loading content.</p>"
}
}
- loadMarkdown().then(e => document.querySelector('script').remove())
+ const title = document.title
+ const previousRender = localStorage.getItem('rendered')
+ if (previousRender) {
+ document.title = 'contents are stale...'
+ content.innerHTMl = previousRender
+ }
+ loadMarkdown().then(e => document.title = title)
</script>
<script>
diff --git a/serviceWorker.js b/serviceWorker.js
new file mode 100644
index 0000000..ba9ca7a
--- /dev/null
+++ b/serviceWorker.js
@@ -0,0 +1,52 @@
+const CACHE_NAME = 'offline-cache-v1'
+const ASSETS = [
+ '/',
+ '/index.html',
+ '/styles.css',
+ '/styles3.css',
+ '/tempo.md',
+ '/bell.png',
+ '/bell.svg',
+ '/by-sa.png',
+ '/cc-by-sa-legalcode.txt',
+ '/symbols.txt'
+]
+
+self.addEventListener('install', e => {
+ console.log('installing sw')
+ e.waitUntil(caches.open(CACHE_NAME).then(cache => cache.addAll(ASSETS)))
+ self.skipWaiting()
+})
+
+self.addEventListener('activate', e => {
+ console.log('sw activated')
+ e.waitUntil(self.clients.claim())
+})
+
+self.addEventListener('fetch', e => {
+ const url = new URL(e.request.url)
+ const isTarget = ASSETS.includes(url.pathname) || url.pathname.startsWith('/fonts/')
+
+ if (!isTarget) return
+
+ e.respondWith(
+ caches.open(CACHE_NAME).then(async cache => {
+ const cachedResponse = await cache.match(e.request)
+
+ if (cachedResponse) console.log(`cache ${url.pathname}`)
+ else console.log(`fetch ${url.pathname}`)
+
+ const networkFetch = fetch(e.request).then(networkResponse => {
+ if (networkResponse.ok) {
+ console.log(`updating ${url.pathname}`)
+ cache.put(e.request, networkResponse.clone())
+ }
+ return networkResponse
+ }).catch(err => {
+ console.error(`failed ${url.pathname}:`, err)
+ })
+
+ return cachedResponse || networkFetch
+ })
+ )
+}) \ No newline at end of file