From 14e5430a9d784fcf10fb8275afb481feeca5a90f Mon Sep 17 00:00:00 2001
From: Curtis Dulmage
Date: Fri, 26 Jul 2024 13:23:53 -0400
Subject: [PATCH] =?UTF-8?q?=F0=9F=92=84=20[PWA]=20Improve=20overall=20page?=
=?UTF-8?q?=20loading=20and=20caching=20(#61)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* :recycle: [OpenGraph] Add some additional twitter tags
* :bug: [Cursors] Bring back preloading
* :dizzy: [Page] Improve page loading
* :hammer_and_wrench: [PWA] Revise config
---
astro.config.mjs | 6 ++-
src/components/ContentBlock.astro | 6 +++
src/layouts/Page.astro | 46 ++++++++++++++++------
src/pages/404.astro | 12 ++++--
src/pages/index.astro | 4 +-
src/scripts/PageLoad.ts | 40 +++++++++++++++++++
src/sections/Intro.astro | 15 +++++---
src/styles/global.css | 64 +++++++++++++++++--------------
8 files changed, 142 insertions(+), 51 deletions(-)
create mode 100644 src/scripts/PageLoad.ts
diff --git a/astro.config.mjs b/astro.config.mjs
index b04f6fe..5135dc1 100644
--- a/astro.config.mjs
+++ b/astro.config.mjs
@@ -34,9 +34,11 @@ export default defineConfig({
AstroPWA({
workbox: {
// Not sure how this differs from `includeAssets`...
- // globPatterns: ['**/*.{js,css,html,ico,png,svg}'],
+ globPatterns: ['**/*.{css,js,html,woff2}', 'assets/*.{png,webp}'],
// Not sure if we actually want to specify this fallback.
- navigateFallback: '/404',
+ navigateFallback: '/',
+ // The `chicken` image is 2.2MB, so we increase the limit to 3MB.
+ maximumFileSizeToCacheInBytes: 3000000,
},
// Specify which public assets (in addition to the default html/css/js)
diff --git a/src/components/ContentBlock.astro b/src/components/ContentBlock.astro
index 61aa29f..3871967 100644
--- a/src/components/ContentBlock.astro
+++ b/src/components/ContentBlock.astro
@@ -63,6 +63,12 @@ const inactive = !title || !subtitle;
/* Just a small nudge for better vertical centering */
padding-top: calc(var(--space-tightest) + 0.1rem);
+ /* Consider improveing the legibility of text */
+ /*
+ background-color: rgb(255, 255, 255, 0.04);
+ backdrop-filter: blur(2px);
+ */
+
& > h3 {
font-weight: 800;
}
diff --git a/src/layouts/Page.astro b/src/layouts/Page.astro
index d30b4bf..77e59b9 100644
--- a/src/layouts/Page.astro
+++ b/src/layouts/Page.astro
@@ -27,7 +27,7 @@ const OG_IMAGE = new URL('/dulmage-social.png', Astro.site).href;
---
-
+
+
+
@@ -129,23 +131,45 @@ const OG_IMAGE = new URL('/dulmage-social.png', Astro.site).href;
display: flex;
justify-content: center;
}
+
+ /* --- Page load --- */
+
+ @keyframes pageLoadScreenCover {
+ from {
+ opacity: 1;
+ visibility: visible;
+ }
+ to {
+ opacity: 0;
+ visibility: hidden;
+ }
+ }
+
+ body {
+ position: relative;
+
+ &::after {
+ content: '';
+ z-index: var(--index-mesosphere);
+ position: fixed;
+ inset: 0;
+ pointer-events: none;
+ background-color: black;
+ }
+ }
+
+ html[data-ready='done'] body::after {
+ animation: pageLoadScreenCover var(--speed-slower) var(--ease) forwards;
+ }
diff --git a/src/pages/404.astro b/src/pages/404.astro
index ad74bec..7756be6 100644
--- a/src/pages/404.astro
+++ b/src/pages/404.astro
@@ -47,17 +47,23 @@ import Stars from '@components/Stars.astro';
}
}
- .ErrorContent {
+ :global(#Main404) {
--color-portfolio: hsl(var(--color-rainbow) 100% 50%);
+ animation: rainbowSpin 4s linear infinite both;
+ }
- position: relative;
+ .ErrorContent {
display: grid;
justify-content: center;
gap: var(--space-tight);
padding: var(--space);
text-align: center;
max-width: 90rem;
- animation: rainbowSpin 4s linear infinite both;
+
+ /* Page load (fade-in) */
+ position: relative;
+ z-index: var(--index-thermosphere);
+ animation: fadeIn var(--speed-slower) var(--speed-slow) var(--ease) both;
}
.ErrorContent h4 a {
diff --git a/src/pages/index.astro b/src/pages/index.astro
index 42b0d92..b23de78 100644
--- a/src/pages/index.astro
+++ b/src/pages/index.astro
@@ -4,6 +4,7 @@ import Page from '@layouts/Page.astro';
import {NAV_ID, NAV_TOGGLE_ID, OVERLAY_ID} from '@data/app';
import {sections} from '@data/sections';
+import Contact from '@components/Contact.astro';
import Hamburger from '@components/Hamburger.astro';
import Navigation from '@components/Navigation.astro';
import Project from '@components/Project.astro';
@@ -14,8 +15,9 @@ import ProjectOverlay from '@sections/ProjectOverlay.astro';
const [intro, ...portfolioSections] = sections;
---
-
+
+
diff --git a/src/scripts/PageLoad.ts b/src/scripts/PageLoad.ts
new file mode 100644
index 0000000..86cc8fa
--- /dev/null
+++ b/src/scripts/PageLoad.ts
@@ -0,0 +1,40 @@
+export type HtmlReady = 'loading' | 'done' | 'error';
+
+export class PageLoad {
+ static MOTION_DELAY = 1200;
+
+ static documentState() {
+ return document.readyState;
+ }
+
+ static isHome() {
+ const {pathname} = window.location;
+ return pathname === '' || pathname === '/';
+ }
+
+ static isLoaded() {
+ return document.documentElement.dataset.ready === 'done';
+ }
+
+ static schedule() {
+ if (PageLoad.documentState() === 'complete') {
+ PageLoad.#updateDocument();
+ return;
+ }
+
+ document.addEventListener('readystatechange', PageLoad.#handleReadyState);
+ }
+
+ static #handleReadyState() {
+ window.scrollTo(0, 0);
+ window.setTimeout(PageLoad.#updateDocument, PageLoad.MOTION_DELAY);
+ }
+
+ static #updateDocument() {
+ document.documentElement.dataset.ready = 'done';
+ document.removeEventListener(
+ 'readystatechange',
+ PageLoad.#handleReadyState,
+ );
+ }
+}
diff --git a/src/sections/Intro.astro b/src/sections/Intro.astro
index 8d4c265..57d2b9f 100644
--- a/src/sections/Intro.astro
+++ b/src/sections/Intro.astro
@@ -1,6 +1,5 @@
---
import {type SectionEntry} from '@data/types';
-import Contact from '@components/Contact.astro';
interface Props {
id: SectionEntry['id'];
@@ -24,15 +23,14 @@ const {id, thumbnail} = Astro.props;
Background image photographed by: Curtis Dulmage
-
+
Curtis Dulmage.
Front end web developer.
- Ottawa, Canada. Here are a few of my most recent projects. Please
- get in touch if you have any questions. Thank you.
+ Ottawa, Canada.
+ Here are a few of my most recent projects.
+ Please get in touch if you have any questions. Thank you.
-
-
@@ -52,6 +50,11 @@ const {id, thumbnail} = Astro.props;
@media (--min-tablet) {
gap: var(--space);
}
+
+ /* Page load (fade-in) */
+ position: relative;
+ z-index: var(--index-thermosphere);
+ animation: fadeIn var(--speed-slower) var(--speed-slow) var(--ease) both;
}
.Details {
diff --git a/src/styles/global.css b/src/styles/global.css
index c988c20..5c757c7 100644
--- a/src/styles/global.css
+++ b/src/styles/global.css
@@ -87,34 +87,6 @@ body {
cursor: url('../assets/svg/cursors/CursorAuto.svg'), auto;
}
-/* --- Page load --- */
-/* TODO: Consider something better with `document.readystate`. */
-
-@keyframes pageLoad {
- from {
- opacity: 1;
- visibility: visible;
- }
- to {
- opacity: 0;
- visibility: hidden;
- }
-}
-
-body {
- position: relative;
-
- &::after {
- content: '';
- z-index: var(--index-mesosphere);
- position: fixed;
- inset: 0;
- pointer-events: none;
- background-color: black;
- animation: pageLoad var(--speed-slow) var(--speed) var(--ease) forwards;
- }
-}
-
/* --- Smooth scroll + snapping --- */
/* Disabled because it breaks "dynamic chrome" behaviour on iOS */
@@ -305,3 +277,39 @@ button {
cursor: url('../assets/svg/cursors/CursorPointerClicked.svg'), pointer;
}
}
+
+.preload-cursors {
+ /*
+ Required to preload the variant cursor. Otherwise, there will be
+ a delay upon click when switching to the different cursor asset.
+ */
+
+ > b {
+ cursor: url('../assets/svg/cursors/CursorDeadClicked.svg'), auto;
+ }
+
+ > u {
+ cursor: url('../assets/svg/cursors/CursorHornsClicked.svg'), pointer;
+ }
+
+ > i {
+ cursor: url('../assets/svg/cursors/CursorPointerClicked.svg'), pointer;
+ }
+
+ /*
+ > strong {
+ cursor: url('../assets/svg/cursors/CursorGrabClicked.svg'), pointer;
+ }
+ */
+}
+
+/* --- Global animations --- */
+
+@keyframes fadeIn {
+ from {
+ opacity: 0;
+ }
+ to {
+ opacity: 1;
+ }
+}