web.dev 工程網誌 #1:我們如何製作網站並使用網頁元件

這是 web.dev 工程網誌中的第一篇文章。接下來幾個月內,我們希望在未來幾個月內,分享這些工作成果的可行見解,因此請密切留意有工程網誌標記的貼文! 以下將探討靜態網站的建立程序,以及 (選擇性!)JavaScript 程式碼

web.dev 提供如何建構新式網頁體驗的內容,並可讓您評估網站效能。熟悉程度的使用者可能會發現我們的 Measure 頁面只是 Lighthouse 的介面,而 Chrome 的開發人員工具也提供這項功能。 登入 web.dev,系統會定期對你的網站執行 Lighthouse 稽核,方便你瞭解分數的長期變化。 我們稍後會重新瀏覽「評估」頁面,因為我們認為這頁面的內容相當特別。🎊

簡介

基本上,web.dev 是一個靜態網站,由一組 Markdown 檔案產生。 我們選擇使用 Eleventy,這是一款精美的可擴充工具,可讓您輕鬆將 Markdown 轉化為 HTML。

我們也會使用新版 JavaScript 套件,但這些套件只適用於支援 type="module" 的瀏覽器,包括 asyncawait。此外,我們也幸好使用長效型瀏覽器所支援的功能,但無法使用少數較舊的版本。 由於我們是靜態網站,因此不一定要使用 JavaScript 閱讀我們的內容。

建構程序完成 (包括產生靜態 HTML,以及使用匯入工具組合我們的 JavaScript) 後,web.dev 可以由簡單的靜態伺服器代管並進行測試。 網站幾乎是完全靜態的,但我們有一些特殊需求,仍然可運用自訂 Node.js 伺服器。 這包括網域無效重新導向,以及剖析使用者偏好語言 (即將推出的國際化功能) 的程式碼。

靜態產生

web.dev 上的每個網頁都是以 Markdown 編寫。 所有網頁都含有前事內容,說明每篇貼文的中繼資料。 系統會將這項中繼資料擷取至每個頁面的版面配置中,並建立標題、標記等。範例如下:

---
layout: post
title: What is network reliability and how do you measure it?
authors:
  - jeffposnick
date: 2018-11-05
description: |
  The modern web is enjoyed by a wide swath of people…
---

The modern web is enjoyed by a wide swath of [people](https://www.youtube.com/watch?v=dQw4w9WgXcQ), using a range of different devices and types of network connections.

Your creations can reach users all across the world...

這個前端可讓我們定義任意屬性,例如作者、發布日期和標記。Eleventy 輕鬆針對幾乎所有外掛程式、範本或其他情境,以資料的形式呈現前置案件,實現更聰明的做法。 資料物件也包含 Eleventy 所描述的「資料架構」,這包括從個別頁面提取的各種資料、從頁面使用的版面配置中提取資料,以及階層資料夾結構中的資料。

每個獨特的版面配置會描述不同類型的內容,且可以從其他版面配置繼承。在 web.dev,我們會使用這項功能以正確設定不同類型的內容 (例如貼文和程式碼研究室),同時分享一個頂層 HTML 版面配置。

集合

Eleventy 提供程式輔助方式,建構任意內容集合。這讓我們得以建構分頁支援功能,並為文章作者產生虛擬網頁 (磁碟上沒有相符的 Markdown 檔案的網頁)。 舉例來說,我們使用包含永久連結運算式 (以便每位作者重新轉譯範本) 和幕後集合的範本來建構作者頁面。

舉例來說,系統會顯示一個簡單的網頁,其中包含小艾的所有貼文

限制

目前我們無法輕鬆整合 Eleventy 的建構程序,因為這是宣告式,而非命令式:也就是描述您想要的方式,而非您想要的方式。 要在大型建構工具中執行 Eleventy 相當困難,因為只能透過其指令列介面叫用 Eleventy。

構思

web.dev 採用 Mozilla 最初開發的 Nunjucks 範本系統。Nunjucks 具備像是迴圈和條件式等典型的範本功能,但也可讓我們定義能產生進一步 HTML 或叫用其他邏輯的短碼

與多數建立靜態內容網站的團隊一樣,我們逐步從小規模開始,並陸續添加了短碼,目前為止約有 20 個。 這些方法大多只會產生進一步的 HTML (包括我們的自訂網頁元件)。範例如下:

{% Aside %}
See how Asides work in the web.dev codebase
{% endAside %}

最終看起來會像這樣:

但它實際建立的 HTML 如下:

<div class="aside color-state-info-text">
<p>See how Asides work in the web.dev codebase</p>
</div>

除了本文的討論範圍外,web.dev 仍使用短碼做為中繼程式設計語言的類型。 簡碼接受引數,而且其中一個引數是內含的內容。由於短碼不必傳回任何內容,因此可用於建立狀態或觸發其他行為。🤔💭

影片腳本

如前文所述,web.dev 是靜態網站,可在沒有 JavaScript 的情況下提供及使用該網站,且可在不支援 type="module" 或我們其他新型程式碼的舊版瀏覽器中使用。 在我們嘗試讓所有人都能存取 web.dev 的做法中,這一點非常重要。

但新世代瀏覽器的程式碼主要由兩個主要部分組成:

  1. 啟動程式碼,包含全域狀態、Analytics (分析) 和 SPA 轉送程式碼
  2. 網頁元件適用的程式碼和 CSS,可逐步強化網站

啟動載入程式碼相當簡單:web.dev 可將新網頁載入為單頁應用程式 (SPA),因此我們安裝一個全域事件監聽器,會監聽本機 <a href="..."> 元素的點擊。 SPA 模型可協助我們維持使用者目前工作階段的全域狀態,否則每次載入新頁面都會觸發呼叫 Firebase 來存取使用者登入狀態。

我們也會根據您點擊的網址,指定一些不同的進入點,並使用動態 import() 載入正確的進入點。 這樣可以減少使用者在使用程式碼強化網站前所需的位元組數量。

網頁元件

網頁元件是自訂元素,封裝 JavaScript 中提供的執行階段功能,以 <web-codelab> 等自訂名稱識別。這項設計非常適合大部分靜態網站 (例如 web.dev):在網站的 HTML 更新時,瀏覽器會管理元素的生命週期,正確地通知任何元素在附加或卸離網頁時。 反射瀏覽器則會完全忽略網頁元件,並轉譯 DOM 中的任何其餘內容。

每個 Web 元件都是一個包含 connectedCallback()disconnectedCallback()attributeChangedCallback() 等方法的類別。web.dev 的自訂元素大多繼承自 LitElement,後者提供複雜元件的簡易基礎。

雖然 web.dev 在許多網頁上都使用 Web 元件,但現在這個元件比「Measure」頁面更加重要。 這個頁面上顯示的功能主要取決於兩個元素:

<web-url-chooser-container></web-url-chooser-container>
<web-lighthouse-scores-container></web-lighthouse-scores-container>

這些元素可建立可提供更多功能的進一步元素。請注意,這些元素只是一般 Markdown 原始碼的一部分,我們的內容團隊可以為「任何」網頁新增擴充功能,而不只是 Measure 節點。

我們的網頁元件最常使用由 React 製作的容器元件模型,不過這個模型現已成為常態。 每個 -container 元素都會連接至我們的全域狀態 (由 unistore 提供),然後呈現視覺元素,接著系統會接著顯示具有樣式或其他內建功能的實際 DOM 節點。

這張圖表顯示全域狀態與使用全域狀態的 HTML 元素之間的關係。
全域狀態和網頁元件

我們最複雜的網頁元件可以透過視覺化的方式呈現全域動作和狀態。舉例來說,web.dev 可讓您稽核喜愛的網站,然後離開「評估」頁面。 如果返回,工作就會繼續進行。

我們的簡易元件只會強化其他靜態內容,或建立令人驚豔的視覺化內容 (例如,每個折線圖都是自己的 <web-sparkline-chart>),而這些元件與全域狀態沒有任何關聯。

歡迎洽詢

web.dev 工程團隊 (RobEwaMichaelSam) 將於近期內深入介紹,提供更多技術深入探討。

希望你能瞭解我們如何提供適合你專案的構想。如果對這個網誌有任何問題或主題要求,歡迎透過 Twitter 與我們聯繫!