brisa-build / brisa

The Web Platform Framework.
https://brisa.build
MIT License
452 stars 12 forks source link

Roadmap 1.0 #197

Open aralroca opened 6 months ago

aralroca commented 6 months ago

ROADMAP TO 1.0 🚀

The previous Routemap to this one was the 0.1 Routemap, where some features like "Runtime-agnostic" were left pending and moved to 1.0.

The rest of Routemap 1.0 will be built by listening to the community.

The first months after version 0.1 we will focus on fixing issues and listening to the community, during these months we will only make features if they are really to fix important issues.

Feel free to suggest ideas in this thread to build 1.0 together.

Runtime-agnostic

Bun is great and has helped a lot in the creation of Brisa, however the more support for runtimes the better. For version 0.1 we already extended to support Node.js, but now for 1.0 we need to extend more runtimes:

Server Actions

Web components

Web Platform

DX

CSS

Optimizations

Integrations

CLI

More

Write ideas below. The first months after 0.1 will be focused on fixing bugs and finishing the 1.0 routemap list by listening to the community.

ansarizafar commented 1 month ago

Brisa always re fetch the page from the server when we navigate to a link. WE should be able to avoid re fetching/roundtrip and use the cached version of the page like Svelte. This is useful If you are using a hosting provider with a request based pricing like Cloudflare and this will also speed up routing as currently it feels slow.(No roundtrip required).

ansarizafar commented 6 days ago

Slow routing issue can also be solved by introducing a client side router. Just like SvelteKit, client side router should take over after initial full page load via URL and only fetch and inject a relevant page component into the layout on navigation to new URL via tag or via code.

aralroca commented 6 days ago

Slow routing issue can also be solved by introducing a client side router. Just like SvelteKit, client side router should take over after initial full page load via URL and only fetch and inject a relevant page component into the layout on navigation to new URL via tag or via code.

@ansarizafar I have some doubts about this issue. Because this means that the server components should be executed on the client and we don't want this. For example, if the content of some server component depends on some parameter or cookie, I'm not sure how to fix this to work. Probably, this could work when the output is static or for pages that have the prerender=true to prerender this page (actually we serve the file with the HTML and the client does the diff).

Nevertheless, thanks, it's a good proposal and more people like @adriablancafort have proposed it, so we'll have to investigate.

ansarizafar commented 5 days ago

Why diffing is necessary, why not just directly inject/update server rendered HTML into layout placeholders?

aralroca commented 5 days ago

Why diffing is necessary, why not just directly inject/update server-rendered HTML into layout placeholders?

inside a server component, there can be a web component and we want to maintain its state (or update if some attribute changes) if it already existed previously. Cases like navigations in the same page that change the parameters or web components that are in the layout. In addition, diffing makes it more lightweight, it does not have to load so many resources, only the part that changes.

Besides, the diffing we have works with streaming. Therefore also with suspense. This way by receiving HTML in chunks and diffing on fly makes the user see the changes as soon as possible. This is the package: https://github.com/brisa-build/diff-dom-streaming

The same RPC that does the diffing during navigation is also used for server actions, where there can be no navigation at all and only a small part can be updated.

Using the same logic to resolve actions and navigation (MPA as SPA) we need to load less code, just 2kb.

ansarizafar commented 4 days ago

I don't know much about internal working of Brisa so I am not sure how viable my ideas are. I want to have complete control on when and where I want to render my HTML. We even don't need layout components. We can have an index.html and in case of a page component we can render it inside body tag and in case of a nested route we can render it inside a container div.

renderInAction is also confusing/inefficient. We should be able to return HTML chunk, decide where we want to render it and how (renderMode = replace/append). For example, I am building an AI assistant and I want to efficiently append different html chunnk/component based on structured data returned by an LLM call in a messages div/component without rerendering whole component/page.

For real time granular updates (HTML/store data) we can use websockets/Server sent events or https://braid.org/ https://www.npmjs.com/package/braid-http without re rendering/diffing.

function HomePage() {

return (
    <div target="body" rendermode="replace">
    .........
    </div>
)
}
aralroca commented 4 days ago

@ansarizafar It's just a great idea. The current rerenderInAction re-render the page or the component. But it has no more power than this. Although it does stream everything it would be easy to implement something similar to what you say.

Page re-render:

// Trigger a full-page rerender
rerenderInAction({ type: "page" });

Component re-render:

// Trigger a component rerender with new props
rerenderInAction({ type: "targetComponent", props: { text: "bar" } });

Surely we could do the following (new proposal):

  1. Breaking change: rename rerenderInAction to renderInAction.
  2. Breaking change: change the parameters as follows:

Page re-render:

// Trigger a full-page rerender
renderInAction(); //  default behavior without arguments

Component re-render:

// Trigger a component rerender with new props
// without more arguments is replacing the target component
renderInAction({ element: <Component {...props} /> });

Render in specific DOM locations:

// Render a component into a specific DOM element
renderInAction({
  element: <AnotherComponent />,
  targetSelector: "#target-id", // specify the DOM node
  mode: "replace", // options: "replace" (default), "append", "prepend"
});

The render of Brisa already supports async generators to facilitate the chunks of HTML. Example:

async function* AnotherComponent() {
  yield <div>{await foo()}</div>;
  yield <div>{await bar()}</div>;
  yield <div>{await baz()}</div>;
}

@ansarizafar do you think my proposal makes sense? I see it quite feasible to do.

aralroca commented 4 days ago

If the naming and defaults are confusing, we can create 2:

// Trigger a full-page rerender
renderPageInAction()

and:

renderComponentInAction({
  element: <Component {...props} />, // The component to render
  targetSelector: "#target-id", // Target DOM node selector
  mode: "replace", // options: "replace" (default), "append", "prepend"
});
ansarizafar commented 4 days ago

I would prefer this

renderPage()   // Full page re-render
renderComponent () // Re-render current component

// Render a specific component on target location
renderComponent({
 element: <Component {...props} />, // The component to render
  target: "#target-id", // Target DOM node selector
  mode: "replace", // options: "replace" (default), "append", "prepend"
});
aralroca commented 4 days ago

I added this to the routemap https://github.com/brisa-build/brisa/issues/648