eBay’s Marko.js, a Lightweight Contender for the JavaScript Framework Title

Sam Everett, Software Developer

Marko.js is eBay’s front-end framework for the future! Over the last few years it seems like there is a new JavaScript framework popping up every time you turn around, so why should we care about Marko? According to the latest polls on Stack Overflow, ReactJS has surpassed Angular in terms of popularity and usage. However, there seems to be no indication that we are heading toward one single victor framework. Many roll their eyes, dismissing the upstarts, or experience decision fatigue when making a front-end application. Many companies on the other hand, seem eager to adopt new frameworks, especially when they come from reputable names in the space, such as Facebook’s React and Google’s Angular. eBay opted to throw their own hat in the ring with Marko. They released it as an open-source project in 2015, and they haven’t looked back since.

eBay created Marko as a part of a greater push toward using a JavaScript heavy development stack, allowing for more lightweight, performant applications. From 2011-2015, eBay used Java as their backend accomplishing server-side rendering with JSP, relying on jQuery for DOM manipulation. Since 2013 they have been ramping up their use of NodeJS, a runtime for JavaScript outside the browser, to handle their server-side rendering and their in-house front-end framework Marko. Since 2015 all of their public facing web applications are rendered with Node and Marko (much of their middleware is still handled with Java). Here is a visual representation of their stack: eBay’s Marko.js, a Lightweight Contender for the JavaScript Framework Title

Lasso.js is another open-sourced project that started at eBay, used for bundling js modules, somewhat analogous to webpack. One of eBay’s lead UI developers, Patrick Steele-Idem, stated at the 2018 Node Summit event in San Francisco that eBay uses server-side rendering for purposes of performance and search engine optimization (SEO). eBay utilizes a concept known as ‘progressive html rendering’. In order to accomplish this, eBay harnesses the power of streaming, which is built into NodeJS Core. Streaming is the sending of chunks of data in a direction. In this case the data is html. The html is flushed down in multiple chunks. Most NodeJS applications do not utilize streaming, because they use express.js for their view engine, which doesn’t support it. However, this concept is well-adapted for eBay’s use case. In addition, eBay encourages handling rendering asynchronously, so that each page is split into discrete chunks that can be handed down independently. Here is a visual representation of the benefits: eBay’s Marko.js, a Lightweight Contender for the JavaScript Framework Title

The first tier is just handing down the html all at once, when the server has finished all the preparation on the back-end, and takes one whole second for the user to see anything on the page. On the second tier the html can be handed down as discrete parts individually, but they are sent down in serial, so each individual piece will appear on the page after its antecedent. In this case the red chunk is the most expensive in terms of load time, but it’s also the second in line to be rendered, so all subsequent components will have to wait. The third tier has asynchronous flushing of each component, passed down in the order of completion. This final tier provides the best user experience, as they can see each piece of content as soon as it’s ready. All this adds up to a pretty sweet stack, optimized for loading lots of search results very fast.

Finally there’s Marko! eBay’s JavaScript / html templating framework created in house, optimized for their stack. Here is a rundown of its notable features:

  • Isomorphic rendering (aka server-side rendering)

  • Asynchronous streaming rendering

  • Virtual DOM rendering

  • Best in class performance (on eBay’s provided benchmarks)

  • Clean syntax with ‘zero’ boilerplate

  • Tiny runtime (~10kb gzip) *Angular is about 150kb, React is about 30kb

  • Single-file UI components

eBay released Marko in 2015 and has been steadily increasing its use. They now have over a billion pages rendered a day with Marko. The project has over 50 developers contributing to it, both in and out of eBay. Though Marko is optimized with server-side rendering in mind, it also works quite well rendered from the client. Here are a few graphics from Marko’s website highlighting its performance compared to other JS frameworks: eBay’s Marko.js, a Lightweight Contender for the JavaScript Framework Title

The benchmark here is rendering a page of 100 search results. Many DOM nodes need to be updated during this process, and the DOM itself is usually the bottleneck for this sort of situation.

Let’s take a look at some of the design decisions that have been made. As far as syntax, the team broadly wanted to take html and make it more like JavaScript. Let’s [KN1] look at a basic component: eBay’s Marko.js, a Lightweight Contender for the JavaScript Framework Title

First off, each of these files uses the file extension ‘.marko’, so it is not strictly html, or js/ts as seen in Angular and React. However, they are using ES6 import statements to include JavaScript modules, as is obvious from the first line. The second line illustrates their handling of adding a line of JavaScript, prefixed with a dollar sign. You’ll also notice that the html attributes aren’t strings they are JavaScript expressions, which allows assigning Booleans as well as strings. Finally, you can see that string interpolation inside the html as if with JavaScript’s template strings.

Now let’s look at one of the cooler features of Marko, its declarative style of handling async rendering. eBay’s Marko.js, a Lightweight Contender for the JavaScript Framework Title

As you can see this makes async rendering intuitive to implement, you simply pass a promise into an ‘await’ component, and you’re ready to go!

Next let’s look at a basic single-file component to see how styling, state and component methods are implemented. eBay’s Marko.js, a Lightweight Contender for the JavaScript Framework Title

As you can see from this excerpt, Marko has a way to manage the component’s state, much the same syntax as React. A side note that is important to this author, there is an implementation for Redux with Marko, so you can manage your syntax with one source of truth. Marko also allows you to create methods contained within the ‘class’ enclosure. You can see that binding the button to the method is no surprise, just passing the string name of the function to the on-click attribute. You can also see how the stylings are added to the html, using the more css oriented syntax of “[tag name].[class name]”.

Now let’s take a brief look at the file structure of a Marko project with a few routes. eBay’s Marko.js, a Lightweight Contender for the JavaScript Framework Title

This structure is pretty straight forward and certainly easy to read. Marko’s structure and compiler works such that this is more or less the only way to structure these files. It’s not as free as React or Angular in that respect. As you can see from the bubbles, shared components are separated from route-specific components. Not shown in this image are the ultimate JavaScript files that are used for the virtual DOM. They appear after compilation, and take the form [filename].marko.js.

To sum up, it’s clear that eBay’s Marko templating framework and NodeJS stack work well for them and their use case. It is made and optimized for NodeJS server-side rendering, a great choice for displaying lots of search results on a page with SEO in mind. Marko itself has lots of attractive features and a demonstrably faster load time than many other frameworks. Finally, Marko also has a syntax that is both fresh and intuitive. Only time will tell if Marko receives a greater market share, but it’s definitely worth a peek for anyone with a use case similar to eBay.

Recent Posts

See All