web.dev בלוג הנדסה מס' 1: כיצד אנחנו בונים את האתר ומשתמשים ברכיבי אינטרנט

זהו הפוסט הראשון בבלוג ההנדסה של web.dev. במהלך החודשים הקרובים, אנחנו מקווים לשתף תובנות פרקטיות מהעבודה שלנו – לכן כדאי לעקוב אחרי פוסטים עם התג של בלוג הנדסה! כאן נסביר על תהליך ה-build עבור האתר הסטטי שלנו (אופציונלי!) JavaScript מאחורי רכיבי האינטרנט שלנו.

web.dev מספק תוכן לגבי בניית חוויות אינטרנט מודרניות ומאפשר לכם למדוד את ביצועי האתר. יכול להיות שמשתמשים מנוסים הבינו שדף המדידה שלנו הוא רק ממשק של Lighthouse, שזמין גם בכלי הפיתוח של Chrome. כניסה ל-web.dev מאפשרת לכם להפעיל ביקורות Lighthouse באופן קבוע באתר שלכם, כדי לראות איך הציון שלו משתנה לאורך זמן. אבדוק שוב את הדף'מדידה' מאוחר יותר, כי אנחנו חושבים שהוא די מיוחד. 🎊

מבוא

בעיקרון, web.dev הוא אתר סטטי שנוצר מאוסף של קובצי Markdown. בחרנו להשתמש ב-Eleventy כי הוא כלי מלוטש שניתן להרחבה, שבעזרתו קל להפוך את Markdown ל-HTML.

אנחנו גם משתמשים בחבילות JavaScript מודרניות שאנחנו מציגים רק לדפדפנים שתומכים ב-type="module", כולל async ו-await. אנחנו גם שמחים להשתמש בתכונות הנתמכות על ידי דפדפנים לטווח ארוך, אבל לא על ידי מיעוט בגרסאות הישנות. מכיוון שאנחנו אתר סטטי, JavaScript פשוט לא נדרש כדי לקרוא את התוכן שלנו.

לאחר שתהליך ה-build - שכולל יצירת 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 אנחנו משתמשים בתכונה הזו כדי למסגר בצורה נכונה סוגים שונים של תוכן (כמו פוסטים ו-Codelabs) ועדיין משתפים פריסת HTML אחת ברמה העליונה.

אוספים

Eleventy מספקת דרך פרוגרמטית לבניית אוספים שרירותיים של תוכן. כך אנחנו יכולים לתמוך בעימוד וליצור דפים וירטואליים (דפים שאין להם קובץ Markdown תואם בדיסק) עבור כותבי פוסטים. לדוגמה, אנחנו בונים את דפי המחברים באמצעות תבנית שמכילה ביטוי לקישור הקבוע שלו (כך שהתבנית תעובד מחדש עבור כל מחבר) ואוסף גיבוי.

התוצאה היא, למשל, דף פשוט שמכיל את כל הפוסטים של אדי!

מגבלות

כרגע אנחנו לא יכולים להתחיל בקלות את תהליך ה-build של Eleventy כי הוא הצהרתי ולא חובה: צריך לתאר את מה שרוצים ולא איך שרוצים. קשה להריץ את Eleventy כחלק מכלי build גדול יותר, כי ניתן להפעיל אותו רק דרך ממשק שורת הפקודה (CLI).

יצירת תבניות

web.dev משתמש במערכת התבניות של Nunjucks שפותחה במקור על ידי Mozilla. ב-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.

כל רכיב אינטרנט הוא מחלקה עם שיטות כולל connectedCallback(), disconnectedCallback() ו-attributeChangedCallback(). הרכיבים המותאמים אישית של web.dev יורשים בעיקר מ-LitElement, שמספק בסיס פשוט לרכיבים מורכבים.

האתר web.dev משתמש ברכיבי אינטרנט בדפים רבים, אבל אין מקום שבו הדבר נדרש יותר מאשר בדף מדידה. שני אלמנטים מספקים את רוב הפונקציונליות שמופיעה בדף הזה:

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

הרכיבים האלה יוצרים רכיבים נוספים שמספקים יותר פונקציונליות. חשוב לציין שהרכיבים האלה הם רק חלק מקוד המקור הרגיל שלנו ב-Markdown - וצוות התוכן שלנו יכול להוסיף פונקציונליות מורחבת לכל דף, לא רק לצומת המדידה.

בדרך כלל, רכיבי האינטרנט משתמשים במודל רכיב הקונטיינר, שהפך לפופולרי על ידי React, אבל המודל הזה הוא עכשיו קצת "passé". כל רכיב -container מתחבר למצב הגלובלי שלנו (שמסופק על ידי unistore), ולאחר מכן יוצר רכיב חזותי, שממשיך לעבד צומתי DOM אמיתיים בעלי סגנון או פונקציונליות מובנית אחרת.

דיאגרמה שמציגה את הקשר בין המצב הגלובלי לרכיבי HTML שמשתמשים בו.
מצב גלובלי ורכיב אינטרנט

רכיבי האינטרנט המורכבים ביותר קיימים כדי להציג פעולות ומצבים גלובליים. לדוגמה, web.dev מאפשר לכם לבדוק את האתר המועדף עליכם ולאחר מכן לנווט אל מחוץ לדף 'מדידה'. כשתחזרו תראו שהמשימה עדיין מתבצעת.

הרכיבים הפשוטים שלנו רק משפרים תוכן סטטי מבחינה אחרת או יוצרים רכיבים חזותיים מדהימים (לדוגמה, כל תרשים קו הוא <web-sparkline-chart> בפני עצמו), שאין לו קשר למצב הגלובלי.

קדימה, לצ'אט

צוות המהנדסים של web.dev (רוב, איווה, מייקל וסאם) יבצע בקרוב ניתוחים מעמיקים נוספים.

אנחנו מקווים ששמענו על מה שאנחנו עושים נתנו לכם כמה רעיונות לפרויקטים משלכם. אפשר לפנות אלינו ב-Twitter אם יש לך שאלות או בקשות להוספת נושא לבלוג הזה!