Do you build things with AMP? Fill out the AMP Developer Survey!
AMP

Stosowanie niestandardowego kodu JavaScript na stronach AMP

AMP dąży do zapewniania niezmiennie wspaniałych wrażeń wszystkim użytkownikom w sieci, zachęcając do stosowania wydajnych i niepowodujących problemów, gotowych do użycia składników.

Niektóre materiały internetowe wymagają znacznego dostosowania, które wykracza poza możliwości wiązania stanów składnika amp-bind oraz dynamicznego pobierania danych i funkcji tworzenia szablonów składników amp-list i amp-mustache. Dla tych jednorazowych przypadków w ramach AMP stworzono składnik <amp-script>, który pozwala na użycie dowolnego kodu JavaScript na stronie AMP bez wpływu na ogólną wydajność strony.

Wstawianie niestandardowego kodu JavaScript

Strony AMP obsługują własny kod JavaScript za pomocą składnika <amp-script>. Poniższy przykład pokazuje jak używać składnika amp-script z plikiem JavaScript ładowanym z adresu URL:

<!doctype html>
<html >
<head>
  ...
  <script async custom-element="amp-script" src="https://cdn.ampproject.org/v0/amp-script-0.1.js"></script>
<body>
  ...
  <amp-script layout="container" src="https://example.com/myfile.js">
    <p>Initial content that can be modified from JavaScript</p>
  </amp-script>
  ...
</body>
</html>

Składnik <amp-script> rejestruje proces Web Worker w celu uruchomienia go w wątku oddzielnym od głównej strony. Proces Web Worker otrzymuje swoją własną kopię modelu DOM poprzez użycie przez składnik amp-script modelu DOM procesu Worker. Dzięki temu Web Worker może bez modyfikacji korzystać z bibliotek JavaScript, takich jak React i jQuery.

Składnik amp-script wysyła wiadomości między wątkiem procesu Web Worker a wątkiem głównym powodując, że wszelkie zmiany dokonane przez użytkownika w głównym modelu DOM będą powtórzone w fałszywym DOM procesu Web Worker. Web Worker może następnie aktualizować fałszywy DOM, co jest odzwierciedlane w głównym modelu DOM.

Buforowanie skryptów niestandardowych

Serwer buforujący AMP Cache obsługuje pliki niestandardowego kodu JavaScript wstawiane za pomocą składnika <amp-script> w taki sam sposób, w jaki obsługuje skrypty składników AMP, co gwarantuje, że żaden niestandardowy kod JavaScript nie spowolni dokumentu AMP.

Serwer AMP Cache buforuje pliki JavaScript, a następnie je dostarcza. Użytkownicy mogą oczekiwać takiej samej wydajności od strony używającej składnika <amp-script> jak od strony, która go nie zawiera.

Używanie składnika <amp-script>

Aby zagwarantować, że strony AMP będą konsekwentnie ładowane szybko i z płynnie działającymi UI, na składnik nałożono ograniczenia.

Inicjowanie

JavaScript w obiekcie Web Worker zezwala na minimalną zmianę modelu DOM przy obciążeniu. Podczas tej fazy dozwolone są następujące zmiany:

  • Rejestrowanie programów obsługi zdarzeń.
  • Podział węzłów TextNode na wiele węzłów TextNode, aby umożliwić obsługę platform, które tego wymagają.

Model DOM wewnątrz znaczników składnika <amp-script> powinien być prawie identyczny przed i po zainicjowaniu.

Na przykład, jeśli zaczyna się od poniższego kodu:

<text> Hello world </text>

Model DOM procesu Worker zezwala na drobne zmiany w strukturze, ale nie zawartości:

 <text>Hello </text><text>world</text>

Manipulacja modelem DOM

Ze względu na wrażenia użytkownika i bezpieczeństwo składnik amp-script wymusza ograniczenia manipulacji modelem DOM.

Interakcja z użytkownikiem

Gdy użytkownik wchodzi w interakcję z elementami w otoce składnika <amp-script>, niestandardowy kod JavaScript musi szybko zwrócić manipulacje modelem DOM, gdy są potrzebne. Domyślnie zmiany w DOM są dozwolone przez czas krótszy niż jedna sekunda od początkowej interakcji. Znaczącym wyjątkiem jest sytuacja, gdy kod musi pobrać dane z sieci przy użyciu interfejsu fetch. Tutaj zmiany DOM mogą być wymagane po zwróceniu odpowiedzi użytkownikowi, a następnie przez czas krótszy niż jedna sekunda. Jeśli skrypt zmieni DOM poza dozwolonym przedziałem czasu, spowoduje to błąd krytyczny i składnik <amp-script> wymusi zakończenie procesu Web Worker. Po wymuszonym zakończeniu składnik nie zostanie wykonany ponownie.

Swobodne zmiany

Jeśli składnik <amp-script> ma ustaloną wysokość, do manipulowania modelem DOM nie jest wymagana interakcja z użytkownikiem.

Rozmiar skryptu

AMP narzuca limit 150 kilobajtów niestandardowego kodu JavaScript na każdej stronie. Limit ten jest dzielony między wszystkie składniki <amp-script> na danej stronie. Każda zewnętrzna biblioteka JavaScript musi zostać zaimportowana do każdego składnika <amp-script>.

Zakres

Wszystkie elementy DOM, z którymi mają współpracować niestandardowe pliki JavaScript, muszą być otoczone znacznikami składników <amp-script>. Dotyczy to również innych składników AMP. Składnik <amp-script> uważa, że document.body jest elementem składnika <amp-script>, a nie elementem sekcji dokumentu.

Jeśliby wywołać funkcję document.body.appendChild(document.createElement('span')) w skrypcie zaimportowanym do elementu <amp-script> w następującym dokumencie:

<body>
  <p>Hello!</p>
  <div>
    <amp-script layout="container" src="customjs.js">
    </amp-script>
  </div>
</body>

Zwróciłaby ona to:

<body>
  <p>Hello!</p>
  <div>
    <amp-script layout="container" src="customjs.js">
      <span></span>
    </amp-script>
  </div>
</body>

Wyzwalacze zdarzeń

Dozwolone są wszystkie wyzwalacze zdarzeń.

Ograniczenia interfejsu API

Niektóre metody synchroniczne są niedozwolone w składniku <amp-script> i zastąpiono je alternatywami, takimi jak Element.getBoundingClientRect()). Metody Element.getBoundingClientRect() nie można zaimplementować w procesie Web Worker, więc zapewniona jest jej asynchroniczna alternatywa, getBoundingClientRectAsync(). Metoda getBoundingClientRectAsync() zwraca Promise, zamiast zwrócić bezpośrednio wynik.

Interfejsy API obsługiwane przez model DOM procesu Worker przedstawia ta tabela.