1. 程式人生 > >前端進階筆記之核心基礎知識---那些HTML標籤你熟悉嗎?

前端進階筆記之核心基礎知識---那些HTML標籤你熟悉嗎?

[toc] 提到HTML標籤,我們會非常熟悉,開發中經常使用。但我們往往關注更多的是頁面渲染效果及互動邏輯,也就是對使用者可見可操作的部分,比如表單、選單欄、列表、圖文等。其實還有一些非常重要卻容易忽視的標籤,這些標籤大多數用在頁面頭部head標籤內,雖然對使用者不可見,但如果在某些場景下,比如互動實現、效能優化、搜尋優化,合理利用它們可以讓我們在開發中達到事半功倍的效果。
# 1、互動實現 在實現一個功能的時候,我們編寫的程式碼越多,不僅開發成本越高,而且程式碼的健壯性也越差。因此我們在開發中提倡**編碼簡約**原則:**Less code, less bug** ## 1.1 meta標籤:自動重新整理/跳轉 meta標籤妙用場景一:假如每隔一分鐘就需要重新整理頁面,這個時候就可以用到meta標籤: ```` ```` meta標籤妙用場景二:假如想讓某個頁面在對使用者展示一段時間後,然後跳轉到其他頁面去,也可用到meta標籤: ```` ```` 上面這行程式碼的意思是當前頁面展示5s之後,跳轉到page2.html頁面去。
## 1.2 title標籤:訊息提醒 B/S架構有很多優點,比如版本更新方便、跨平臺、跨終端,但在處理某些場景時,比如即時通訊時,會變得有點麻煩。 因為前後端通訊深度依賴HTTP協議,而HTTP協議採用“請求-響應”模式,這就決定了服務端也只能被動地傳送資料。一種低效的解決方案是客戶端通過輪詢機制獲取最新訊息(HTML5下可使用WebSocket協議)。 另外在HTML5標準釋出之前,瀏覽器沒有開放圖示閃爍、彈出系統訊息之類的介面,因此訊息提醒功能實現比較困難。但是我們可以通過修改title標籤來達到類似的效果(HTML5下可使用Web Notifications API彈出系統訊息)。 下面這段程式碼,通過定時修改title標籤內容,模擬了類似訊息提醒的閃爍效果: ```` let msgNum = 1 // 訊息條數 let cnt = 0 // 計數器 const inerval = setInterval(() =>
{ cnt = (cnt + 1) % 2 if(msgNum===0) { // 通過DOM修改title document.title += `聊天頁面` clearInterval(interval) return } const prefix = cnt % 2 ? `新訊息(${msgNum})` : '' document.title = `${prefix}聊天頁面` }, 1000) ```` 實現效果如下圖所示,可以看到title標籤名稱上有提示文字在閃爍。 ![](https://img2020.cnblogs.com/blog/454511/202006/454511-20200628181938941-534592308.gif) 通過模擬訊息閃爍,可以讓使用者在瀏覽其他頁面的時候,及時得知服務端返回的訊息。 通過定時修改title標籤內容,除了用來實現閃爍效果之外,還可以製作其他動畫效果,比如文字滾動,但需要注意瀏覽器會對title標籤文字進行去空格操作;還可以將一些關鍵資訊顯示到標籤上(比如下載時的進度、當前操作步驟),從而提升使用者體驗。
# 2、效能優化 效能優化是前端開發中避不開的問題,效能問題無外乎兩方面原因:**渲染速度慢**、**請求時間長**。效能優化雖然涉及很多複雜的原因和解決方案,但其實只要通過合理地使用標籤,就可以在一定程度上提升渲染速度,以及減少請求時間。 ## 2.1 script標籤:調整載入順序提升渲染速度 由於瀏覽器的底層執行機制,一般情況下,渲染引擎在解析HTML時從上往下執行,若遇到script標籤引用檔案,則會暫停解析過程,同時通知網路執行緒載入引用檔案。 檔案載入完成後,再切換至JavaScript引擎來執行對應程式碼,程式碼執行完成之後,再切換至渲染引擎繼續渲染頁面。 即預設情況下,載入HTML的過程主要有四個步驟: * 從上往下解析HTML; * 碰到script標籤引用檔案,暫停解析,同時通知網路執行緒載入引用檔案; * 檔案載入完成,切換至JavaScript引擎來執行對應程式碼; * 程式碼執行完成後,再切換至渲染頁面,繼續渲染HTML。 從這一過程可以看出,頁面渲染過程包含了請求檔案以及執行檔案的時間,但頁面的首次渲染可能並不依賴這些檔案。這些請求和執行檔案的動作反而延長了使用者看到頁面的時間,從而降低了使用者體驗。 為了減少這些時間損耗,可以藉助script標籤的三個屬性來實現: + async屬性:立即請求檔案,但不阻塞渲染引擎,而是檔案載入完成後,再阻塞渲染引擎並立即執行檔案內容。 + defer屬性:立即請求檔案,但不阻塞渲染引擎,等到解析完HTML之後再執行檔案內容。 + HTML5標準type屬性,對應值為“module”:讓瀏覽器按照ECMA Script6標準將檔案當作模組進行解析,預設阻塞效果同defer,也可以配合async在請求完成後立即執行。 通過對比,我們看出,設定defer和type="module"最推薦,都是在HTML渲染完成後才執行script引用的檔案程式碼。 效果圖比較見下面: ![](https://img2020.cnblogs.com/blog/454511/202006/454511-20200628190724525-1435104211.png) 另外注意,當渲染引擎解析HTML遇到script標籤引入檔案時,會立即進行一次渲染。 所以這也就是為什麼構建工具會把編譯好的引用JavaScript程式碼的script標籤放入到body標籤底部。因為當渲染引擎執行到body底部時,會先將已解析的內容渲染出來,然後再去請求相應的JavaScript檔案。 如果是內聯指令碼(即不通過src屬性引用外部指令碼檔案直接在HTML中編寫JavaScript程式碼的形式),渲染引擎則不會渲染,先執行指令碼程式碼再渲染頁面。 我們可以來做個試驗驗證下,第一個測試:在HTML頁面中間引用外部js檔案 ```` 引用js指令碼





古人學問無遺力,少壯工夫老始成;

紙上得來終覺淺,絕知此事要躬行。

```` 引用外部js指令碼test.js:````alert('男兒何不帶吳鉤,收取關山五十州');```` 效果圖: ![](https://img2020.cnblogs.com/blog/454511/202006/454511-20200628193758373-2013024466.png) 第二個測試:在HTML頁面中間內聯js指令碼 ```` 內聯js指令碼




古人學問無遺力,少壯工夫老始成;

紙上得來終覺淺,絕知此事要躬行。

```` 效果圖: ![](https://img2020.cnblogs.com/blog/454511/202006/454511-20200628193926314-106282860.png) ## 2.2 link標籤:通過預處理提升渲染速度 在大型單頁應用進行效能優化時,也許會用到按需賴載入的方式來載入對應的模組。但是如果能合理利用link標籤的rel屬性值來進行預載入,就能進一步提升渲染速度。 * **dns-prefetch**:當link標籤的rel屬性值為“dns-prefetch”時,瀏覽器會對某個域名預先進行dsn解析並快取。這樣,當瀏覽器在請求同域名資源的時候,能省去從域名查詢IP的過程,從而減少時間損耗。下圖是淘寶網設定的dns預解析。 ![](https://img2020.cnblogs.com/blog/454511/202006/454511-20200628200937299-716853539.png) * **preconnect**:讓瀏覽器在一個HTTP請求正式發給伺服器前預先執行一些操作,這包括dns解析、TLS協商、TCP握手,通過消除往返延遲來為使用者節省時間。 * **prefetch/preload**:兩個值都是讓瀏覽器預先下載並快取某個資源,但不同的是,prefetch可能會在瀏覽器忙時被忽略,而preload則是一定會被預先下載。 * **prerender**:瀏覽器不僅會載入資源,還會解析執行頁面,進行預渲染。 這幾個屬性值恰好反映了瀏覽器獲取檔案的過程,它們獲取檔案的流程: 1. 設定dns-prefetch, 然後判斷是否有對dns進行預解析。沒有則進行dns解析,有則執行下一步preconnect; 2. 執行preconnect, 對ddns、TLS、TCP進行預連線,然後判斷是否已經TCP連線。沒有則進行TCP連線,有則執行下一步prefetch/preload; 3. 執行prefetch/preload,載入資原始檔。然後判斷資原始檔是否已經預載入。沒有則進行http進行資源請求下載,有則進行下一步prerender; 4. 執行prerender, 預渲染頁面。然後判斷預渲染是否成功。沒有預渲染成功則進行渲染,預渲染成功則呈現給使用者看。 流程圖如下: ![](https://img2020.cnblogs.com/blog/454511/202006/454511-20200628202149247-1196497366.png) # 3、搜尋優化 我們寫的前端程式碼,除了要讓瀏覽器更好的執行,有時候也要考慮更方便其他程式(如搜尋引擎)理解。合理地使用meta標籤和link標籤,恰好能讓搜尋引擎更好的理解和收錄我們的頁面。 ## 3.1 meta標籤:提取關鍵資訊 通過meta標籤可以設定頁面的描述資訊,從而讓搜尋引擎更好的展示搜尋結果。 比如在百度中搜索“拉勾”,就會發現網站的描述,這些描述資訊就是通過meta標籤專門為搜尋引擎設定的,目的是方便使用者預覽搜尋到的結果。 為了讓搜尋引擎更好的識別頁面,除了描述資訊之外還可以使用關鍵字,這樣即使頁面其他地方沒有包含搜尋內容,也可以被搜尋到(當然搜尋引擎有自己的權重和演算法,如果濫用關鍵字是會被降權的,比如Google引擎會對堆砌大量相同關鍵詞的網頁進行懲罰,降低它被搜尋的權重)。 當我們搜尋關鍵字“垂直網際網路招聘”的時候搜尋結果會顯示拉勾網的資訊,雖然顯示的搜尋內容上並沒有看到“垂直網際網路招聘”字樣,實際上因為拉勾網頁面中設定了這個關鍵字。 對應程式碼如下: ```` ```` ## 3.2 link標籤:減少重複 有時候為了使用者訪問方便或者出於歷史原因,對於同一個頁面會有多個網址,又或者在某些重定向頁面,比如:https://xx.com/a.html、 https://xx.com/detail?id=abcd,那麼在這些頁面中可以設定:````````這樣可以讓搜尋引擎避免花費時間抓取重複網頁。不過需要注意的是,它還有個限制條件,那就是指向的網站不允許跨域。 當然,要合併網址還有其他的方式,比如使用站點地圖,或者在http請求響應頭部新增rel="canonical"。 ## 3.3 延伸內容:OGP(開放圖表協議) 前面說的是HTML5標準的一些標籤和屬性,下面再延伸說一說基於meta標籤擴充套件屬性值實現的第三方協議---OGP(open graph protocal, 開放圖表協議)。 OGP是Facebook公司在2010年提出的,目的是通過增加文件資訊來提升社交網頁在被分享時的預覽效果。你只需要在一些分享頁面中新增一些meta標籤及屬性,支援OGP協議的社交網站就會在解析頁面時生成豐富的預覽資訊,比如站點名稱、網頁作者、預覽圖片。具體預覽效果會因各個網站而有所變化。 下面是微信文章支援OGP協議的程式碼,可以看到通過meta標籤屬性值聲明瞭:標題、網址、預覽圖片、描述資訊、站點名稱、網頁型別和作者資訊。 ![](https://img2020.cnblogs.com/blog/454511/202006/454511-20200628210504232-152860553.png) # 總結 本篇從互動實現、效能優化、搜尋優化場景觸發,分別講解了meta標籤、title標籤、link標籤,一級script標籤在這些場景中的重要作用,希望這些內容你都能應用到工作場景中,不再只是瞭解,而是能夠熟練運用。 最後在思考一下:你還知道哪些“看不見”的標籤及用法?