簡介
有時候需要向新同學科普前端,又不知道如何下手?先把這篇圖文分享丟給他吧!
本文改編自魔法哥為 “百姓網暑期實習生訓練營” 所作的前端入門講座。此講座面向在校大學生,內容比較初級,高手請飄過~
大家好,今天的分享主要分為以下三個部分。
由於目前計算機專業還沒有為 Web 前端技術設立專門的課程,每位同學對前端的瞭解程度也不一樣,今天的講座會以最淺顯的方式來為大家介紹 “前端”,幫助大家建立一個基本的概念。
前端是什麼?
在回答這個問題之前,我想到了一道面試題:
當我們在瀏覽器中輸入網址並按回車之後,接下來會發生什麼?
我們來簡單地看一看 “網頁展現” 的整個過程。
比如這裡有一個使用者,它需要訪問 abc.com
這個網址。一般來說,當使用者輸入一個域名時,是在請求一個 HTML 資源。當他完成域名解析之後,他的瀏覽器會向 abc.com
這個域名所指向的 Web 伺服器發出請求。
有時候 Web 伺服器直接就可以返回使用者的請求了;有時候 Web 伺服器還需要向資料庫查詢一些資料,然後才能把處理結果返回給使用者。
當使用者的瀏覽器拿到伺服器返回的 HTML 資源之後,就開始解析並顯示 HTML 的內容了。
一般來說,HTML 頁面需要 CSS 資源來描述頁面的樣式。比如瀏覽器在解析 HTML 時發現了一個 CSS 外鏈 abc.com/a.css
,它就會去請求這個資源。
HTML 頁面往往還需要載入外部的 JS 資源,比如 abc.com/a.js
,此時瀏覽器同樣會向伺服器請求這個資源。
當所需的資源都載入完成之後,這個頁面就可以提供完整的外觀和功能了。整個過程差不多就是這個樣子了。
我們看一看這張流程圖,可以在中間畫一道豎線,把它分成左右兩個部分。
我們會發現,這道線左側的事情發生在瀏覽器端,我們稱之為 “前端”;右側的事情發生在伺服器端,稱為 “後端”。(“前端” 之所以叫 “前端”,是因為它離使用者更近一些。)
大家都學過後端開發的相關課程,對後端這一塊應該都比較熟悉了。那問題來了:在上面這個過程中,後端有哪些侷限?
伺服器一旦把資源提供給瀏覽器之後,便失去對內容的影響。
伺服器無法得知使用者在瀏覽器裡做了什麼,無法與使用者互動。
這意味著,只有當使用者下一次向伺服器請求資源時,伺服器才有機會再次決定使用者看到的內容。那麼,使用者什麼時候再向後端請求資源呢?
第一種情況是 “導航動作”。比如使用者重新整理頁面、點選連結、點選瀏覽器的前進/後退等等。
第二種情況是使用者提交表單。表單是最傳統的頁面互動方式之一,提交表單時瀏覽器會向伺服器發出新請求——這意味著瀏覽器會跳轉到一個新的地址,伺服器會在新頁面中顯示錶單的處理結果。
還有一種特殊情況,就是伺服器在給瀏覽器返回 HTML 資源時,在頁面中插入一個特殊的標記,瀏覽器看到這個標記就會在一定的時間後自動重新整理當前頁面或跳轉到其它頁面,相當於伺服器強制使用者再次發出請求。可想而知,這種非使用者意願驅動的頁面跳轉行為並不討人喜歡,因此已經不常用了。
在傳統網頁中,上述幾種使用者與伺服器之間的互動方式也算夠用了。不過隨著網頁形態的不斷演進,使用者對網頁體驗提出了更高的要求,很多時候網頁不僅僅是一篇靜止的文件,而更像是一個應用程式,使用者隨時可能與之互動。這個時候,前端的價值就體現出來了。
使用者從停留在當前頁面到發起新請求的這段時間內,前端可以控制頁面內容。
當使用者停留在當前頁面時,前端有能力與使用者互動。由於前端的 JS 可以監聽使用者在瀏覽器中的各種行為(比如滑鼠點選、鍵盤輸入、滾動頁面等等),前端就可以針對這些行為作出相應的反饋。
在前端與使用者的互動過程中,有些事情光靠前端就可以做出響應。比如我們在網頁上做了一個計算器的功能,當使用者輸入算式之後,JS 就可以直接計算出結果並顯示給使用者。整個過程不需要伺服器的參與就可以完成。
但有些事情,光有前端是無法完成的。此時前端就需要交給後端來處理,拿到處理結果之後再交給使用者。在這個過程中,前端可以讓使用者一直停留在當前頁面,互動過程具有良好的連續性。
那麼,前端如何把任務交給後端並拿到後端處理的結果呢?主要有兩種方式:Ajax 和 Socket 連線。
Ajax 是最常見的前後端互動方式。它以 “請求→響應” 的方式來完成前後端的資訊傳遞。傳統的表單互動需求幾乎都可以由 Ajax 改造為 “原地提交併獲取反饋” 的互動方式,不需要跳轉頁面,從而有效提升使用者體驗。
而對於實時性比較高的場景,Socket 連線就是一個更好的選擇。它的工作方式是前後端建立一個持續的連線,資訊可以隨時由前端發向後端,或由後端推送到前端。如果我們要建立一個實時對話的應用,通常就會用到 Socket 連線了。
前端需要用到哪些技術?
說到前端技術,我們通常都會說到 “三大塊”:
- HTML
- CSS
- JS
這是前端最核心的三項技術。
接下來,我們就會說到 “前端的分層架構”。這個架構的原則就是 “讓合適的技術去做合適的事情”。一個網頁從邏輯上可以視為這三層的有機結合體:
結構層:這一層的作用是表述一個頁面中有哪些資訊,以及這些資訊之間的關係是什麼。這一層在技術上是由 HTML 來實現的。
表現層:這一層決定了頁面中的資訊會以什麼樣的外觀呈現出來。這一層由 CSS 來實現。
行為層:這一層控制了頁面如何與使用者進行互動。在傳統的展示型網頁中,可能只需要 “結構層” 和 “表現層” 就足以提供完整的功能;而現代網頁承載了越來越多的互動,這就推動 “行為層” 的能力不斷增強。這一層由 JS 來實現。
我們通過一個例項來理解這個分層架構。
比如我是一個百姓網的使用者,我開啟了 “使用者中心” 中的 “我釋出的資訊” 這個頁面。
這個頁面的 HTML 描述了資訊以及資訊的結構。即使沒有 CSS 和 JS 的輔助,這個頁面仍然可以呈現出可理解的內容(參見上圖)。頁面頂部是一些導航元素,接下來的 “顯示中的資訊” 是一個標題,它又引出了一個列表。這個列表自然就是我在百姓網釋出的所有資訊了。(除了 “顯示中的資訊” 以外,頁面後半段還有 “已刪除的資訊”,這裡不再贅述。)
接下來,我們會在表現層下功夫,通過 CSS 來為頁面中的各個元素設定外觀。經過這一層的修飾之後,頁面中的內容更加美觀了;更重要的是,各元素的功能職責也更加直觀易懂了(參見上圖)。
這已經是一個挺不錯的網頁了,但接下來,我們還會通過 JS 來豐富它的功能,提升使用者的使用效率。
作為資訊的釋出者,我可能需要修改某條資訊的內容,或對它進行 “重新整理” 之類的操作。在傳統的互動中,我需要在這個列表中點選需要操作的資訊,然後在資訊的詳情頁選擇合適的操作。
我們可以把這個流程簡化一下:我們在這個列表中為每條資訊新增一個操作按鈕,當使用者點選某條資訊的操作按鈕時,我們就在頁面中彈出一個操作皮膚,使用者可以直接選擇想要的操作,減少了中間環節(參見上圖)。
由此可見,結構層、表現層、行為層這三者各有所長,共同構造了一個功能完備、體驗良好的網頁出來。
除了基本的 “三大塊” 之外,作為前端工程師,我們還需要掌握以下知識和技能:
HTTP 相關:由於前端資源都是瀏覽器通過網路下載的,因此我們有必要了解相關的網路協議。
瀏覽器相關:前端程式碼執行在瀏覽器中,我們需要了解瀏覽器的各種特性,以及瀏覽器向我們提供的各種介面。
前端效能優化:讓網頁更快,減少使用者的等待,這也是前端工程師面臨的重要課題。優化網頁的前端效能,需要我們具備上面兩項知識,並且掌握效能優化相關的工具和方法。
圖形影像:網頁資訊不僅包含文字,還包含圖片、視訊等多媒體資訊。圖片作為最常用媒體資源,需要我們掌握與其相關的技能。比如瞭解各種圖片格式適用的場景、基本的圖片處理方法等等。
(在講座中設立了一個 demo 環節,我會現場演示如何從零開始建立一個簡單的網頁,並實踐 “前端的分層架構” 這一指導思想。)
前端的開發方式是怎樣的?
前面我們已經介紹了前端技術 “三大塊”,然而在如今,當我們在編寫這三塊的程式碼時,已經不再 “裸寫” 了。這意味著我們在開發階段編寫的程式碼與實際在瀏覽器環境中執行的程式碼已經不一樣了,詳細來說:
- 我們通過模板語言來生成 HTML。
- 通過 CSS 前處理器來生成 CSS 程式碼。
- 通過 ES6+ 的語法和特性來編寫 JS 程式碼。
舉例來看吧,以下三個例子展示了程式碼書寫方式的演化。
百姓網採用了 Jade 和 Jedi 這兩種模板語言。在上圖的程式碼中,我們僅僅使用了模板語言最基本的標記語法,還沒有插入使用模板語言的任何邏輯能力。僅此一步,就可以看出模板語言帶來的好處。
原先我們在寫 HTML 程式碼時,會花費大量的精力在 <
、/
、>
這樣的語法噪音上;同時,識別標籤的巢狀關係也很費眼。幸運的是,Jade 和 Jedi 這樣的現代模板語言把前端工程師解放了出來。它們通過縮排來表達巢狀關係,層級關係一目瞭然;語法更精練,表現力更強。
在 CSS 方面,前處理器一方面通過更簡潔的語法減輕開發者的書寫負擔,另一方面通過內建的邏輯能力增強了程式碼的表現力。舉個例子,在使用原生 CSS 來寫程式碼時,不同元素採用的相同顏色只能分散在程式碼各處;而採用了 CSS 前處理器之後,我們可以把相同意義的顏色通過變數的形式抽象出來,然後在程式碼各處呼叫即可。這樣不僅便於後期維護,在平時讀程式碼時也更容易理解程式碼意圖。
在 JS 方面,我們開始享受 ES6+ 帶來的新特徵福利。ES(ECMAScript)是定義 JS 這門語言的標準規範,從第六版開始,ES 以每年一版的節奏持續快速地擴充套件著 JS 語言的能力。
在以往,如果我們要實現 “在陣列中找出符合特定條件的成員” 的需求,往往需要藉助 Underscore 這樣的工具庫,呼叫它的 _.find()
方法。而在 ES6 中,語言本身就擴充套件了陣列的能力,我們只需要直接呼叫 Array#find()
介面即可。另外,像箭頭函式這樣的新語法也可以令程式碼進一步簡化。
在 HTML、CSS、JS 這三大塊,我們放棄 “裸寫”,採用 “更高階” 語言的目的在於:
利用高階語言提供的 “邏輯能力” 來增強程式碼的表現力。
利用高階語言的 “語法糖” 和 “新特性” 來提升開發效率和舒適度。
當然,採用這些更高階的語言也不是完全沒有成本的。我們在開發階段所用的語言已經不是純粹的 HTML、CSS、JS 了,瀏覽器無法直接識別和執行。因此,當我們放棄 “裸寫”,也就意味著:
在部署流程中需要設立構建環節,把原始碼編譯到瀏覽器環境可以執行的目的碼。
在開發階段,需要有工具來實時監視並編譯有變動的原始碼,以確保頁面上呈現的是我們修改過的最新效果。
在百姓網,前端架構組已經搭建好了必要的開發環境,開發者們只需要關注開發本身就可以了。
在企業級的前端開發中,我們還需要了解如下知識點:
模組化:模組化是最常見的程式設計實踐之一,令我們的程式碼組織更加清晰、易維護。ES6 為 JS 增加了完善的模組化方案,我們的日常開發也已經遷移到了 ES6 模組規範之下。
包管理:如何將開源社群中的優秀元件為我所用?這就不能不提 “npm” 這個最主流的 JS 包管理器。前端界優秀的開源專案幾乎都發布到了 npm 的包倉庫,我們日常開發中用到的第三方庫也都是由 npm 來管理的。
打包工具可以把我們寫的模組化的原始碼和第三方包整合到一起,形成頁面所需的完整 JS 資源。“包管理器”、“模組化”、“打包工具” 的相互結合,基本上就是日常的 JS 程式碼組織方式。
元件化:在傳統的前端開發中,HTML、CSS、JS 這三塊的程式碼有各自獨立的檔案,這些檔案往往也分散在不同的目錄結構中。
如果頁面功能區塊的劃分足夠清晰,開發者就可以用 “元件” 的概念來把頁面拆分,整個頁面會被視為多個元件的巢狀和組合;同時,開發者也傾向於把每個元件相關的 HTML、CSS、JS 程式碼整合到同一個目錄(或同一個檔案)中,便於管理和維護。
這就是 “元件化” 的開發模式。要實現這樣的開發模式,通常需要前端框架和構建工具的配合。
單頁應用:HTML5 的 History API 為前端提供了控制瀏覽器導航行為的能力,配合 Ajax 無重新整理更新頁面內容的特性,我們可以在一個頁面內實現應用的多檢視切換,避免頁面的頻繁跳轉,提供類似桌面應用的體驗。比如 Gmail 等產品就是典型的單頁應用模式,百姓網的大多數後臺系統也都是單頁應用。
其它實用的知識點,就留待大家在工作中慢慢發掘吧。
今天想跟大家分享的主要內容就是這些了,感謝閱讀,再見!
作者:CSS魔法@前端架構
簡介:百姓網前端架構 TL,《CSS 揭祕》譯者,CSS Conf 講師,自稱 “披著工程師外衣的設計師”。本文僅為作者個人觀點,不代表百姓網立場。
題圖作者:lakexyde @ Pixabay
本文在 “百姓網技術團隊” 微信公眾號首發,掃碼立即訂閱: