如果你問我,前端世界裏最容易被低估、但權力又最大的標籤是誰?

我會毫不猶豫地告訴你:不是 <div>,不是 <span>,而是 <script>。

因為沒有它,HTML 就像一張“死去的地圖”,CSS 也只是“漂亮的外殼”。而 <script>,就是那個能讓頁面活過來的信使

今天我想給你講一個故事。一個發生在“網頁王國”裏的故事。

script元素:網頁王國裏的信使

在很久很久以前(也就是你打開一個網頁的那一瞬間),瀏覽器會進入一個叫網頁王國的地方。這裏有:

  • HTML 城市:負責地皮和房屋結構
  • CSS 裝修隊:負責顏色、大小、排版
  • JavaScript 軍團:負責邏輯、交互、靈魂

而 <script>,就是 JavaScript 軍團唯一被允許進入 HTML 城市的通行證

JavaScript 王國的“信使”:一個關於 script 標籤的故事_CSS

你把 JavaScript 寫在哪裏不重要:只要它被 <script> 包裹,瀏覽器就會認真對待。

所以從本質上來説:

<script> 是 HTML 用來引入或執行腳本代碼的容器

你可以把它理解為:“敲門的人”

script的 8 個屬性:信使的裝備清單

信使不是空手來的。它身上帶着一整套“裝備”,一共 8 個屬性,每一個都決定了腳本的行為方式。

我們先來一張“裝備表”的感覺。

JavaScript 王國的“信使”:一個關於 script 標籤的故事_CSS_02

1、src:信使從哪裏來

這是最常用的屬性。

JavaScript 王國的“信使”:一個關於 script 標籤的故事_CSS_03

含義很簡單:

“別執行我肚子裏的內容了,去這個地址把腳本拿過來。”

一旦 src 出現:

  • <script> 標籤內部的代碼會被忽略
  • 瀏覽器會發起一個網絡請求

你可以把 src 理解成:“快遞單號”

2、type:信件寫的是什麼語言

在很久以前,我們會看到這樣的寫法:

JavaScript 王國的“信使”:一個關於 script 標籤的故事_CSS_04

但在 HTML5 時代:

  • 默認就是 text/javascript
  • 完全可以省略

現在它更多出現在:

  • type="module"
  • 或非 JS 腳本(很少見了)

3、async:信使自由行動

這個屬性後面我們會重點講,但先記一句話:async = 我來了就執行,不等別人

4、defer:信使等開會結束再説

和 async 對應:defer = 你慢慢來,文檔解析完你再上

5、charset:信件的編碼方式

JavaScript 王國的“信使”:一個關於 script 標籤的故事_CSS_05

現代瀏覽器基本都用 UTF-8,這個屬性已經很少需要。

6、crossorigin:跨國信件檢查

當你加載的是 CDN 腳本時,它會出現。

JavaScript 王國的“信使”:一個關於 script 標籤的故事_CSS_06

主要用於:

  • CORS
  • 錯誤堆棧的完整性

7、integrity:防篡改印章

JavaScript 王國的“信使”:一個關於 script 標籤的故事_加載_07

含義是:“如果腳本的哈希和我記的不一樣,那就別執行。”

安全感直接拉滿。

8、nomodule:只給老古董瀏覽器看

用於 type="module" 的補充:

JavaScript 王國的“信使”:一個關於 script 標籤的故事_HTML_08

現代瀏覽器用模塊,老瀏覽器用舊方案。

標籤位置:信使站在哪裏最合適?

這是一個經典到不能再經典的面試題

1、放在 <head> 裏

JavaScript 王國的“信使”:一個關於 script 標籤的故事_HTML_09

問題來了:

  • HTML 解析遇到 <script>
  • 停下來
  • 加載
  • 執行
  • 再繼續解析

結果是什麼?頁面白屏時間變長

2、放在 <body> 最後

JavaScript 王國的“信使”:一個關於 script 標籤的故事_HTML_10

這就像:裝修完房子,再裝智能系統

頁面先展示,再執行腳本,用户體驗明顯更好。

結論

  • 早期:靠位置優化
  • 現代:靠 defer / async

JavaScript 王國的“信使”:一個關於 script 標籤的故事_HTML_11

推遲執行腳本:defer 的故事

假設你在公司開會。

  • 老闆在講戰略
  • PPT 在播放
  • 你在角落記筆記

這時候有個同事衝進來大喊:“我有個 JS 要執行!”

顯然不合適。於是有了 defer。

JavaScript 王國的“信使”:一個關於 script 標籤的故事_加載_12

defer 的規則很清晰:

  1. 腳本會並行下載
  2. 不阻塞 HTML 解析
  3. 等 DOM 解析完成後再執行
  4. 按順序執行

適合:

  • 操作 DOM
  • 多個腳本有依賴關係

異步執行腳本:async 的自由人

如果説 defer 是守紀律的員工,那 async 就是:“我效率高,我説了算”

JavaScript 王國的“信使”:一個關於 script 標籤的故事_加載_13

async 的行為:

  1. 並行下載
  2. 下載完立即執行
  3. 不管 DOM
  4. 多個腳本執行順序不可控

適合:

  • 埋點
  • 廣告
  • 統計
  • 與頁面邏輯無關的腳本

一句話總結:async = 快且亂,defer = 慢但穩

JavaScript 王國的“信使”:一個關於 script 標籤的故事_加載_14

動態加載腳本:叫外賣式的 JS

有些腳本,不適合一開始就加載。比如:

  • 視頻播放器
  • 富文本編輯器
  • 地圖 SDK

這時候你會用動態加載

JavaScript 王國的“信使”:一個關於 script 標籤的故事_加載_15

這相當於:“我現在餓了,才點外賣”

動態加載的特點:

  • 完全由 JS 控制
  • 執行時機靈活
  • 常用於懶加載

在現代工程化中,這幾乎是常態操作。

XHTML 中的變化:古老王國的禮儀

如果你接觸過 XHTML,你會發現它特別嚴格。例如:

  • 標籤必須閉合
  • 屬性必須有值
  • 大寫小寫

在 XHTML 中:

JavaScript 王國的“信使”:一個關於 script 標籤的故事_CSS_16

這一堆 CDATA,一度把無數前端人送走。

好消息是:

  • HTML5 已經完全不需要操心這些
  • XHTML 基本退出歷史舞台

JavaScript 王國的“信使”:一個關於 script 標籤的故事_CSS_17

廢棄的語法:時代的眼淚

技術在進化,一些寫法已經被淘汰。

1. language="javascript"

JavaScript 王國的“信使”:一個關於 script 標籤的故事_HTML_18

早已廢棄。

2. 內聯事件腳本氾濫

JavaScript 王國的“信使”:一個關於 script 標籤的故事_CSS_19

還能用,但不推薦。

3. 同步阻塞式加載所有腳本

在 head 裏堆一堆 <script>,不考慮性能,在今天已經屬於“反模式”。

JavaScript 王國的“信使”:一個關於 script 標籤的故事_加載_20

總結:script不只是一個標籤

很多新手會覺得:<script> 就是“寫 JS 的地方”,但隨着你做的項目越來越複雜,你會發現:

  • 它決定了頁面加載性能
  • 它影響首屏時間
  • 它關係到安全
  • 它是工程化的入口

如果 HTML 是“骨架”,CSS 是“皮膚”,那 <script> 就是:“神經系統”

它一旦設計不好,整個頁面都會“反應遲鈍”。

END

我是小米,一個喜歡分享技術的31歲程序員。如果你喜歡我的文章,歡迎關注我的微信公眾號“軟件求生”,獲取更多技術乾貨!

如果你喜歡這種用講故事的方式聊前端底層知識的文章,歡迎點個在看,我們下次繼續聊點更有意思的。