diff --git a/mobile/lib/modules/asset_viewer/views/video_viewer_page.dart b/mobile/lib/modules/asset_viewer/views/video_viewer_page.dart
index 0967bf52a7..eb125f27fb 100644
--- a/mobile/lib/modules/asset_viewer/views/video_viewer_page.dart
+++ b/mobile/lib/modules/asset_viewer/views/video_viewer_page.dart
@@ -40,7 +40,7 @@ class VideoViewerPage extends HookWidget {
       controlsSafeAreaMinimum: const EdgeInsets.only(
         bottom: 100,
       ),
-      placeholder: placeholder,
+      placeholder: SizedBox.expand(child: placeholder),
       showControls: showControls && !isMotionVideo,
       hideControlsTimer: hideControlsTimer,
       customControls: const VideoPlayerControls(),
@@ -58,7 +58,7 @@ class VideoViewerPage extends HookWidget {
             if (controller == null) {
               return Stack(
                 children: [
-                  if (placeholder != null) placeholder!,
+                  if (placeholder != null) SizedBox.expand(child: placeholder!),
                   const DelayedLoadingIndicator(
                     fadeInDuration: Duration(milliseconds: 500),
                   ),
diff --git a/mobile/lib/modules/memories/ui/memory_card.dart b/mobile/lib/modules/memories/ui/memory_card.dart
index 5243e24a13..af57c272ae 100644
--- a/mobile/lib/modules/memories/ui/memory_card.dart
+++ b/mobile/lib/modules/memories/ui/memory_card.dart
@@ -1,12 +1,12 @@
 import 'dart:ui';
 
 import 'package:flutter/material.dart';
+import 'package:flutter_hooks/flutter_hooks.dart';
 import 'package:immich_mobile/extensions/build_context_extensions.dart';
 import 'package:immich_mobile/modules/asset_viewer/views/video_viewer_page.dart';
 import 'package:immich_mobile/shared/models/asset.dart';
-import 'package:immich_mobile/shared/models/store.dart';
+import 'package:immich_mobile/shared/ui/hooks/blurhash_hook.dart';
 import 'package:immich_mobile/shared/ui/immich_image.dart';
-import 'package:immich_mobile/shared/ui/immich_thumbnail.dart';
 
 class MemoryCard extends StatelessWidget {
   final Asset asset;
@@ -22,8 +22,6 @@ class MemoryCard extends StatelessWidget {
     super.key,
   });
 
-  String get accessToken => Store.get(StoreKey.accessToken);
-
   @override
   Widget build(BuildContext context) {
     return Card(
@@ -38,19 +36,8 @@ class MemoryCard extends StatelessWidget {
       clipBehavior: Clip.hardEdge,
       child: Stack(
         children: [
-          ImageFiltered(
-            imageFilter: ImageFilter.blur(sigmaX: 30, sigmaY: 30),
-            child: Container(
-              decoration: BoxDecoration(
-                image: DecorationImage(
-                  image: ImmichThumbnail.imageProvider(
-                    asset: asset,
-                  ),
-                  fit: BoxFit.cover,
-                ),
-              ),
-              child: Container(color: Colors.black.withOpacity(0.2)),
-            ),
+          SizedBox.expand(
+            child: _BlurredBackdrop(asset: asset),
           ),
           LayoutBuilder(
             builder: (context, constraints) {
@@ -113,3 +100,50 @@ class MemoryCard extends StatelessWidget {
     );
   }
 }
+
+class _BlurredBackdrop extends HookWidget {
+  final Asset asset;
+
+  const _BlurredBackdrop({required this.asset});
+
+  @override
+  Widget build(BuildContext context) {
+    final blurhash = useBlurHashRef(asset).value;
+    if (blurhash != null) {
+      // Use a nice cheap blur hash image decoration
+      return Container(
+        decoration: BoxDecoration(
+          image: DecorationImage(
+            image: MemoryImage(
+              blurhash,
+            ),
+            fit: BoxFit.cover,
+          ),
+        ),
+        child: Container(
+          color: Colors.black.withOpacity(0.2),
+        ),
+      );
+    } else {
+      // Fall back to using a more expensive image filtered
+      // Since the ImmichImage is already precached, we can
+      // safely use that as the image provider
+      return ImageFiltered(
+        imageFilter: ImageFilter.blur(sigmaX: 30, sigmaY: 30),
+        child: Container(
+          decoration: BoxDecoration(
+            image: DecorationImage(
+              image: ImmichImage.imageProvider(
+                asset: asset,
+              ),
+              fit: BoxFit.cover,
+            ),
+          ),
+          child: Container(
+            color: Colors.black.withOpacity(0.2),
+          ),
+        ),
+      );
+    }
+  }
+}
diff --git a/mobile/lib/modules/memories/views/memory_page.dart b/mobile/lib/modules/memories/views/memory_page.dart
index 4312a7ad2e..9308e812dc 100644
--- a/mobile/lib/modules/memories/views/memory_page.dart
+++ b/mobile/lib/modules/memories/views/memory_page.dart
@@ -10,7 +10,6 @@ import 'package:immich_mobile/modules/memories/ui/memory_epilogue.dart';
 import 'package:immich_mobile/modules/memories/ui/memory_progress_indicator.dart';
 import 'package:immich_mobile/shared/models/asset.dart';
 import 'package:immich_mobile/shared/ui/immich_image.dart';
-import 'package:immich_mobile/shared/ui/immich_thumbnail.dart';
 
 @RoutePage()
 class MemoryPage extends HookConsumerWidget {
@@ -110,24 +109,13 @@ class MemoryPage extends HookConsumerWidget {
         asset = memories[nextMemoryIndex].assets.first;
       }
 
-      // Gets the thumbnail url and precaches it
-      final precaches = <Future<dynamic>>[];
-
-      precaches.addAll([
-        precacheImage(
-          ImmichImage.imageProvider(
-            asset: asset,
-          ),
-          context,
+      // Precache the asset
+      await precacheImage(
+        ImmichImage.imageProvider(
+          asset: asset,
         ),
-        precacheImage(
-          ImmichThumbnail.imageProvider(
-            asset: asset,
-          ),
-          context,
-        ),
-      ]);
-      await Future.wait(precaches);
+        context,
+      );
     }
 
     // Precache the next page right away if we are on the first page