Description
Bento extensions are "standalone", included like:
<script async src="https://cdn.ampproject.org/v0/bento-timeago-1.0.js"></script>
Optionally, we include custom-elements-polyfill.js
once for compatibility.
<script src="https://cdn.ampproject.org/v0/custom-elements-polyfill.js"></script>
<script async src="https://cdn.ampproject.org/v0/bento-timeago-1.0.js"></script>
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
) _ Updatingnpm
releases of Web Components, since they should sharepreact
as a peer dependency. _ Reducing the size of the shared runtime.
Overview
- Rename
custom-elements-polyfill.js
tobento.js
. It is no longer optional. - Wrap extension code so that it does not execute until a global
BENTO
is available. ProvideBENTO
frombento.js
.
Details
bento.js
is asynchronous
Unlike custom-elements-polyfill.js
; bento.js
can be asynchronous because extensions are runtime-blocked.
<script async src="https://cdn.ampproject.org/v0/bento.js"></script>
We wrap extension code:
- 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.
- 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
:
- 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 |