question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Motivation

AMP offers the ability to easily author web pages with good performance and UX characteristics. One of the tradeoffs of AMP has made to guarantee good performance is the restriction on executing custom JS—this avoids the problems of heavy, slow JS but also prevents reasonable JS use cases. Features like amp-bind help but, compared to non-AMP pages, it’s still more difficult for page authors to write dynamic and interactive widgets and often impossible to reuse existing JS code.

Our goal is to allow custom JS to run in a constrained environment for the purpose of building dynamic and interactive UI components. For example, this feature would support rendering a React component as a UI element on an AMP page.

Requirements

  • Allow AMP publishers to author custom JS that renders a UI component
  • Preserve AMP’s UX invariants of instant-loading and no-page-jumping
  • Follow AMP’s design principles i.e. “user experience > developer experience” and “graceful degradation”
  • Maintain strong security and privacy characteristics

Proposed design

We propose to allow 3P (custom) JS to run on a web worker that receives user gesture events from the page and sends mutation requests to the page over postMessage. The 3P JS will be run inside a custom-built sandbox and virtual DOM environment in the worker. The “worker DOM” offers DOM mutation APIs like setAttribute() and appendChild(), and forwards these as mutation requests to the page. The page then runs these mutation requests through a sanitizer—for security and to preserve AMP’s UX invariants—and performs these mutations on the real DOM. This functionality will be offered in a new AMP extension: <amp-script>.

js in amp_ i2i

To preserve AMP’s instant-loading behavior, <amp-script> will support “ahead-of-time” rendering. Similar to server-side rendering, the HTML markup for the initial render state of the 3P JS will be inlined as children of <amp-script> and hydrated at runtime. This ensures that the latency of creating the web worker and running the 3P JS doesn’t impact time to first contentful paint.

To preserve AMP’s “no-page-jumping” invariant, mutation requests received from the worker will only be honored within a small window after a user gesture.

Proposed syntax:

<script async custom-element="amp-script" 
    src="https://cdn.ampproject.org/v0/amp-script-0.1.js"></script>

<!-- amp-script supports all defined-size layout types. -->
<amp-script src=”https://pub.com/my_custom_component.js” layout=responsive>
  <!-- The children are the “ahead-of-time” render. -->
  <div>...</div>
</amp-script>

3P JS can be provided either as an <script type=javascript/worker> element or as an https:// source URL. If the URL is specified, the file will be versioned and cached on an AMP Cache (for pages served from Cache). This avoids skew between the AMP page HTML and 3P JS. Similar to AMP’s existing 50KB CSS size constraint, the 3P script will have a reasonable max file size that will be enforced (actual size TBD).

/cc @cramforce @kristoferbaxter

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:102
  • Comments:42 (12 by maintainers)

github_iconTop GitHub Comments

25reactions
donohoecommented, Feb 15, 2018

You do understand that this is just another step in the direction of forking the web as-is and making a whole new version?

From a technical perspective this is a very exciting challenge, but the end result is that any company with a web presence must now create a regular HTML page and also create a separate AMP-specific version with increasingly divergent code base.

Basically, everything needs to be built twice. So… where does AMP end and the web begin now? The game appears to be forking the web and re-inventing the web browser.

10reactions
dreamofabearcommented, Nov 26, 2018

We’re hoping for sometime Q2 next year. 😃

Read more comments on GitHub >

github_iconTop Results From Across the Web

Use custom JavaScript in AMP pages - amp.dev
amp -script lets you write and run your own JavaScript in a way that maintains AMP's performance guarantees. Most AMP components enable common...
Read more >
How to add custom JavaScript to AMP HTML - Stack Overflow
In order to use your custom JavaScript in AMP HTML, make use of <amp-script> component. Below, your AMP HMTL code;
Read more >
Google AMP - Custom Javascript - Tutorialspoint
Amp has its own component to take care of the job which is suppose to be done by the additional script which is...
Read more >
You can now add custom JavaScript to AMP pages
Custom JavaScript can now be added to AMP pages, Google announced this week. The amp-script component can be used to enable user ...
Read more >
How to add custom scripts in AMP - AMPforWP
1 – External Scripts. An amp-script element can load a JavaScript file from a URL. This is usually the best way to integrate...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found