Marfeel AMP Shell

Q1 2017

Mission Statement

Easy and painless PWA that maximises the RPU (Revenue Per User) by boosting user engagement. The longer the user stays the more money a publisher makes.

At Marfeel we believe high engagement can only be achieved by combining great UX and great performance

MRF = f (♥, ⚡, $)

User Experience

  • Smooth native-like UX, orchestrations and gestures
  • Three navigation levels
  • Key re-circulation elements: deep linking, continuous swipe, etc

360º Solution


  • Valid Lighthouse PWA providing save to home screen, push notifications, offline caching, etc.
  • Manage common UI elements: header, footer, sharing, side bar
  • Nice & Smooth UI Orchestration
  • Content prefetching as user scrolls
  • Manage views life cycle as user navigates (pre-rendering, activation, pausing, removing, etc.)
  • Usage instrumentation (PV, events, etc)
  • A single HTTP request to fetch the entire document and make all elements available

Smooth Swipe

  • 3-Column recycling strategy
  • Next Column pre-render
  • Native browser scroll (browser bar collapses when scrolling)

Navigation Levels

  • Different levels for Article details and Sections
  • Translates into 2 different ViewNavigators each with 3 different columns

Infinite Scroll Strategy

When a user lands to an article the Shell adds infinite scroll and automatically loads and renders the home page at the end of an article


  • Could be base implementation of amp-lightbox-viewer
  • Swipe Transitioner
  • Column recycling strategy
  • Model Adapter
  • Decorators: bullets, numeric pager
  • Event dispatching (Instrumentation, Browser History, etc.)
  • API: next, previous, jump, etc.
  • UI customisation depending current page


  • Used to load AMP documents in the ViewNavigator columns and infinite scroll
  • Standard AMP extension to load AMP documents following the default AMP life cycle
  • Abstract communication between Shell and the AMP Shadow API

   <amp-doc-loader uri="/amp-doc1.html"/>
   <amp-doc-loader uri="/amp-doc2.html"/>
   <amp-doc-loader uri="/amp-doc3.html"/>
   <amp-doc-loader uri="/amp-doc4.html"/>
   <amp-doc-loader uri="/amp-doc5.html"/>
   <amp-doc-loader uri="/amp-doc6.html"/>
   <amp-doc-loader uri="/amp-doc7.html"/>
   <amp-doc-loader uri="/amp-doc8.html"/>

Why use AMP docs?

  • Use mobile-ready third party components implementation available: ad server, analytics providers, widgets, video players
  • One implementation shared for Google Search and for publisher's mobile site.
  • Common language between Marfeel and the publisher
  • Publisher keeps control

Current AMP-Shadow + Service Workers limitation

  • Amp shadow cannot adopt an amp doc from the DOM
  • PWA inside WebViews (i.e Facebook App)
  • When no SWs are available (like Safari), users just see a normal AMP page.
  • Even if SWs are available there's a big chance that the user only visits once the publisher site (54% of the users only visit one time a site)

<!-- An amp-doc can be adopted from the DOM, 
     not only from a doc Fragment -->
         <h1>This is the document rendered inline</h1>
         <p>There should be no need for a second round trip</p>
   <amp-doc-loader uri="/doc1.htm2"/>
   <amp-doc-loader uri="/doc1.htm3"/>
   <amp-doc-loader uri="/doc1.htm4"/>
   <amp-doc-loader uri="/doc1.htm5"/>

Marfeel Shell is AMP managed

  • Marfeel AMP Shell doesn't necessarily validate as an AMP document but can use all the AMP power
  • Complete and performant component lifecycle management
  • Proper DOM manipulation
  • Ready to use key services
    • Viewport (listen scroll events)
    • Instrumentation
  • Mobile-ready UI elements: sidebar, amp-carousel, sharing bar
  • It could promote any AMP document to a PWA



It's not only about UX and Speed


Pricing Cluster & Optimizers

Revenue and Fill Rate

Revenue and CTR




Floor Price

Floor Price and eCPM


<!-- Marfeel AMP Shell can render amp elements -->

<script src="amp-shadow.js" />
<script src="marfeel-amp-shell.js" />
         <li>Menu 1</li>
         <li>Menu 2</li>
      <amp-doc-loader uri="/doc1.htm2"/>
      <amp-doc-loader uri="/doc1.htm3"/>
      <amp-doc-loader uri="/doc1.htm4"/>
      <amp-doc-loader uri="/doc1.htm5"/>


  • In order to mantain native browser scroll, this component manages which is the current column of the current navigation level, playing with position fixed / static values
  • Hackish code to avoid iOS flickers (common when promoting / demoting hardware accelerated layers)

Marfeel Cache (Gutenberg)

- Server side measuring AMP components above the fold
- First AMP Doc (Necessary for progressive enhancement)
- Shell UI
- Ability to serve AMP docs without styles or UI elements

Marfeel AMP Shell use case (I)

  1. When user accesses the document below is returned including content document and shell

    <script src="amp-shadow.js" />
    <script src="amp-shell.js" />
             <li>Menu 1</li>
             <li>Menu 2</li>
             <body> ...  </body>
          <amp-doc-loader uri="/doc1.htm3"/>

Marfeel AMP Shell use case (II)

  1. The viewport can be rendered with just one roundtrip to the server
  2. A SW is registered if possible
  3. The shell is cached
  4. User visits for the second time:
    1. If SW available, proxy catches the request, serves the shell immediately and loads the document
    2. if SW is not available the shell will be rendered server side again (ie. Safari, 54% of visits)

Next Steps (I)

  • Contribute amp-shadow.js to support:
    • Marfeel amp shell being an amp-doc
    • promote dom element into amp-doc
  • Fix Horizontal axis resources preload

Next Steps (II): marfeel-amp-shell.js

  • amp-doc-loader
  • amp-view-navigator + swipeTransitioner
  • windowScrollManager
  • levelManager + levelTransitioner
  • amp-fetch