Navigation Menu

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JS in AMP #13471

Closed
dreamofabear opened this issue Feb 13, 2018 · 42 comments
Closed

JS in AMP #13471

dreamofabear opened this issue Feb 13, 2018 · 42 comments
Assignees
Labels
INTENT TO IMPLEMENT Proposes implementation of a significant new feature. https://bit.ly/amp-contribute-code P1: High Priority WG: runtime

Comments

@dreamofabear
Copy link

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

@dreamofabear dreamofabear added the INTENT TO IMPLEMENT Proposes implementation of a significant new feature. https://bit.ly/amp-contribute-code label Feb 13, 2018
@findar
Copy link

findar commented Feb 13, 2018

Is 3P JS the customized version of Preact mentioned at AMP Conf 2018?

@kristoferbaxter
Copy link
Contributor

kristoferbaxter commented Feb 13, 2018

3P JS is author written script intended to run within the Sandboxed Web Worker and mutate the DOM of the associated <amp-script> element in the parent page.

@m4dc4p m4dc4p mentioned this issue Feb 15, 2018
@rektide
Copy link

rektide commented Feb 15, 2018

I love the notion of this. And it sounds, fundamentally, like a good top level idea. I think AMP should do this.

But at the same time, this makes me very nervous. How much experience do we have with 3P JS in the field? What other examples of moving UI-interaction work into web-workers do we have?

This is super exciting and super cool, but I'd be terrified & mortified to consider any specific protocol for accomplishing this more than an experimental vessel at this early stage. It seems like there's a huge field of unknowns heading into the technics of this. I'm delighted and happy to see it happening, but I'm not aware of the royal collective we having much experience doing this kind of thing, and I'm concerned that early design decisions could end up being poor matches in the long run. That the protocol will proxy or emulate DOM sounds like a very good, stabilizing, promising thing, one that will permit the underlying protocols to change and evolve over time, and that's great, but this still seems like something I'd want to explore first as a venture, and make fit to update or replace down the road.

INTENT TO IMPLEMENT does a reasonable job reflecting some of the speculative nature of this work, but I wanted to voice by trepidation none the less. Thanks.

Is there any EcmaScript Module support here, or is this a single file, standalone script only?

@senthilp
Copy link

@choumx The “ahead-of-time” rendering should also be done by the 3P JS author right? Meaning they should put the markup inside <amp-script>.

@kristoferbaxter
Copy link
Contributor

@rektide Agree it's a good idea to continue to reinforce the speculative nature of this work. When announced at AMPConf earlier this week, a slide was used to communicate this.

screen shot 2018-02-15 at 12 53 48 pm

As for module support, the current plan is for author code to be a single standalone script per amp-script element – it's expected authors will bundle code, using an iife, to be inserted into a crafted scope exposing a DOM like API.

@kristoferbaxter
Copy link
Contributor

@senthilp – That's correct. One approach we've been brainstorming is a pre-render Node.js driven CLI leveraging the same DOM implementation shipping within the WorkerGlobalScope.

@donohoe
Copy link

donohoe commented 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.

@cramforce
Copy link
Member

@donohoe The meta goal here is to make "AMP go out of the way" from being a JS library to more of a set of UX guidelines. With this change developers can use the framework and tooling of their choice (Be it React, Preact, Angular, Vue, or WebPack, Rollup). At that stage, one doesn't need to use "parallel versions with divergent code bases" as one may either use just one version of use the exact same code base for both.

As you say this is a very exciting technical challenge. Lets keep this issue purely focused on that since there is, indeed, a lot of stuff to discuss (And Github has no threading). If you have additional meta comments, please feel free to file a new issue. I will also move further meta-comments or similar to a new issue should they come up here.

@ampprojectbot ampprojectbot added this to the Pending Triage milestone Feb 19, 2018
@ghelapratik
Copy link

@donohoe - We built a website using Native AMP HTML. So, we didn't have to build 2 versions of the same site ( Normal Desktop & AMP ). It did work for us. I think that if AMP allows 3P integration, then may be AMP can be a new web standard altogether.

@deepshik
Copy link

deepshik commented Apr 4, 2018

how to add custom js in amp

@web-apply
Copy link

web-apply commented May 19, 2018

@choumx no longer, simple JavaScript commands and operations must come to the amp. because the limited amp is detrimental to the user experience. In very simple in-page applications, for example (math calculation, currency convert, weight converter etc ..), we do the calculation in php with form action-xhr and show the results with json results.

responsive web inches to cm app :

<label>Inches</label>
<input id="inputInches" type="number" placeholder="Inches" oninput="LengthConverter(this.value)" onchange="LengthConverter(this.value)"> 
cm: <span id="outputcm"></span> 
<script>function LengthConverter(valNum) {  document.getElementById("outputcm").innerHTML=valNum/0.39370; } </script>

How can I do this in the page without using action-xhr in amphtML?

@niutech
Copy link
Contributor

niutech commented May 19, 2018 via email

@mchr3k
Copy link

mchr3k commented Jul 25, 2018

Can you comment on whether you intend to allow custom JS within AMPHTML ads?

The AMPHTML ads spec currently restricts AMPHTML ads to contain no custom JS. The only exception is whitelisted MRC-accredited vendors who can include arbitrary JS in a nested iframe.

The AMPHTML ads landing page claims that "These ads are only delivered after being validated, ensuring that they’re free of malware." and "AMPHTML ads need to be validated before they’re served, eliminating the risk of malware." It's unclear how such strong statements could be made if AMPHTML ads were allowed to contain arbitrary JS.

@cramforce
Copy link
Member

@m1ck43l There are currently no plans to allow JS in AMPHTML ads and I don't see that happening, nor that it is necessary.

@mchr3k
Copy link

mchr3k commented Jul 25, 2018 via email

@pdaexample
Copy link

Hi,

from this topic, any plan for loading custom script and allow us to access "window", "document", "local storage" etc..? why I ask that because lot of our custom tracking system need to access all of them.

@kristoferbaxter
Copy link
Contributor

Our current plan is to allow access to document, (potentially window), and other APIs as you would expect.

Access to localStorage is not planned since the storage is not always on the canonical domain of the document.

@ahsane
Copy link

ahsane commented Aug 23, 2018

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).

Any idea how much it is to be expected? 500kb? 1mb?

@cramforce
Copy link
Member

@ahsane There hasn't been significant discussion on the topic. But smaller than those values. I'd expect this to be around 50-100KB uncompressed.

Significant update on progress on this topic. We just released the WorkerDOM library https://amphtml.wordpress.com/2018/08/21/workerdom/ which we are planning to use to implement the JS in AMP feature.

@jeffwhelpley
Copy link

jeffwhelpley commented Oct 31, 2018

Hey, so what is the status of this? Can I experiment with WorkerDOM in AMP today?

@dreamofabear
Copy link
Author

It's in active development but still rough around the edges. You can follow along and play with it on a local build here: https://github.com/ampproject/amphtml/tree/master/extensions/amp-script

@dreamofabear
Copy link
Author

We're hoping for sometime Q2 next year. :)

@rrjanbiah
Copy link

Apologies for my ignorance...

When I open any AMP pages, I'm already logged into Google. So, will this custom JavaScript implementation add any session hijack attack? If not, how this will be handled? TIA

@dreamofabear
Copy link
Author

No, for several reasons. An important one is that AMP pages are served off a different domain (e.g. *.cdn.ampproject.org for the Google AMP Cache) than the launching page (e.g. google.com).

@rrjanbiah
Copy link

@choumx Thank you for your explanation!

@cvazac
Copy link
Contributor

cvazac commented Feb 20, 2019

Will there be access to the performance object?

@niutech
Copy link
Contributor

niutech commented Apr 3, 2019

You can now use Vue.js in an experimental <amp-script> extension - I have added the TodoMVC example in #21701.

@olsantiago
Copy link

amp-script still fails AMP Validation?

@kristoferbaxter
Copy link
Contributor

To use amp-script on a valid AMP document, your origin needs to be included in the origin trial.

You can signup for a token here: https://bit.ly/amp-script-trial

We expect these tokens to start being issued in the coming days.

@dreamofabear
Copy link
Author

#21867 enables amp-script in the AMP validator. In the meantime, you can start experimenting with it in local development.

@jaygray0919
Copy link

jaygray0919 commented Apr 22, 2019

@choumx may i ask a 'general' question? We use D3 JavaScript libraries extensively. I can share examples for you to look at if needed. We have experiment with vis-vega as an alternative to D3 to run on amp pages. But vis-vega (on non-amp pages) does not meet our needs.
Will we be able to run D3 on amp pages under the amp-script plans? If no (i.e. the D3 libraries are not 'ported' to amp), can the D3 JavaScript be re-written in amp-script to perform the same function?
aside: we have to run our D3 pages in an amp-iframe (we do this now) but there are issues ...

@dreamofabear
Copy link
Author

Good question. We're actually investigating D3 support at the moment, stay tuned.

@jaygray0919
Copy link

We can help! if you want external feedback. Here is a link that uses several libraries (which you may not support). Here is a link that we hope you could support. Here is a reference for a pure D3 instance. Note: several are implemented an non-valid AMP pages (we were comparing a native implementation to an iframe implementation)

@dreamofabear
Copy link
Author

/cc @patrickkettner

@ghost
Copy link

ghost commented May 17, 2019

To use amp-script on a valid AMP document, your origin needs to be included in the origin trial.

You can signup for a token here: https://bit.ly/amp-script-trial

We expect these tokens to start being issued in the coming days.

Hello

How can I get the token?

Or is there anyway to generate the token on my own server?

@Jouvan
Copy link

Jouvan commented May 27, 2019

Is there any chance to display Ads on AMP Page without hardcoding? Only just using Javascript? Thank you

@patrickkettner
Copy link
Contributor

hi @bloolight! The token needs to be generated by us, the amp team. This is because they end up being included in the chromium binary. As mentioned in the section you quoted, you can sign up for a token using that link (https://bit.ly/amp-script-trial). You will be emailed the token once it is accepted and generated.

cheers!

@ghost
Copy link

ghost commented May 30, 2019

Hi @patrickkettner

Thanks for your response.

I've PM to you via email. (patrickkettner@gmail.com)

Could you please check it and let me know your thoughts, please?

Regards.

@ghost
Copy link

ghost commented May 31, 2019

@patrickkettner Any update for me, please?

@Jouvan
Copy link

Jouvan commented May 31, 2019

@patrickkettner any update for me, please?

@dreamofabear
Copy link
Author

Closing now that amp-script is generally available.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
INTENT TO IMPLEMENT Proposes implementation of a significant new feature. https://bit.ly/amp-contribute-code P1: High Priority WG: runtime
Projects
None yet
Development

No branches or pull requests