At Eyevinn we’ve always valued platform and product independence as well as taking a neutral stand when it comes to languages and frameworks. Therefore, when building components for Consuo, our vod-to-live stitching product, it was a quite obvious choice for us to not only build a React component, which may have been the simplest decision, but also a web component for vanilla JavaScript projects with no framework being used.
A lot of JavaScript developers these days thinks that you need a framework such as React or Vue to be able to create encapsulated components to be shareable. Though over the last few years standards as been moving quite fast and the web component standard as such give us all the features that we expects and wants out of modern JavaScript solution for building a component to act isolated as well as being shared in a simple way, both internally as well as externally (e.g. webcomponents.org).
Since before we already had an Up Next component for Consuo, built and shared as a React component. As soon as it had been shared internally I took the challenge to create an exact replica as an web component, as I as a developer loves standard vanilla, no framework, solutions.
Why do we need an ecosystem for Consuo?
Consuo as a product, or rather as a base platform together with its open source engine, is the core of a wider end user experience. We want to bring the laid back experience of classic linear tv into the new era of streaming, as well as bringing the unused potential back to the streaming companies backlog of clips and vod videos in terms of consumption and monetization.
Consuo as a core handles the scheduling as well as the stitching of the channel, creating the core experience. Though we want to help you evolve that experience by bringing more functionality to the table by building a base plate of open source components to be used. This starts with our schedule related components to show what’s currently on air and what’s next up.
Framework decisions and framework neutrality?
We started to build this component as a React component, as this is currently the framework of choice for our product web as well as demo solutions. But as mentioned earlier, we have a history and pride of being language and framework agnostic at Eyevinn. And we do really want this experience and these components to be available for everyone to implement and to use.
With the evolvement of the quite recent web component standard it was a simple decision to take, to develop such alternative as well. As this can be used in all frameworks, not isolated to a single one.
The state of web components
As mentioned earlier The state of web components in style JavaScript standard is quite exciting these days. The api as such might not be as simplified and fine tuned as in React or Polymer, but all the functionality as expected is there, and to avoid the overhead of an framework as well as creating a shareable component not dependent on the framework being used by the implementing part, is a quite exciting thing.
So what can we do?
- Choose to be reachable by outer JavaScript or to entirely encapsulate the functionality.
- Choose to be reachable by outer styling or to entirely encapsulate our styles.
- Act on being attached, as well as detached, from a document. (See Life Cycle Callbacks)
- Act on the attributes of the element being changed during runtime.
This means that we can choose whether we want to build an ecosystem by contributed functionality only, or by encapsulated visually designed components that matches our product’s graphical profile.
For this specific component we just wanted to deliver the functionality of a simple schedule visualizer and do not encapsulate any specified styling.
So let’s go to the functionality of the Up Next component as such and to compare a React component to what we can build in native JavaScript.
The feature set
The component as such solves a rather basic scenario which can be seen as a base plate functionality in any linear channel experience - Showing what’s currently playing and what’s Up Next.
This is implemented by pulling the schedule from which the linear experience is created out of the video files that already exists in the archive.
An example of such schedule json
[
{
"channelId": "eyevinn",
"assetId": "urn:uuid:da80b21b-2e6e-42ae-82b8-3b1b5581b59a",
"eventId": "735fecc8-cade-410d-993f-9860e4de9efe",
"id": "urn:uuid:da80b21b-2e6e-42ae-82b8-3b1b5581b59a",
"title": "TV Plus Joachim",
"start_time": 1590226668810,
"end_time": 1590226741810,
"start": "2020-05-23T09:37:48.810Z",
"end": "2020-05-23T09:39:01.810Z",
"uri": "http://lambda.eyevinn.technology/stitch/master.m3u8?payload=eyJ1cmkiOiJodHRwczovL21haXR2LXZvZC5sYWIuZXlldmlubi50ZWNobm9sb2d5L3R2cGx1cy1hZC1qb2FjaGltLm1vdi9tYXN0ZXIubTN1OCIsImJyZWFrcyI6W3sicG9zIjowLCJkdXJhdGlvbiI6MTYwMDAsInVybCI6Imh0dHBzOi8vbWFpdHYtdm9kLmxhYi5leWV2aW5uLnRlY2hub2xvZ3kvYWRzL3NmZi0xNXMubXA0L21hc3Rlci5tM3U4In1dfQ==",
"duration": 73
},
{
"channelId": "eyevinn",
"assetId": "urn:uuid:b8ff551a-6da3-485a-8a53-b11c5d28753f",
"eventId": "c25f531a-3bf5-4645-b3f0-cbaf4c7f459d",
"id": "urn:uuid:b8ff551a-6da3-485a-8a53-b11c5d28753f",
"title": "TV Plus Johanna",
"start_time": 1590226741810,
"end_time": 1590226816810,
"start": "2020-05-23T09:39:01.810Z",
"end": "2020-05-23T09:40:16.810Z",
"uri": "http://lambda.eyevinn.technology/stitch/master.m3u8?payload=eyJ1cmkiOiJodHRwczovL21haXR2LXZvZC5sYWIuZXlldmlubi50ZWNobm9sb2d5L3R2cGx1cy1hZC1qb2hhbm5hLm1vdi9tYXN0ZXIubTN1OCIsImJyZWFrcyI6W3sicG9zIjowLCJkdXJhdGlvbiI6MTYwMDAsInVybCI6Imh0dHBzOi8vbWFpdHYtdm9kLmxhYi5leWV2aW5uLnRlY2hub2xvZ3kvYWRzLzZjZDdkNzY4LWUyMTQtNGViYy05ZjE0LTdlZDg5NzEwMTE1ZS5tcDQvbWFzdGVyLm0zdTgifV19",
"duration": 75
}
]
React component vs Web Component
Both these components are built in quite a similar way as the feature set is quite similar, as mentioned earlier on in this post. So the things that really differs is the markup as such, the state handling and the rendering language implementation.
Life cycle handling
Life cycles in React and Web Components exposes the same possibilities, though with different terminology and minor limitations.
A simple table of the most common life cycle events can be shown as this
Event | React Component | Web Component |
---|---|---|
Added to DOM | componentDidMount | connectedCallback |
Rendering | render | - |
Attributes being changed | - | attributeChangedCallback |
Removed from DOM | componentWillUnmount | disconnectedCallback |
As seen the main structure is the same between the solutions, though the missing part doesn't mean that the functionality is missed as such.
React handles the changed attributes by simply changing the values on the props of the component, and re-render the component with those values in mind. In the web component you will have to trigger the render function yourself, both when added to DOM (the connectedCallback
event) as well when you get the event for changed attribute values.
Rendering
The other major difference is how the rendering is handled. In React you render your inner html with a markup language called JSX. This gives us the ability to get great autocompletion in your code editor as well as evaluating expressions and values of properties to take visualisation decision based on those. For Web Components on the other hand, we will rather create the inner html elements in JavaScript and append them as childs or, as I prefer to do, write the html as such in a template literal. Even though this doesn't bring the excellent editor functionality as JSX might give us, we will have the same ability to handle expressions and property values in the rendition.
React Example
Web Component Example
Conclusion
To take the extra step and deliver a cross framework component is, as seen, quite a small job - bringing not only a value to the ecosystem that we want to build, but also letting the customer utilise our knowledge and development undependent on their framework choices.
The components can be downloaded through npm (React component and web component) and the source code can be found on our Github (React component and web component). Please feel free to contribute, either to the libraries and components that already exists or to the ecosystem around the Channel engine and Consuo by building open source functionality around them.
Top comments (0)