Viking CMS

Philosophy

  • SEO before speed.
  • Speed.
  • Sooner is better than perfect.
  • Our computers do the hard work.
  • Empower developers to submit straight HTML, CSS, and Javascript.
  • Don't let developers break things.

User Documentation

Who is it for?

Viking CMS is for companies who have content-based websites with staff developers with basic HTML/CSS skills, and producers who generate story content. We can take any HTML/CSS that you give us and make it into a full featured, enterprise-scale CMS. It is framework-agnostic, and there is no CSS/JS overhead that you would find with Wordpress or similar. It is literally whatever you want it to be. Your company creates your design, and we turn it into a CMS, without a single line of unnecessary front-end code. Each customer has its own Javascript and CSS bundle, you won't find any extra "plugins" or features dangling around, slowing down your UX.

If you have developers who write HTML/CSS and don't want to hire a front-end and back-end to fix the errors they cause, or want more features than a simple Wordpress can offer your organization, Viking CMS is the right product for you!

Where did we come from?

Viking started as a solution to the problems encountered by a front-end working with developers who were allowed to publish raw HTML to a CMS. We found ourselves constantly chasing down CSS collisions and Javascript errors caused by multiple parties working in a shared environment that wasn't built to prevent collisions of CSS and/or Javascript. It turns out, developers are really good at writing markup that makes pretty things on the screen, but they are not good at thinking about the lifecycle of the whole product, or even considering the effects of their contribution on other developers. So often, they would add HTML/CSS/Javascript and then complain that "our" navigation was broken on that particular page!

The first feature that we built was name-spacing of page-level CSS, which solved the ongoing CSS-collision problem. However, we are still chasing external stylesheets around, even though developers are clearly instructed not to use external stylesheets unless absolutely necessary. Old habits die hard I guess.

The other problem with other CMS's is speed. They typically render infrequently, and rely heavily on their CDN to take the load. That is fine, but for the producers and developers, this often means 10-20 minute cache times before they see their changes live, either in content or pages (custom HTML). We found that completely unacceptable, so the second feature was to allow each page to have a separate cache time associated with it, and to allow a "cache=false" query string parameter for instant viewing of changes. Perhaps /home has a cache time of only 20 seconds, but a infrequently-accessed page could have 600 seconds. This cache time is not just internal, but passed on to the CDN as well.

In a media environment, the content is not always internal. There can be weather, elections, school closings, lake levels, marine weather, etc coming from outside sources. Other CMSs expect that external content has to be client-side rendered, since it can't be rendered on the server (or in rare cases, isomorphic React is used, which presents its own problems). This adversely affects SEO and page-load speed, as well as content jumping around the page during the JS execution, which Google *really* doesn't like (they call it Cumulative Layout Shift). Our solution was a combination of a headless CMS and a high-speed rendering engine.

How does it work?

You can think of Viking as a headless CMS that also server-side renders. Each page has data feeds associated with it, which are either relative URLs (fetching from itself), or absolute urls (fetching externally). This is interesting because it makes Viking fundamentally self-talking. It requests data from itself via HTTP in order to render a page. If an external URL is used, it requests from that URL. This makes Viking extremely flexible, and also extremely fast. It also makes it dangerous, because external content is untrustworthy. It is not recommended to use external URLs that have not been vetted by Viking. We are happy to set up what we call a task-runner that can parse, validate, and canonicalize external data feeds, so that your website is not adversely affected by failures or changes in any external data feed. Some examples: Weather Data, School Closings Data, AP Content.

Data Structure

The overall data structure is a pretty simple category/story association, with a many-to-many relationship. Publishers are users with extra permissions, and have a one-to-many relationship with their stories, as expected. There are other fun items like banners and skycams as well, that are more or less stand-alone inside of Viking. Images have a library, and are associated with stories, not contained in them.

Video

Viking is built to function solely with your choice of video hosting service. We have used both ViewNexa and Field59, and believe that it is more important that you choose the video product that works for your team. They handle encoders, transcoding, and cloud delivery. Our video library serves basically as a data association between your assets and our stories. Like images, videos are associated with stories, not contained in them.

Rendering

We decided early on to use EJS as a rendering engine; it is incredibly fast. It can be used on the front-end, and it is tiny. It is a REGEX-based engine, so it is very sensitive to semantic errors. Developers can use EJS in their designs directly, if they learn how, but it is not recommended because if done incorrectly they can break things. Any dynamic content that developers need should be requested from Viking. We will happily create a partial for you that your developers can invoke with whatever data feed is appropriate; the partial will internally handle errors so the page doesn't break.

Caching

  • CDN - the HTML content is held at a server physically near your user (TTL in seconds).
  • Memcache - the HTML content and data feed content is held in RAM in a distributed network of servers in the AWS datacenter in Virginia (TTL in milliseconds)
  • Server - HTML content, data feed content, and internally cached data structures are held in the RAM of individual servers in Virginia (TTL in microseconds)

We use a layering approach in order to keep content fresh, cut computational expenses, cut delivery expenses, and to allow for extremely fast demand-based horizontal scaling of servers. Most CDNs don't offer the speed or fine-grained control of caching that we do.

Architecture

Every Viking CMS affiliate is horizontally-scalable. That means that as demand increases, servers are created in parallel. Your DNS is directed to a load-balancer that parcels out requests to multiple servers as needed. The individual servers stay up to data with each other via a distributed Memcache, so that each server's content will always agree with the others within a few milliseconds.

CSS

Cascading Style Sheets. The most boring, and troublesome part of web development! There are so many schools of thought on how to best handle styles: element-level, inline, external, deferred, partial, etc. Each method has its pro's and con's. We have tried to thread the needle, and find the most effective method for your developers. Instead of trying to create one unified CSS environment for your website, we've segmented it based on what is most important for your SEO metrics:

  • Above The Fold
  • Below The Fold
  • Page Level

Here is how that works:

  1. We analyze your most frequently accessed pages from off-platform (i.e. a user that found you via google, and never visited your site before), and we inline only the CSS they need for the "above the fold" content (the first render, before the user start scrolling). Above the fold styles are minimized and inlined in your page, in the header, so those users have the fastest experience of your content. The "global" CSS environment is created here, because it requires no additional requests and is instantly available as soon as the initial request is complete. Our target for the initial request completion is 50ms, far faster than competing platforms.
  2. The rest of the commonly accessed content has it's styles bundled up in an external stylesheet called `below-the-fold`, which will be downloading while your user is viewing the above the fold content. When they scroll down, or click on another page, it will be ready for them. This includes all the styles for less frequently used views that Viking has built for you.
  3. Page-level CSS (developer-submitted) for the various custom HTML pages is compiled, checked for errors, name-spaced for your protection, and inlined only in the appropriate page where it needs to be. This protects your developers from each other, and also creates the best SEO metrics for your custom pages. This prevents bulking of the "below-the-fold" CSS on less-commonly accessed pages, or short duration products.

There is one downside to our method, the first HTTP request can be 20% larger than would otherwise be required if using a single, external stylesheet that would include both `above-the-fold` and `below-the-fold` CSS. However, once the "session" is established, all subsequent HTTP requests treat the `above-the-fold` CSS content as an external stylesheet. Considering that SEO focuses on the *first* request, we feel that we are justified in optimizing above-the-fold content. This is especially true considering that your HTML content is typically less than 1% of the total page resources. Images and videos are the biggest bandwidth hogs for your users, and they get the most of our attention for SEO.