matfantinel / sveltekit-static-blog-template

A lightweight and customizable template for blogs and portfolio websites, built with SvelteKit.
https://sveltekit-static-blog-template.vercel.app
GNU General Public License v3.0
140 stars 28 forks source link

Jampack's image processing is replaced by SvelteKit's hydration #1

Closed matfantinel closed 1 year ago

matfantinel commented 1 year ago

The way image optimization works in this template is that, after the website is compiled, Jampack goes through the files and automatically converts images and then updates their references in HTML. So an img tag that points to image.png will point to image.webp instead.

This would work well if SvelteKit didn't replace that content as soon as the page load (in a process called hydration). Since the data is loaded via the +page.server.ts files, it's like the data is coming from a server (even though it's a static site). And since the reference to the images come from these requests, they get replaced.

I've tried disabling Client-Side Rendering to only use the generated static content, but that completely disables all JavaScript in the page (which means theme toggle and sparkles won't work, as well as navigation is a bit more clumsy).

I see 2 possible ways of fixing this:

  1. Instead of importing data in the *.server.ts file, do it directly in the page itself. I think this will make the hydration not occur since it's not "loading" data from anywhere. Obs: the reason I did this initially was mostly in prep of using a CMS and loading dynamic data. While that might eventually happen on my own personal website, it won't in this template, so I don't think it's necessary
  2. Remove Jampack and wait for Svelte's built-in image optimization package. However that looks like it will work by importing the Images in JavaScript which is not really a good experience when doing the blog posts.
matfantinel commented 1 year ago

Option 1 didn't work as data still gets hydrated, unfortunately. Gonna try and think of another solution as I'm not a fan of Option 2

xKesvaL commented 1 year ago

I've done some research on this since it also interests me. Here's my idea: After looking, I found svelte-preprocess-import-assets, it's pretty straight forward: transforms pure <img src="..." /> html to a import in <script>, as you would do it with Vite usually.

You probably already got the Idea, you could make a component that takes in {src} and {alt} parameters, and simply returns some html and an image with predefined vite-imagetools parameters.

blogpost.md

# hey im a post

<ImageComponent src="yo" alt="hey" />

ImageComponent.svelte

<script>
  export let src;
  export let alt;
</script>

<img srcset="{src}?w=300;400;500&format=webp&srcset" {alt} />

And then svelte-preprocess-import-assets would convert that as an import on compile. I'm not sure wether that plugin works importing components in md or svx, but if it does, that would probably be a good solution.

matfantinel commented 1 year ago

@xKesvaL hmmm, that approach does look promising! I think I've tried some combination of those tools but not this one specifically. Guess I'll try it out and see how well it goes.

matfantinel commented 1 year ago

@xKesvaL unfortunately that approach did not work, as svelte-preprocess-import-assets does not work when the src is a variable (which in this case it would be). So it won't transform into an import and then vite-imagetools can't do its job.

My next idea is to keep using Jampack and have an image component that automatically adds the srcsets, which shouldn't be that hard. The challenge is to fail gracefully if for any reason there isn't any webp version of a file (e.g. while developing)

matfantinel commented 1 year ago

Good news! I was able to simplify things even more and make use of my image-transmutation project, using it as a NPM package. Local tests went really well.

I'm just waiting a bit for NPM to allow me to publish the package and will update this Issue and this template to use it

matfantinel commented 1 year ago

Fixed! Images are now being automatically optimized.