denoland / fresh

The next-gen web framework.
https://fresh.deno.dev
MIT License
12.2k stars 624 forks source link

Feature: Lazyload islands components in the client side #565

Open Khaledinges opened 2 years ago

Khaledinges commented 2 years ago

Hello !

It comes to my mind that I wouldn't want to load all the islands JS chunks on the page load in the client side. Obviously, it would be for performance optimization reasons.

would it be possible to inject some islands JS components code when needed (lazyloaded) or on user interactions ?

lucacasonato commented 2 years ago

This would be a good addition, I agree. Ideally one should be able to set when the island should be loaded via either an option in the island file (at declaration), or at the island instantiation (at island use).

I think "at declartion" would be an easier first step. Maybe something along the lines of:


// islands/Island.tsx

export default function Island() { ... }

// When to load the island. Defaults to "eager".
// Valid options are:
//   - "eager": load as soon as possible (use for above the fold islands).
//   - "viewport": load when the island is about to enter the viewport.
//   - "interaction": when an interactive event is encountered by the island. The event will be captured, the island loaded, and then the event is replayed.
export const load = "eager";
Khaledinges commented 2 years ago

Great looks perfect ! Thank you

igorbrasileiro commented 1 year ago

It seems that islands already can lazy load to user interaction via Suspense. Take a look at this example:

import { Suspense, Lazy }  from "preact/compat"
import {useState} from "preact/hooks"

const Comp = lazy(() => import("../component/Comp.tsx"))
export default function Component() {
  const [render, setRender] = useState(false);
  return <div>{render && <Comp />} <button onClick={() => setRendeR(true)}>click</button></div>
}

In addition, IMO, islands can be rendered from fresh following the browser scheduler.postTask improving the UX and decreasing the TBT. I opened a PR doing this (https://github.com/denoland/fresh/pull/1019) for islands, this could be implemented for plugins too.