AMP strives to provide a consistently great experience to all users across the web by encouraging the use of high-functioning and seamless components that are ready to go out of the box.
Some web experiences require a high amount of customization that goes beyond the state binding capabilities of
amp-bind and the dynamic data retrieval and templating functionality of
amp-mustache. For those one-off cases, AMP has created
<amp-script> component. The example below demonstrates how to use
<amp-script> component registers a Web Worker to run on a separate thread than the main page. The Web Worker is given its own copy of the DOM through
amp-script component sends messages between the Web Worker thread and the main thread, causing any changes the user makes on the main DOM to be echoed on the Web Worker's false DOM. In turn, the Web Worker can then update the false DOM, which is reflected on the main DOM.
Custom scripts caching
<amp-script> as a page that doesn't include it.
To guarantee AMP pages will load consistently fast and with smooth UIs, limitations exist on
- Registering event handlers.
- Splitting a TextNode into multiple TextNodes, to allow for frameworks that require it.
The DOM inside
<amp-script> tags should be almost identical before and after initialization.
For example, if starting with the code below:
<text> Hello world </text>
Worker DOM permits minor changes in structure but not content:
For user experience and security reasons,
amp-script enforces DOM manipulation restrictions.
When a user interacts with elements wrapped inside an
fetch. Here DOM changes can be requested after the response is returned to the user and for less than one second afterward. If a script mutates the DOM outside of a permitted window, this will result in a fatal error and the
<amp-script> component will terminate the Web Worker. A terminated
<amp-script> component will not run again.
There is no user interaction required to manipulate the DOM if the
<amp-script> component has a fixed height.
<amp-script> component tags. This includes other AMP components. The
<amp-script> component considers
document.body to be the
<amp-script> element and not the document's
If you were to call
document.body.appendChild(document.createElement('span')) within the script imported into an
<amp-script> element in the following document:
<body> <p>Hello!</p> <div> <amp-script layout="container" src="customjs.js"> </amp-script> </div> </body>
It would result in this:
<body> <p>Hello!</p> <div> <amp-script layout="container" src="customjs.js"> <span></span> </amp-script> </div> </body>
All event triggers are allowed.
Some synchronous methods are disallowed in
<amp-script> and replaced with alternatives, such as
Element.getBoundingClientRect() could not be implemented in a Web Worker, an async alternative to it,
getBoundingClientRectAsync(), is provided.
getBoundingClientRectAsync() returns a
Promise instead of returning the result directly.
View this chart to see WorkerDOM supported APIs.