Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Client render without static contents #795

Closed
mohsen1 opened this issue Aug 5, 2017 · 2 comments
Closed

Client render without static contents #795

mohsen1 opened this issue Aug 5, 2017 · 2 comments

Comments

@mohsen1
Copy link

mohsen1 commented Aug 5, 2017

When using Preact with server-side rendering we're transferring a parts of the app to the client two times!

Consider following app:

const App = () => <div onClick={ ()=> alert('hi') }>Lorem ipsum</div>

Server will render the app with the string "Lorem ipsum" in the HTML. The client bundle has the string "Lorem ipsum" in it as well.

Solution

Make a transformer(Babel or TypeScript) that removes static content from client bundle

By removing static content that's possible to recover from rendered HTML we can reduce the bundle size:

const App = () => <div onClick={ ()=> alert('hi') }></div>

Make client render use existing HTML to hydrate its virtual DOM.

<html>
    <body>
        <div id="root">
            <div>Lorem ipsum</div>
        </div>
        <script src="preact.js"></script>
        <script>
            const App = () => <div onClick={ ()=> alert('hi') }></div>
            preact.render(App, document.getElementById('root'));
        </script>
    </body>
</html>

We might have to put markers to maintain order of children in components. For instance:

const Comp =({children, prop1}) => (
  <div> 
        Static content 1
        {prop1}
        Static content 2
  </div>
)

Should be transformed into something like this:

const Comp =({children, prop1}) => (
  <div> 
        {preact.staticContent}
        {prop1}
        {preact.staticContent}
  </div>
)

Recovering more than just strings from HTML.

If we can determine part of component is completely static we can remove it entirely and recover it from HTML:

const Comp =({children, prop1}) => (
  <div> 
        <div><span>Hi</span></div>
        {prop1}
  </div>
)

Tranfroms into:

const Comp =({children, prop1}) => (
  <div> 
        {preact.staticContent}
        {prop1}
  </div>
)

I don't understand Preact internals. Is it even possible? This might be a very tricky problem to solve but I believe it worth it. Our own apps are exploding it bundle size and most of the bundle is just static strings.

@developit
Copy link
Member

Could maybe do this in userland by having a scanner that converts DOM to VDOM and then provides a component that can insert that VDOM in place. Hard to ditch the static via Babel though, JSX isn't very deterministic.

@marvinhagemeister
Copy link
Member

Determining which string can be safely removed will be extremely tricky due to the highly dynamic nature of JavaScript. Whilst this is an interesting idea it's out of scope for us to tackle. For this to work one would need to plugin into one of the existing compilers and extend them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants