question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Compile JSX right into virtual node objects avoiding `h` function

See original GitHub issue

There are an idea to avoid using h in favor of compilation step which will do the same work. Compile JSX:

const view = (state, actions) => (
  <main>
    <h1>{state.count}</h1>
    <button onclick={actions.down}>-</button>
    <button onclick={actions.up}>+</button>
  </main>
)

to:

const view = (state, actions) => ({
  name: 'main',
  props: {},
  children: [
    { name: 'h1', props: {}, children: [state.count] },
    { name: 'button', props: { onclick: actions.down }, children: ['-'] },
    { name: 'button', props: { onclick: actions.up }, children: ['+'] }
  ]
})

Potentially the app should work faster this way because each function call requires additional computing resources. Also h which is still necessary for JSX haters could be tree shakied from your build.

Possible future improvements: adopt babel-plugin-transform-react-constant-elements to speedup the app even more:

const h1 = { name: 'h1', props: {}, children: ['Static content'] }
const view = (state, actions) => h1

Can anyone foresee potential pitfalls?

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:4
  • Comments:27 (21 by maintainers)

github_iconTop GitHub Comments

6reactions
SkaterDadcommented, Mar 21, 2018

@jorgebucaran Here’s a taste of the JS Framework Bechmark results for lazy/thunks, run in-browser and scientifically clicking around at a steady pace. I’ll run the full automated test again soon. I ran it last night, but my implementation was wrong, so the results were way too good to be true. Now that I’ve fixed it, the results line up with my expectations, showing big wins on partial page updates. I removed percentages which were within 20% as not being significant.

Test (avg. of 10 runs in browser) Normal Thunks %Improved
Create 1000 181.74 172.12
Update Every 10th - 1000 Nodes 74.41 11.99 84%
Swap Rows - 1000 Nodes 158.17 155.36
Create 10,000 Nodes 1934.625 1913.02
Update Every 10th - 10,000 Nodes 725.5909 571.29 21%
Swap Rows - 10,000 Nodes 464.8091 300.21 35%
Keep Adding 1000 Nodes (only run once) Normal Thunks %Improved
Create 1000 144.3 158.3
Add 1000 to 1000 162.6 152
Add 1000 to 2000 229.6 171 26%
Add 1000 to 3000 228.9 181.2 21%
Add 1000 to 4000 307.1 246.7 20%
Add 1000 to 5000 277 207.3 25%

I know it’s been said before that generating the tree isn’t that expensive, but it can really add up on a large app, or even a small one that has complex logic to generate the VNode tree. It’s a lot faster to do a few strict === checks around some components, and generate the new node only if needed.

I’m look forward to combining these lazy functions with the custom JSX optimizations to get the best of both worlds: faster node creation, and faster partial updates 😎 My computer is going to hate me after running all of these variations through JS Framework Benchmark 🖥️ 💥

The API is pretty ugly right now, so I’ll PR once I’ve thought of a nicer way to use this and learn how to write tests for it.

5reactions
SkaterDadcommented, Mar 10, 2018

So… I’ve recently decided to not hate on JSX so hard 😆

The readability is so much higher than nested h calls in large view functions, that I really want to convert my main project. However, the runtime perf costs due to the variable length arguments and extra function calls (h(Component)) are hard to swallow.

Today I’ve been working on getting babel-plugin-transform-jsx to work with hyperapp.

I’m new to Babel transforms, but I managed to get this working! The transform code was quick & dirty, but I’m really pleased with the results so far 😄

As a proof of concept, here is my recent Lazy Components Codepen demo run through babel-plugin-transform-jsx then my own custom transform: https://codepen.io/SkaterDad/pen/wmBKbM?editors=0010

Quick rundown:

  • Normal HTML elements get transformed to raw VNode objects (thanks to the first plugin). My plugin renames the properties and changes children: null to children: [] when needed.
  • Components & Lazy Components get turned into direct function calls. No more h(Component, props, children), just Component(props, children).

Next steps:

  • Clean up code to ensure I’m only modifying VDOM objects, and just any random object with the properties I’m targeting.
  • Package this up with babel-plugin-transform-jsx as a dependency, or maybe fork it?
  • ~@jorgebucaran Any interest in this being in the @hyperapp NPM scope?~
  • Could call it babel-plugin-transform-hyperapp-jsx or something to fit in with the rest of babel plugins?
  • Performance testing the output against the React JSX transform, and against raw h calls. Should be higher since there are less functions being invoked at runtime.
  • Compare compiled bundle sizes of an application
Read more comments on GitHub >

github_iconTop Results From Across the Web

Render Functions & JSX | Vue.js
h () is short for hyperscript - which means "JavaScript that produces HTML (hypertext markup language)". This name is inherited from conventions shared...
Read more >
Introducing JSX - React
By default, React DOM escapes any values embedded in JSX before rendering them. Thus it ensures that you can never inject anything that's...
Read more >
Can I use jsx without React to inline HTML in script?
I was able to write JSX files and inject them into an HTML page using a 'fake' React file. no-react.js /** * Include...
Read more >
JSX Alternatives - Medium
JSX is a very popular choice nowadays for templating in various frameworks, not just in React. However, what if you don't like it, ......
Read more >
Class: VComponent - Oracle
Virtual DOM nodes are plain old JavaScript objects that specify the node type ... Virtual component render functions support the use of JSX...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found