Passion & Opportunity ? continue : break

From Vanilla to React to Preact to Hyperscript

Written: 2019-06-21 16:24:14Last update: 2019-09-09 13:03:44

This is a special article which actually my story about my journey
to choose the right UI framework/library for my new blog site,
there are many web front-end UI frameworks and libraries available,
in this journey I only use
ReactJS,
PreactJS,
and HyperScript,
this story is not giving a detail comparison between these frameworks/libraries
because I have not use them to their fullest features,
this story is about what I have tried and how I use each of them to make the UI for my blog site,
the word 'I' is more frequently used than 'you' or 'we'.

To be honest this is a surprising journey for my self and I have thought a lot
about how to write this surprising journey to just one article,
where should I start? how to end it?
should I write this story jumping back and forth (flashback) like recent Marvel movies? (^.^),
at the end I concluded there is no perfect way but only perfect timing,
so I just write this story from start to finish in a sequence of my real journey,
I tried to make this article as short as I could while keeping the important detail and not skipping too much,
also will share some of my thoughts along the way and why I did what I did.

If you are really interested in reading this rather long story then
before you continue reading please get your favorite drink
(a cup of hot coffee or hot-choco or fruit juice, cold spirit, etc.)
and come back to enjoy this journey story.

A few months ago, I started to create new blog site quick.work,
its main home page has a listing of articles,
originally I use my server (written in PHP) to fully render the main page
and other pages using traditional multi-pages application (MPA) web,
the articles count is growing and even though the count is not a lot now but definitely will increase
because I intend to write article regularly to share my experiences until unforeseen time.

The problem I was facing is sending all the article headline list
fully rendered in the server (include header, footer and content which has many HTML tags)
is causing my small PHP server a high load burden,
opening the website is rather slow,
so then I knew that the first thing I need to do
is to convert the traditional MPA to SPA (Single Page Application) web,
the conversion is simple and I have written other article about it
(if you are interested then you could read my other SPA article),
conversion from MPA to SPA means need to create some APIs and use them to get the JSON data
then the JSON data need to be rendered to the screen in client side,
in this article I will skip about how to make the API,
(there are some tips and tricks about designing fast APIs which I will write for a future article),
this article will just focus on the making of the UI (User Interface) for quick.work,
below is the partial sample of JSON data which I will use throughout this article.

The first trial in this journey is to render the article-headline-list in the main home page,
I use simple vanilla JavaScript below,
just a note for the first-time reader to see my coding style please note that
I purposely wrote long verbose comments and long function name
to remind my self in the future and let readers easily understand.

Above JavaScript is simple to understand, sort code and fast (no DOM element handling, only string operation),
it works and has no problem,
but other front-end developers may disagree and some may even scream 'OMG ..',
it is rather lame to see that code in 2019 .. LOL,
the code works but not friendly and not easy to upgrade for more additional features in the future
such as handling onMouseOver, onClick or other additional attributes,
the main problem of the code is using many hard-coded elements,
very error-prone such as missing end-tag, spelling error, etc.

The Second trial in this journey is to find a more elegant way, introducing the rarely use
HTML5 <template> tag,
I created 2 templates, articlesContainerId is the container
and articleHeadlineId is the content to be repeated for all article headlines.

Using JavaScript to get a template, clone the content to get virtual DOM,
adjust and filled the virtual DOM elements
then append it to the container dynamically, logic is simple and the is working well,
it has less error-prone and less possible to make spelling mistake,
but it is SLOWER compared to the first step (pure JavaScript to do string operation),
DOM operations like importNode, querySelector, querySelectorAll, appendChild (render to actual screen)
needs some overhead.
If I have only a few lists then I can ignore this speed issue but
I am sensitive to performance issue so I thought that I would revisit this
and will change the logic when I found a better solution.

Both tried solutions are working as expected,
a few days passed, then I thought that
I want to follow the current 'trend' of web front-end UI development,
so I read some topics about using 'Reusable Component' design pattern,
the idea is similar to OOP (Object Oriented Programming)
by creating objects (eg: data model, methods, forms, etc.) which can use with many functions,
so 'Reusable Component' is to design/make a component which can be reusable in combination with other components
or reusable with other functions (business logic).

Third trial in this journey is to use ReactJS,
the facebook-back framework,
somehow I still love to code in JavaScript without transpiler like Babel,
it is much more convenient to make quick prototyping,
which I often do in my articles,
unfortunately without Babel to transpile the Component means that I can't use
JSX (JavaScript XML),
using JSX to create React Component (DOM elements) is easier and recommended,
so I read some how-to articles including
ReactJS without JSX,
at the time of my trial to use ReactJS v16.8.6, I need to include React framework (ReactJS and ReactDOM libraries) as follow.

After React framework loaded properly then I created some components,
when I started to use React,
all my components are class-based (stateful component)
to bind (enclose) some data with the component,
but then I realized for my requirement
there is no need to keep data inside the component
to automatically refresh component (update UI)
by calling this.setState(...) to change the data,
this feature normally for MVVM or to make an interactive UI like forms or web games
(more detail about ReactJS state),
maybe I will need this feature in the future but definitely not now,
so I changed all classes to functional (stateless) components.

Calling the method renderArticleheadlineListUsingReact(...)
will automatically create the same article list as the previous first and second trials,
please see that I have broken down the 'component' to single element whenever possible (ie: A_BOX, IMG and BLOG_TITLE),
but it is not necessary, the reason I did that just want to show about the logic of 'reusable component',
in my actual trials, I put the content of A_BOX, BLOG_LINK, IMG, BLOG_TITLE and BLOG_DATES directly into BLOG_LIST
to make it smaller code, easier to understand and faster (not jumping around 'component'),
in fact, if we don't care about 'reusability' then we can combine all those simple components as one big 'component'.

ReactJS has so many more features than what I use here,
I only scratched the surface,
in the beginning, I was satisfied with the result,
seem simple and easy to get another person to join development too,
days passed and then the guilty feeling started to rise,
ReactJS is simply too much for my requirement,
another more complex website such as Facebook may use ReactJS to its full potential (because ReactJS is born from Facebook),
seeing that ReactJS features make me wonder what Facebook's web front-end developers would use
if they are tasked to find a replacement for ReactJS?
can they easily replace ReactJS with AngularJS or VueJS or other frameworks?
it makes me think that Facebook's web front-end development and ReactJS are married for life.

Questioning what disadvantages of using ReactJS for my tiny blog site?
I could only thing that I've wasted the framework because I don't use many of ReactJS features and also the framework download size issue (it is not a big problem but a waste nevertheless),
slowly I continue to look for a more suitable front-end framework.

Fourth trial in this journey is the PreactJS,
actually I did know PreactJS before I use ReactJS,
at the time I was skeptical about the '3kb size' thing
because what good thing can come in 3kb?
to make a long story short,
after ReactJS implementation is done and running properly,
then the Preact's 'drop-in replacement' and 'closer to the metal' marketing start to kick-in my mind,
so I dig deeper to understand the
differences between PreactJS and ReactJS
and see the Preact source code,
after I reviewed the code then I regretted that I did not try it earlier,
so I swap the code to verify whether the 'drop-in replacement' actually work ... and BAM !!
Preact candy never taste so sweet and simple,
the first thing I did was to replace the 'ReactJS framework' with 'Preact library'
(it is only a single 3kb file and should not be called 'framework' .. LOL).

Can you spot the differences?
the differences are mainly for the shortcuts,
in React, we created 2 shortcuts e = React.createElement and render = ReactDOM.render,
in Preact we also created 2 shortcuts h = window.preact.h and render = window.preact.render
both React's render() and Preact's render() are using the same parameters,
also React's e() and Preact's h() are using the same parameters,
so I only replace every 'e(...)' with 'h(...)', all other parameters are the same,
if in ReactJS we replace the shortcut from 'window.e = React.createElement'
to 'window.h = React.createElement' then the component code will stay the same.

Eager to see a better result, I wasted no time to quickly replace React with Preact in my local server
then uploaded to my remote hosting server to monitor server log output to see if there is any side-effect,
there is no strange issue which is expected because no code changes related to the back-end,
tried with different browsers, Chrome, Firefox, Safari in Mac and Android smartphone,
everything seems stable and I was happy.

Days have passed then at one night when I was free,
I remembered that my web does not need Virtual DOM nor stateful component,
so in a way Preact also 'too big' for my web,
there is some code in Preact to do a comparison (diff-ing) of data to update UI (data binding),
then I was started to feel itchy and want to find a smaller library,
I did not pay much attention to HyperScript (Hypertext + JavaScript) previously,
so I start to read some articles about the relation between HyperScript and JSX,
not much I can find but HyperScript is definitely old
(checked Github, the project created on Aug 19th, 2012).

Fifth trial in this journey is to take HyperScript
and customize it, HyperScript itself is very small, less than PreactJS,
this time I want to really chop-off everything that I don't need,
there is only 1 requirement in my head,
the customized version must be able to use the same exact stateless functional component
for React and Preact, so I can switch to React or Preact anytime in the future easily,
so I only need the 'h()' and 'render()'
below is the over-simplified (butchered) code.

The above code shine more light onto what is the h() and render() actually do,
h() is to define the values for the element tag name, attributes and children,
the render() is to create the DOM element using document.createElement(tagName),
the tag name can be any valid HTML element tags
or any custom element tag like 'this-is-my-custom-tag' to create
<this-is-my-custom-tag></this-is-my-custom-tag>,
in render() I append the created element(s) to rootElement just like PreactJS,
it is different compare to React which will replace the rootElement full content (innerHTML),
I think maybe because React has a need to understand (maintain) everything inside rootElement.

It is very tiny and can fulfill my web need at this moment,
I am satisfied with it,
in the future if I need more functions then I could either add to it
or jump straight to PreactJS and if PreactJS not enough then maybe to ReactJS without much change,
obviously I can not pull-request to HyperScript's Github,
so for naming sake,
I just call it HScript (an over-simplified version of HyperScript),
using Google Closure Compiler
with 'Advanced' optimization selected the output code is 1,010 bytes (1 KB), 566 bytes gzipped.

During my journey with React, Preact, HyperScript, and HScript,
I have a need to verify whether my 'components code'
can work properly with all of them without any change,
so I created wrapper functions to dynamically load the required framework/library,
this makes my testing and switching between framework/library much easier.

For me personally this is quite a journey, a surprising one,
started with using pure vanilla JavaScript then use the most features React framework,
then to Preact library and to HyperScript library and circle back to vanilla JavaScript.

Throughout this journey I have learned some new useful things about React framework
and have gained more experience using it,
I also learned another important lesson,
don't look down on small things and ignore them but try to be more open-minded and invest some time to try them all,
even though my chosen method is actually very simple
and I feel have wasted too much time for these long trials and tiresome journey
but in the end it is all worth it, as in life, we always learn new things whether we like it or not.

Hopefully this story can help someone to give the inspiration to try these frameworks/libraries,
your journey may well be so different than mine, enjoy your own journey.