AppWorks School Batch #16 Front-End Class 學習筆記&心得(駐點階段四:個人專案~Sprint 1)


Posted by ralphhong5465 on 2022-09-15

「個人自主專案」階段進入第一週,在全屆面前報告專案構想之後,緊接而來的是五個週期的短衝(sprint)。雖然專案的難度高低、進度快慢可以自己安排,但每階段進度的展示都將可能有校務人員加入,也會直接影響求職,壓力跟前數週比起來可謂有增無減。

取自 AppWorks School 前端班課程大綱

期中考檢討

上週六期中考的結果很快就出爐,School、導師與自己都可以藉此檢視自己的學習狀況。雖說考試本身會有分數,但我們不是在學校修課,沒有所謂「過」與「不過」、拿到什麼等第或排名的問題,成績的「數字」本身並不是重點,因此,導師沒有主動向每位同學公布結果,倒是花了一整天跟每個人來場各為時至少半小時的一對一談話。

對「人」的工作是最累的,就算是照表操課、每位同學都只聊半小時,導師還是要陸續跟所有同學一路聊到六點下班,但真正對談時也不可能像律師按表計時,因此實際結束時間幾乎已到晚上八點。我非常佩服導師可以如此有耐心,一一跟每位同學討論學習狀況,即便輪到最後幾位入場時已經過下班時間,也不會只想匆匆結束,依舊跟每位同學聊好聊滿,還送上超好吃的零食。

導師在一對一對談中送的小零食

個人專案-短衝一

如同跨班協作(Co-Work)階段開始前會先報告預計要做的內容,個人自主專案開始前也會向全屆進行簡單報告,各班導師們與校務也都在場,每人僅有三分鐘的時間。

打從去年接觸 HTML 開始,我就一直希望能夠做一個與芬蘭羅瓦涅米有關的網站,但自學時期的成長曲線緩慢,一直等不到開始動手執行的那一天。終於,在 AppWorks School 進度壓力的驅使下,生出了專案的使用者流程(user flow)與線框圖(wireframe),我也把握著為時三分鐘的報告時間,運用聲音表情講述專案發想流程,盡可能增添故事感,否則對於聽眾而言,要連續聽完 45 位同學的報告,也是件不輕鬆的事。

我的個人專案「Yolu 遊囉」提案簡報封面

適逢第 15 屆的最後一週,校長 Shirney 趕緊把握機會,以他們的經驗,向剛要進入個人專案階段的我們說明徵才廠商注重的面向,其中包含下列三點:

  1. 完整性:使用者流程應順暢,避免任何步驟走到一半出現瑕疵。
  2. 精緻度:不能像是完成指派的作業,而是代表個人能力的「作品」。
  3. 流暢度:展示時應避免修正錯誤或等待的尷尬時間。

School 也制定了每個短衝(sprint)的進度要求,先以最容易卡關的「核心功能」為要求重點,再處理使用者介面。有別於 STYLiSH 階段都是先把畫面刻出來再做功能,把難的部分往前放有助於我們提早發現問題、並有餘裕思考解決方案,而非花了大把時間把美美的畫面做出來後,卻發現原本主打的核心功能無法實現。

個人專案雖然不會有發 PR、給導師審閱的過程,School 依然建議我們仿 Git Flow 方式進行。除此之外,每個人也都各自建立屬於自己的 Trello 看板,上頭有專案目標(project vision)、使用者故事(user story)、專案整體積壓(backlog)、短衝積壓(sprint backlog)、進行中(in progress)、短衝已完成(sprint-complete)等項目,每天早上的晨會(recap)皆以檢視當期短衝進度為主。要同步管理 Git Flow 與專案各項目的進度,有種身兼產品專員與工程師的感覺。

我的個人專案 Trello 看板

週五主題短講:網路

在個人專案開始,每週五早上都會有為時一個半小時以內的主題短講(Friday Talk),所有班別都會同時參與,內容以電腦科學相關基礎觀念為主,許多都是面試經典問題,即將於本日畢業的第 15 屆也有一群人坐在一旁聆聽,而且還聽得超專心,可見這些觀念有多麼重要。

本週的主題是「網路」,而對應的經典面試問題就是:

當我們在瀏覽器輸入網址、按下 Enter後,發生了什麼事情?

如果 Google 搜尋這道問題,會發現這是工程師面試的超常見問題,網路上的答案也非常多,簡單整理如下:

  1. 瀏覽器在網域名稱系統(DNS)尋找對應的 IP 位置。
  2. 瀏覽器向伺服器傳送 HTTP 請求(HTTP request)。
  3. 伺服器向瀏覽器回傳 HTTP 回應(HTTP response)。
  4. 瀏覽器收到回應後,解析並渲染 HTML 頁面。

瀏覽器在 DNS 尋找網域名稱對應的 IP 位置

當我們在瀏覽器輸入網址(URL)時,輸入的是「網域名稱(domain name)」,例如 www.google.com.tw,其特色是人腦易於理解、但伺服器看不懂,伺服器可以理解的是 IP 位置。

什麼是 IP 位置(IP address)?

不知道大家在 2000 年代剛上小學電腦課時,有沒有用過一系列奇怪的數字連上特定網站?例如 74.125.31.99 可以連到 Google 首頁、74.6.231.20 可以連到 Yahoo 首頁,這串奇怪的數字就是「IP 位置」。

而要理解「IP 位置」這些數字怎麼來的,得先從電腦的「二進制(binary)」開始說起...

在電腦的世界裡,只有 0 跟 1 兩種數字,每一個數字都代表一個位元(bit),每八個位元代表一個位元組(byte),因此每個位元組都有 2⁸ = 256 種組合。為了避免過於冗長,IP 位置內的每個位元組會改用十進制(decimal)表示,每個位元組可能的數字包含 0~255。

IPv4 的 IP 位置範例

IPv4 時期,每個 IP 位置皆由四個位元組(byte)組成,因此一共可以有 2⁸⁺⁸⁺⁸⁺⁸=2³² 種組合,約莫是近 43 億,但全球人口數早就不只 43 億、加上每個人可能同時有不只一個裝置,這樣的數字遠遠不夠用,因此,1995 年推出的 IPv6 讓每個 IP 位置都有 16 個位元組,共有 2¹²⁸ = 3.4 * 10³⁸ 種組合,這是一個天文數字,就算地球上的每粒沙、每顆石頭都有一個 IP 位置也用不完。

IPv4 與 IPv6 比較範例(取自 Cloudflare

既然 URL 對於人腦較友善、但伺服器卻又只懂 IP 位置,因此,需要透過「網域名稱系統(DNS)」,將我們輸入的 URL 轉成 IP 位置,這個過程就叫做「域名解析」。

域名解析:DNS 把人腦易理解的 URL 轉換成伺服器能懂的 IP 位置。

在域名解析的過程中,DNS 會由瀏覽器緩存、系統緩存、路由器緩存、網路供應商(Internet Service Provider, ISP) DNS 緩存、根域名伺服器供應商逐層向上尋找,直到找到對應的 IP 位置為止。

瀏覽器向伺服器傳送 HTTP 請求(HTTP request)

伺服器向瀏覽器回傳 HTTP 回應(HTTP response)

「發送 HTTP 請求」和「回傳 HTTP 回應」兩步驟是整個流程的核心,可以一併探討。

找到 URL 對應的 IP 位置後,瀏覽器就準備向伺服器發送請求,但在此之前,還是有些前置作業要處理。

如果一臺電腦是用 Windows 系統、另一臺是用 Mac,那這兩臺電腦要如何溝通呢?這時候就需要先制定一個共同的標準,最常見的包含 OSI 與 TCP/IP 兩種模型。

  1. 開放式系統互聯(Open System Interconnection, OSI)模型

此模型將通信系統分為七層,發送端會將資料由上而下一層一層往下傳,每傳一層就封裝(encapsulate)一次;待接收端收到資料後,再一層一層往上傳,每傳一層都會解封裝,直到接收端的使用者拿到發送端最原始的資料為止。

OSI 模型概念圖,資料每往下一層就會多一層封裝

  1. 傳輸控制協定/網際網路協定(TCP/IP)模型

TCP/IP 可說是 OSI 模型的簡化版,將原本的七層濃縮為四層,並可大致與原本的 OSI 相對照。兩裝置間互相傳遞資料時,一樣是越下層有越多層封裝。

OSI 與 TCP/IP 模型比較

在 TCP/IP 模型中,每一層都有各自的協定,用來制定該層的標準,確保規模化使用之後,不同裝置間依然可以有效溝通。

TCP/IP 模型:簡化版 OSI 模型,將軟體通訊分為四層,每層有各自對應的協定。

應用層協定:HTTP

「應用層」最常見的協定為「超文本傳輸協定(hypertext transfer protocol, HTTP)」,而根據不同的目的,客戶端可發送不同的 HTTP 請求,這些請求種類稱為「HTTP方法(HTTP method)」,常見的如下:

  1. GET:拿資料。
  2. POST:寫入資料。
  3. DELETE:刪除資料。
  4. PUT:修改資料。
  5. PATCH:修改部分資料。

當伺服器端回傳回應時,則會帶有不同的「狀態碼(HTTP status code)」,用來表示回應的結果,常見的如下:

  1. 1XX:請求已被伺服器接受,待處理。
  2. 2XX:請求已被伺服器接受(200 代表「請求成功」)。
  3. 3XX:要重新導向,需要客戶端進一步操作才能完成請求。
  4. 4XX:客戶端錯誤(404 代表「請求對象未在伺服器找到」)。
  5. 5XX:伺服器端錯誤。

用更口語化的方式理解就是伺服器端在跟客戶端說:

  1. 1XX:請稍等。
  2. 2XX:東西來了。
  3. 3XX:你走錯了,請改道。
  4. 4XX:你搞砸了。
  5. 5XX:我搞砸了。
HTTP:應用層的協定,透過 HTTP 方法標準化請求動作、HTTP 狀態碼標準化回應結果。

傳輸層協定:TCP、UDP

到了「傳輸層」,顧名思義,關注的是「如何傳輸」,最常見的協定有「傳輸控制協定(Transmission Control Protocol, TCP)」與「使用者資料報協定(User Datagram Protocol, UDP)」兩種:

  1. TCP:在建立連線前,會經歷「三次握手(three‐way handshake)」,斷開連線前則會經歷「四次揮手(three‐way handshake)」,用來確認收發雙方都可以正常運作。
  2. UDP:直接把數據發出去,不管後續狀態。

由此可見,TCP 不管建立或斷開連線都會經過多重確認,較為可靠但效能較差、UDP 則是「射後不理」,效能佳但可靠性低。

TCP&UDP:傳輸層的協定;TCP 可靠但效能差、UDP 不可靠但效能佳。

TCP 的「三次握手」與「四次揮手」機制究竟有多嚴謹呢?我們可以分別用較口語化的方式理解。

三次握手

步驟一:客戶端向伺服器端說:「我要送資料囉」。

步驟二:伺服器端向客戶端說:「好,知道了」。

步驟三:客戶端向伺服器端說:「好,我知道你知道了」。

現在我們一一來看三個步驟分別具有什麼功能:

步驟一:伺服器端可確認(1)客戶端發送功能正常,否則他發不出訊息、(2)伺服器端接收功能正常,否則自己讀不到訊息。

步驟二:客戶端可確認(1)客戶端發送功能正常,否則自己的上一則訊息發不出去、(2)伺服器端接收功能正常,否則他收不到我發的上一則訊息、(3)伺服器端發送功能正常,否則對方發不出回覆確認的訊息、(4)客戶端接收功能正常,否則自己收不到回覆確認的訊息。

步驟三:伺服器端可確認(1)伺服器端發送功能正常,否則自己的上一則訊息發不出去、(2)客戶端讀取功能正常,否則他讀不到我發的上一則訊息。

總之,三個步驟可以用來讓客戶端與伺服器端都確認彼此的收發都正常,才會開始傳遞資料。

三次握手:TCP 建立連結前,讓客戶端與伺服器端確認彼此都能正常收發。

四次揮手

步驟一:客戶端向伺服器端說:「我要中斷連結了」。

步驟二:伺服器端向客戶端說:「好,知道了,但還有一些資料沒送完,請稍等」。

步驟三:伺服器端向客戶端說:「我把最後一筆資料送出去了」。

步驟四:客戶端向伺服器端說:「好,我收到最後一筆資料了,再見」。

與建立連結的三次揮手最大的不同是,伺服器端收到客戶端說要中斷連結的訊息時,可能還有資料還沒傳完,因此,客戶端會待收到伺服器端發送的最後一筆資料後,才跟伺服器說再見。

客戶端在說再見後,仍會等待一段時間,如果伺服器端沒有收到「再見」訊息,則可能再傳送新資料給客戶端,因此,客戶端會再次跟伺服器說「再見」,直到伺服器在等待時間內都不再回傳新資料為止。

四次揮手:TCP中斷連結前,讓伺服器端傳完最後一筆資料,客戶端再說「再見」。

通訊埠

不管是 TCP 還是 UDP,都需要另外提供「通訊埠/接口(port)」資訊,用來代表欲請求的項目。就好比某間銀行的 1 號櫃檯負責開戶、2 號櫃檯負責換匯、3 號櫃檯存提款、4 號櫃檯負責理財服務,當我們今天要去該銀行換錢時,除了需要知道銀行地址(IP 位置)外,還需要知道對應的櫃檯號碼(通訊埠),走對銀行也走對櫃檯,才可以得到想要的服務。

在一個伺服器中,可能有多個不同的通訊埠,各自有專責的處理項目,常見的如下:

  1. HTTP:80 埠。
  2. HTTPS:443 埠。
  3. SSH:22 埠。
通訊埠:在同一個 IP 位置對應的伺服器中,指向特定的服務項目。

HTTP 持久連接

HTTP 是一種以 TCP 為基礎的無狀態協定(stateless protocol),意即每次的請求與回應都與先前的毫無關聯,而在 HTTP 1.1 起,送請求之後並不會中斷連線,實現「持久連接(persistent connection)」,HTTP 可用同一個 TCP 連接來處理多個請求與回應,就不需要多次的「三次握手」與「四次握手」過程。

HTTP 持久連接:用同一個 TCP 連接處理多個 HTTP 請求與回應。

WebSocket

WebSocket 是另一種位於應用層的傳輸協議,與 HTTP 同樣基於 TCP,但最大的特色是在經歷一次的「三次握手」流程後,就可持續進行雙向溝通,常用來製作即時聊天室,如 Socket.IO 就是基於此協定的 JavaScript 函式庫。

WebSocket:應用層協定,可實現持續性雙向溝通。

瀏覽器收到回應後,解析並渲染 HTML 頁面

等到瀏覽器經過上述一系列流程,終於拿到伺服器提供的頁面資訊後,下一步就是要在畫面上渲染,而這個過程稱為「關鍵渲染路徑(critical rendering path, CRP)」。

關鍵渲染路徑(critical rendering path, CRP)流程圖

  1. 解析 HTML:將 HTML 中的標籤(tag)轉為一個一個標記(token),再將標記轉為節點(node)後組成「DOM tree」。DOM 的建構過程可以是逐步的,例如可以將 header 的 DOM 先建立完並顯示在畫面上、再建立 body 的 DOM,不必等所有內容都拿到後才呈現整個網頁的 DOM。
  2. 解析 CSS:過程與解析 HTML 相似,將 CSS 字符轉為一個一個標記(token),再將標記轉為節點(node)後組成「CSSOM tree」。比較特別的是,CSS 為「鎖定渲染(render blocking)」資源,代表所有 CSS 檔案都要拿到才會載入,與可逐步建構的 HTML DOM 不同;此外,CSS 也是「script blocking」,沒有先把 CSS 全部載完的話,被包含在 <script> 標籤裡的 JavaScript 檔案無法執行。
  3. 執行 JavaScript:鎖定轉譯 JavaScript 檔案,由於轉譯完成前都不會處理後面的 HTML ,因此一般會將帶有 JavaScript 檔案的 <script> 標籤放在最後。
  4. 渲染樹(render tree):結合 HTML DOM 與 CSSOM,產生樹狀結構。在 HTML head 裡面的內容、設定為 display:none 等不會佔據空間的節點都不會出現在此樹狀結構,但設為 visibility:hiddenopacity:0 者,因仍會在畫面中佔空間,因此仍被包含在樹狀結構中。
  5. 布局/排版(layout):又可稱為「回流(reflow)」,即根據渲染樹的節點建構基本排版,主要計算節點位置與大小,類似畫畫時,先繪製基本構圖。更改螢幕方向、調整視窗大小等事件都會造成重新布局,因此這個步驟非常吃效能。
  6. 繪製(paint):決定繪製順序,由於不同的節點可能在同樣位置,僅有 z-index 的上下層之分,此程序可以確保下層的圖層不會蓋住上層圖層,圖層的概念與 Adobe Illustrator 等繪圖軟體類似。若改變背景或元素顏色,則會發生「重新繪製(repaint)」,但跟上個步驟的「回流(reflow)」比起來,較不吃效能。
  7. 組合(compositing):決定好架構之後,終於要開始畫圖了!把前面步驟整理好的資訊轉成像素呈現在畫面上的過程,稱為「刪格化(rastering)」。早期 Chrome 瀏覽器僅在視窗可見範圍進行刪格化,但這樣會造成頁面滾動時,新出現的可見範圍還沒畫好,因此,現在改用「組合(compositing)」的概念,把畫面拆成一層一層進行刪格化,這樣視窗不管怎麼移,每個部分都已經畫好,就算有動畫,也因分層繪製,動畫層不會影響到其他層。

心得

我的期中考表現並不是非常理想,如果有算分大概是準備停修或被當的那種,題目不是寫不出來,而是該掌握的技能還沒有爐火純青,會花比預期多的時間處理,而這也是我要把握個人專案期間、甚至是在 School 畢業後要補強的。因為面試也會有時間壓力,要能夠在狀態不佳時還能發揮到 100 分,那本身就要有至少 120 分的實力。

學習困境 & 步調調整

因為過去摸新技術的時間都比想像中久一些,我在個人專案的難度安排上偏保守,多數都是已經操作過、但仍不熟的基礎技術,也安插了一些沒有摸過的新功能,例如 Google Map API、使用 Firebase 處理會員註冊與登入、登出等,兩者的文件都頗為詳細,且學習資源不少,就算完全沒有碰過,以目前的能力而言,理應不至於無法實現。

打從 STYLiSH 專案開始,我就覺得自己並沒有很紮實得學會各項新技術。過去的我仰賴打學習筆記驗證,但駐點開始後進度緊湊,我不再有大把時間慢慢消化學習內容,導致很多東西都只停留在「有印象」階段,因此,在有機會自己安排進度的個人專案環節,我的重點著重在「把不會的東西補起來」,待到時候要展示時,寧願功能簡單一點、技術少一點但能完整說明,也不要用很多看起來很炫、但自己也沒很懂的東西,「完整性」遠比「花俏」來得重要許多。

實作外,也要讀理論

看到一票第 15 屆的學長姐們在畢業當天還跑來聽早上的主題短講,再看到講師與他們互動的過程,深深感受到剛經歷面試的他們,有多重視這些看似無聊的理論。

本次短衝的進度有幸提早完成,我得以花一整天的時間慢慢複習當天上課的內容,把先前一直聽到、但始終沒有搞懂的多個網路觀念如 DNS、TCP/IP、TCP、UDP、WebSocket、CRP 等徹底研讀一次,過程中也查詢了不少文章與教學影片,而這當中最讓我印象深刻的,莫過於 Huli 在 Medium 撰寫的《從傳紙條輕鬆學習基本網路概念》。文章從傳紙條告白的故事開始,透過非常生活化的方式,一一帶出 IP、TCP、HTTP、通訊埠、UDP、還有 TCP/IP 模型中的網路分層概念,讓人看了不僅印象深刻、還不時會心一笑。

後面每週也都會有新的主題短講,期許自己都能把握週末時間好好複習,否則空有個人作品、但是面試時基礎觀念一問三不知,還是非常吃虧,我可不希望自己在面試後,才發現原本應該會的觀念沒有弄熟。

送往、待迎來

第 15 屆的畢業典禮在週五舉行,我們就像就讀小五/國二/高二的在校生(當然是沒有人去致詞),看著上一屆學長姐歡樂地畢業、而我們卻是在趕個人專案,還離開了曾經創造許多回憶的 Microsoft 會議室,改到校務辦公層的 Adobe 會議室進行後續每天的晨會等班級活動。在與某位第 15 屆學長的對談過程中,我發現過往都是一屆畢業後才迎接下一屆,今年年初搬到福記大樓後,因為場地夠大,才可以同時容納兩屆的人,因此,我們是第一屆與前一屆同時駐點集訓、也將會是第二屆與下一屆同時上課的屆別,得以觀察學長姐的進度、也會被下一屆觀察。雖然 School 本身沒有安排跨屆交流活動,但在同一段時間待在同一個空間,如果夠主動,還是比以往有機會認識更多跨屆別的人。

兩週後,第 17 屆的駐點集訓即將開始,我不禁好奇,自己能成為他們的好榜樣嗎?然而多想無益,還是好好把握時間,努力處理個人專案比較實際!

參考資料

  1. 從傳紙條輕鬆學習基本網路概念(大推!)
  2. 瀏覽器輸入網址後,按下 ENTER,背後發生什麼事情?
  3. [熱門面試題] 從輸入網址列到渲染畫面,過程經歷了什麼事?
  4. [30 天學會 Web 前端效能優化] 2. 傳輸層簡述
  5. 一条视频讲清楚TCP协议与UDP协议-什么是三次握手与四次挥手?
  6. 【筆記】Socket,Websocket,Socket.io的差異
  7. 30–10之通訊協議的基本常識
  8. 【Web】瀏覽器如何繪製網頁?探討 DOM、CSSOM 與渲染(翻譯)
  9. 增進效能從了解瀏覽器開始 — 關鍵渲染路徑
  10. JS 原力覺醒 Day25 — CRP : 關鍵渲染路徑
  11. Website Performance Optimization (Udacity)

#AppWorks School









Related Posts

Day 1 Markdown & Minimal Table

Day 1 Markdown & Minimal Table

Heroku 部署

Heroku 部署

JavaScript 程式執行原理:Event Loop

JavaScript 程式執行原理:Event Loop


Comments