雜記 › 技術筆記 › HTML 擠成一行沒法讀?美化和壓縮各在什麼時候用

HTML 擠成一行沒法讀?美化和壓縮各在什麼時候用

今年三月我接手過一個同事留下的郵件範本。檔案是建置產物,整個 body 裡幾萬個字元全擠在一行,編輯器裡要橫向捲四十多屏才能看到一個閉合標籤。我要改的東西很小:某個 div 上的一個 class 名。結果找了將近二十分鐘,中間還誤刪過一段被吞進同一行的註解。那天之後我給自己定了條規矩——拿到壓縮過的原始碼,第一件事不是讀,是先把它攤開;而反過來,要上線的頁面我捨不得把結構縮排留著不動。

美化和壓縮不是同一個動作的兩面

很多人把這兩個方向理解成「加換行」和「刪換行」,好像來回做就能回到原樣。實際上只有單向是可逆的:美化在標籤嵌套關係上重新插入換行和縮排,壓縮把所有空白和換行刪掉。壓縮後的檔案裡沒有留下「原本在哪裡換行、原來縮排幾個空格」這些資訊,你再美化一次,得到的是工具按嵌套層級重新排的版本,而不是原作者手寫的那份。

這件事在版本控制裡很要命。假設倉庫裡存的是壓縮版,某次你把它攤開提交,diff 會把整份檔案當成「一行刪除、幾百行新增」,誰也無法審。更常見的是另一種:前一個人用 2 空格,你用 4 空格重新格式化一遍再提交,於是每一行都被標記成改動,真正那兩行改了什麼完全被淹沒。我做過的處理是——倉庫裡統一儲存一種形態(多數時候是美化版),壓縮只發生在建置產物裡,不進倉庫;並且格式化時先選定縮排寬度,之後不隨意切換。

<div class="wrap"><p>第一段</p><p>第二段</p><ul><li>條目</li></ul></div>

攤開以後是下面這樣。我關心的是層級一眼能看出來,閉合標籤和開標籤在同一個縮排深度:

<div class="wrap">
  <p>第一段</p>
  <p>第二段</p>
  <ul>
    <li>條目</li>
  </ul>
</div>

2 空格、4 空格還是 Tab,我的選擇依據

用 HTML 美化壓縮 時可以先選縮排方式,三個選項是 2 空格、4 空格、Tab。這個選擇本身沒有優劣,只有「和別人一致」的價值。我一般按嵌套深度來估:如果頁面結構經常到第四第五層,2 空格在窄編輯器裡不會把程式碼擠到螢幕右邊,4 空格則看得更清楚。定下來之後有個可核對的規律——同一段結構換縮排寬度,每層的字元數是可以算的。

標籤嵌套層級2 空格縮排的前導空格數4 空格縮排的前導空格數Tab 縮排
第 1 層000 個
第 2 層241 個
第 3 層482 個
第 4 層6123 個
第 5 層8164 個

之所以我會專門去數這個:一旦從 2 空格切到 4 空格,第 5 層的行前面就多了 8 個空格,那一行的內容變了,diff 必然認為它被改過。反過來,如果兩個人一個用 Tab 一個用空格,同一個檔案在兩種編輯器設定下看起來「錯位」,其實是顯示寬度不同,不是程式碼不同。

壓縮刪掉的那些空白,有一部分是渲染要用的

HTML 解析時會把原始碼裡連續的空白和換行摺疊成一個空格。所以平時標籤之間換行、縮排,頁面上看不出差別,這是美化的安全邊界。但一旦涉及行內元素,那個被摺疊出來的空格就存在了:兩個用空格分隔的行內區塊之間,原始碼裡換成回車,渲染出來通常仍然留著一個空格的寬度;靠把字級設成 0 來消掉間隙的寫法,一旦空白處理發生變化,間距就跟著變。

更直接的是 pre 和 textarea 這類內容:裡面的換行和空格本身就是要顯示的東西,不能當成「格式雜訊」刪掉。HTML 美化壓縮 的壓縮模式對 pre、textarea 這類標籤的內容是保留的,我自己壓完也還是會 grep 一遍這兩處,確認程式碼範例、簽名框沒被壓平。

郵件範本是我最不願意隨手格式化的地方

回到開頭那份範本。郵件的 HTML 和網頁不是一套脾氣:各家郵件用戶端對空白的處理不一致,行內元素之間的換行在某些用戶端會真的變成一個空格寬度;表格儲存格 display 設成行內區塊來排版時,原始碼裡加個換行就可能把版面頂歪。所以我處理郵件範本的順序是:先看是否需要攤開閱讀,攤開只在「要讀懂結構」那一步用,改完再壓回去提交;如果這個檔案本身是要上線的範本,我不會把美化後的版本直接塞進寄送流程,而是先在自己這裡寄一封測試郵件,看那幾處依賴空白的間距有沒有變化。

另一條經驗是別把註解留在壓縮後的行裡。壓縮之後一段註解可能把緊跟的程式碼吞掉——這是我那天誤刪註解之後才想明白的,範本裡我用註解標記可編輯區域,壓完必須確認這些標記還在。

什麼時候美化,什麼時候壓縮

我遇到的情形方向理由
建置產物、線上抓下來的原始碼,全在一行美化要讀結構、要定位某個標籤
手寫的 HTML 要發布,體積敏感壓縮去掉換行與縮排,減少傳輸字元
要提交進倉庫、要別人 review美化diff 只顯示真正改動的行
郵件範本、含程式碼範例的頁面美化後檢查、壓縮前檢查空白參與渲染,pre、textarea 內容不能動
排查標籤沒閉合、層級混亂美化靠縮排深度發現錯位的閉合標籤

壓縮這件事我會看工具給出的原始字元數、結果字元數和壓縮率,但我不把它當效能結論用——一次壓縮省的往往只是幾百到幾千個空白字元,頁面快不快主要不是由這點空白決定的。這幾個數對我真正的用處是「量級感」:壓縮率異常高說明原來有大量空白,壓縮率幾乎為 0 說明這檔案本來就是壓縮過的,再壓一次只是白做。

幾件常被問到的

Q:美化會不會改變頁面顯示效果?

絕大多數情況下不會,因為標籤之間的換行會被摺疊成空白,瀏覽器忽略多餘空白。會出問題的地方是 pre、textarea,以及依賴行內元素間距的寫法,這兩類要單獨看。

Q:壓縮以後出問題,能還原回去嗎?

不能精確還原。原來的換行位置和縮排寬度沒有被儲存,壓縮後再美化得到的是按層級重排的版本。所以我從不在唯一一份副本上做壓縮。

Q:接手一行式的檔案,我該整份攤開還是只攤片段?

整份攤開更省事,因為讀結構要看全局;但要提交回去時,我會用壓縮版覆蓋,只把改動的那幾處複製過去,避免格式化波及全檔案。

Q:Tab 和空格哪個「更規範」?

沒有哪個更規範,只有一個專案裡只能用一種。Tab 的問題是顯示寬度取決於編輯器設定,同一份檔案兩個人看到的對齊不一樣;空格則永遠一致。要混用時我傾向於統一轉成空格。

Q:CSS 和 HTML 分在兩個檔案裡,要不要一起處理?

我不會混著做。樣式表的換行規則、影響面和標籤結構不同,我一般把樣式那邊單獨走一遍,改完先看樣式有沒有塌陷,再動 HTML。

那個一行的郵件範本最後是改完了,我用的時間比預期長,不是因為找不到 class,而是因為攤開以後我發現結構本身有兩處閉合標籤位置不對——壓縮的版本把這些都藏在一行裡看不出來。現在我的判斷標準是:要讀懂、要審、要 debug,一律美化;要發布、要減體積,才壓縮;而只要檔案是別人要接著改的,倉庫裡那份就必須是可讀的形態,壓縮留在建置裡。

📎 相關文章

PNG 壓了三遍只減 426 位元組:無損壓縮的真實邊界 2026-10-22 WebP 轉 PNG 後體積漲了幾倍:什麼時候必須轉,怎麼把漲幅壓住 2026-10-22 截圖縮到四分之一,小字糊成一團的三種原因 2026-10-22 同樣裁 300×300,頭像為什麼總偏右下角半格 2026-10-22 按每月 1.7 倍預估 18 個月,腳本和表格為什麼給出兩個數 2026-10-22