ampproject / ampproject/amphtml
I2I: Standalone Bento Runtime
- Dominant language
- JavaScript
- Stars
- 14.9k
- Forks
- 4.1k
- PR merge metrics
- No merged PRs in 30d
Description
Bento extensions are "standalone", included like:
```html
```
Optionally, we include `custom-elements-polyfill.js` once for compatibility.
```html
```
A minimal `bento-*-1.0.js` file is **very large**. This is caused by including `preact` and `PreactBaseElement`, which are identical on all Bento extensions.
```
amp make-extension --name=amp-example --bento
amp dist --core_runtime_only --extensions=amp-example
cat dist/v0/bento-example-1.0.js | brotli -c | wc -c
16127
```
## Goal
Share `preact`/`PreactBaseElement` as a "Bento runtime" so that extension files are each 15-16K smaller compressed.
### Non-goals
- Updating AMP versions of the extension files (like `amp-timeago-1.0.js`) _ Updating `npm` releases of Web Components, since they should share `preact` as a peer dependency. _ Reducing the size of the shared runtime.
## Overview
1. Rename `custom-elements-polyfill.js` to `bento.js`. **It is no longer optional.**
2. Wrap extension code so that it does not execute until a global `BENTO` is available. Provide `BENTO` from `bento.js`.
## Details
### `bento.js` is asynchronous
Unlike `custom-elements-polyfill.js`; `bento.js` can be asynchronous because extensions are **runtime-blocked.**
```js
```
We wrap extension code:
```diff
- defineElement();
+ (self.BENTO = self.BENTO || []).push(defineElement);
```
Note that we don't call `defineElement` in the extension bundle, but only provide it so that `bento.js` calls it instead. This is similar to the AMP runtime's async loading mechanism, but simpler since we do not version-lock.
### Preact is defined by `BENTO`
On compiled code, global `preact` functions are not bundled, but instead provided by `BENTO`. This is fine since extension code should not execute until `BENTO` is available.
```diff
- const C = fR(
+ const C = BENTO['#preact'].forwardRef,
({children}, r) =>
- h(
+ BENTO['#preact'].h(
- Fragment,
+ BENTO['#preact'].Fragment,
null,
children
)
);
```
Likewise, we provide `PreactBaseElement` as `BENTO.BaseElement`:
```diff
- class B extends P {
+ const {PreactBaseElement} = BENTO['#preact/base-element'];
+ class B extends PreactBaseElement {
```
## Differences in filesize
| | before | after | Δ |
| ------------------------------- | ---------: | ---------: | ----------: |
| `bento.js` | n/a | `18.01` kB | `18.01` kB |
| `custom-elements-polyfill.js` | `2.21` kB | n/a | n/a |
| `bento-accordion-1.0.js` | `18.61` kB | `7.90` kB | `-10.71` kB |
| `bento-base-carousel-1.0.js` | `23.29` kB | `9.11` kB | `-14.18` kB |
| `bento-brightcove-1.0.js` | `20.10` kB | `6.21` kB | `-13.88` kB |
| `bento-date-countdown-1.0.js` | `17.70` kB | `3.29` kB | `-14.41` kB |
| `bento-date-display-1.0.js` | `17.34` kB | `3.14` kB | `-14.21` kB |
| `bento-embedly-card-1.0.js` | `18.66` kB | `4.57` kB | `-14.09` kB |
| `bento-facebook-1.0.js` | `19.11` kB | `5.11` kB | `-14.00` kB |
| `bento-fit-text-1.0.js` | `16.72` kB | `1.63` kB | `-15.10` kB |
| `bento-iframe-1.0.js` | `17.33` kB | `3.04` kB | `-14.29` kB |
| `bento-inline-gallery-1.0.js` | `16.35` kB | `3.83` kB | `-12.52` kB |
| `bento-instagram-1.0.js` | `16.98` kB | `2.67` kB | `-14.31` kB |
| `bento-jwplayer-1.0.js` | `21.15` kB | `7.25` kB | `-13.90` kB |
| `bento-lightbox-1.0.js` | `17.32` kB | `3.10` kB | `-14.23` kB |
| `bento-lightbox-gallery-1.0.js` | `25.15` kB | `11.12` kB | `-14.02` kB |
| `bento-mathml-1.0.js` | `18.94` kB | `5.04` kB | `-13.90` kB |
| `bento-render-1.0.js` | `16.53` kB | `1.87` kB | `-14.66` kB |
| `bento-selector-1.0.js` | `17.98` kB | `3.62` kB | `-14.36` kB |
| `bento-sidebar-1.0.js` | `18.27` kB | `4.27` kB | `-14.00` kB |
| `bento-social-share-1.0.js` | `21.18` kB | `6.30` kB | `-14.88` kB |
| `bento-soundcloud-1.0.js` | `17.05` kB | `2.79` kB | `-14.26` kB |
| `bento-stream-gallery-1.0.js` | `23.79` kB | `9.61` kB | `-14.18` kB |
| `bento-timeago-1.0.js` | `24.13` kB | `9.76` kB | `-14.37` kB |
| `bento-twitter-1.0.js` | `18.69` kB | `4.69` kB | `-14.00` kB |
| `bento-video-1.0.js` | `18.41` kB | `4.31` kB | `-14.10` kB |
| `bento-video-iframe-1.0.js` | `19.21` kB | `5.19` kB | `-14.03` kB |
| `bento-vimeo-1.0.js` | `19.89` kB | `5.92` kB | `-13.97` kB |
| `bento-wordpress-embed-1.0.js` | `17.19` kB | `2.88` kB | `-14.31` kB |
| `bento-youtube-1.0.js` | `20.10` kB | `6.17` kB | `-13.93` kB |
Contributor guide
Assessment
This issue has not been assessed yet.