摘要:標(biāo)簽加載順序如果要談標(biāo)簽加載順序問題,首先要談的就是標(biāo)簽的位置,因?yàn)闃?biāo)簽的位置對(duì)于加載順序來說有著很重要的影響。例如標(biāo)簽在以上代碼中,可能由于下載時(shí)間比較長(zhǎng),由于兩個(gè)標(biāo)簽都是異步執(zhí)行,互不干擾,因此可能就會(huì)先于執(zhí)行。
談?wù)? 標(biāo)簽加載順序的問題
這篇文章比較長(zhǎng),如果你耐心讀完了,我會(huì)感謝你愿意在這篇文章上花費(fèi)時(shí)間,也希望你有收獲。
其實(shí)說起,幾乎搞前端的都知道他的作用:引入 JavaScrit 代碼。沒錯(cuò),這就是被創(chuàng)建的最初原因。標(biāo)簽出現(xiàn)的很早,這個(gè)元素是由 Netscape 創(chuàng)造,并在 Netscape Navigator 2中首先實(shí)現(xiàn)。后來,這個(gè)元素被加入到正式的 HTML 規(guī)范中。
JavaScript 的誕生離不開 Netscape ,JavaScript 是由 Netscape 公司的布蘭登·艾奇(Brendan Eich)在 1995 年開發(fā)的一種腳本語言,JavaScript 的第一個(gè)版本 JavaScript 1.0 就在 Netscape Navigator 2 實(shí)現(xiàn)。擁有的屬性
async:可選,表示應(yīng)該立即下載腳本,但不應(yīng)妨礙頁面中的其他操作,比如下載其他資源或等待加載其他腳本。只對(duì)外部腳本文件有效。
charset:可選。表示通過 src 屬性指定的代碼的字符集。由于大多數(shù)瀏覽器會(huì)忽略它的值,因此這個(gè)屬性很少有人用。
defer:可選。表示腳本可以延遲到文檔完全被解析和顯示之后再執(zhí)行。只對(duì)外部腳本文件有效。IE7 及更早版本對(duì)嵌入腳本也支持這個(gè)屬性。
language: 已廢棄。原來用于表示編寫代碼使用的腳本語言(如 JavaScript 、 JavaScript1.2 或 VBScript )。大多數(shù)瀏覽器會(huì)忽略這個(gè)屬性,因此也沒有必要再用了。
src:可選。表示包含要執(zhí)行代碼的外部文件。
type:可選??梢钥闯墒?language 的替代屬性;表示編寫代碼使用的腳本語言的內(nèi)容類型(也稱為 MIME 類型)。雖然 text/javascript
和 text/ecmascript 都已經(jīng)不被推薦使用,但人們一直以來使用的都還是 text/javascript 。實(shí)際上,服務(wù)器在傳送 JavaScript 文件時(shí)使用的
MIME 類型通常是 application/x–javascript ,但在 type 中設(shè)置這個(gè)值卻可能導(dǎo)致腳本被忽略。另外,在非IE瀏覽器中還可以使用以下值:
application/javascript 和 application/ecmascript ??紤]到約定俗成和最大限度的瀏覽器兼容性,目前 type 屬性的值依舊還是
text/javascript 。不過,這個(gè)屬性并不是必需的,如果沒有指定這個(gè)屬性,則其默認(rèn)值仍為text/javascript 。
在以上屬性中 async屬性是 HTML5 中的新屬性。引入方式 JavaScript 的兩種方式 內(nèi)聯(lián)形式
這種方式指的是在 html 文件中,添加一個(gè)標(biāo)簽,然后將 JavaScript代碼直接寫在里面,如:
外置形式script 標(biāo)簽
外置形式是將 JavaScript 代碼寫在外部的一個(gè)文件里面,在 html 文件中通過 標(biāo)簽的 src 屬性引入,如:
兩種引入形式的比較script 標(biāo)簽
對(duì)于這兩種方式,毫無疑問,外置形式明顯好于內(nèi)聯(lián)形式,主要表現(xiàn)為以下方面:
可維護(hù)性:外置 Javascript 文件可以被多個(gè)頁面調(diào)用而不用在每個(gè)頁面上反復(fù)地書寫.如果有需要改變的部分,你只需要在一處修改即可.所以外置JavaScript 導(dǎo)致代碼工作量減少,進(jìn)而使得維護(hù)手續(xù)也更加方便。
可緩存:瀏覽器能夠根據(jù)具體的設(shè)置緩存鏈接的所有外部 JavaScript文件。也就是說,如果有兩個(gè)頁面都使用同一個(gè)文件,那么這個(gè)文件只需下載一次。因此,最終結(jié)果就是能夠加快頁面加載的速度。
關(guān)注點(diǎn)分離:將 JavaScript 封裝在外部的.js文件遵循了關(guān)注點(diǎn)分離的法則.總體來說,分離 HTML,CSS 和 JavaScript 從而讓我們更容易操縱他們.而且如果是多名開發(fā)者同步工作的話,這樣也更方便。
因此,在今后的開發(fā)中盡量使用外置方式的形式引入JavaScript。
標(biāo)簽加載順序如果要談 標(biāo)簽加載順序問題,首先要談的就是標(biāo)簽的位置,因?yàn)闃?biāo)簽的位置對(duì)于JavaScript加載順序來說有著很重要的影響。
標(biāo)簽位置標(biāo)簽的位置有兩種,一種是方式元素里面,另外一種就是放在 元素中頁面內(nèi)容的后面,下面將一一介紹這兩種形式:
標(biāo)簽放在元素里Example HTML Page
這是一種比較傳統(tǒng)的做法,目的就是把所有外部文件(包括 CSS 文件和 JavaScript 文件)的引用都放在相同的地方.可是,在文檔的
元素中包含所有 JavaScript 文件,意味著必須等到全部 JavaScript 代碼都被下載、解析和執(zhí)行完成以后,才能開始呈現(xiàn)頁面的內(nèi)容(瀏覽器在遇到 標(biāo)簽時(shí)才開始呈現(xiàn)內(nèi)容)。對(duì)于那些需要很多 JavaScript 代碼的頁面來說,這無疑會(huì)導(dǎo)致瀏覽器在呈現(xiàn)頁面時(shí)出現(xiàn)明顯的延遲,而延遲期間的瀏覽器窗口中將是一片空白。很明顯,這種做法有著很明顯的缺點(diǎn),特別是針對(duì)于現(xiàn)在的移動(dòng)端來說,如果超過 1s 還沒有內(nèi)容呈現(xiàn)的話將是一種很差的用戶體驗(yàn)。為了避免這個(gè)問題,就有了下面這種加載方式。 標(biāo)簽放在 元素中頁面內(nèi)容的后面Example HTML Page
對(duì)于這種方式,在解析包含的 JavaScript 代碼之前,頁面的內(nèi)容將完全呈現(xiàn)在瀏覽器中。而用戶也會(huì)因?yàn)闉g覽器窗口顯示空白頁面的時(shí)間縮短而感到打開頁面的速度加快了
延遲加載的每個(gè)屬性設(shè)計(jì)來肯定都是有用的,下面我們就來說一說 defer 屬性。
HTML 4.01 為 標(biāo)簽定義了 defer 屬性。這個(gè)屬性的用途是表明腳本在執(zhí)行時(shí)不會(huì)影響頁面的構(gòu)造。也就是說,腳本會(huì)被延遲到整個(gè)頁面都解析完畢后再運(yùn)行。因此,在 元素中設(shè)置defer 屬性,相當(dāng)于告訴瀏覽器立即下載,但延遲執(zhí)行,比如:
script 標(biāo)簽
在這個(gè)例子中,雖然我們把 元素放在了文檔的 元素中,但其中包含的腳本將延遲到瀏覽器遇到 標(biāo)簽后再執(zhí)行。HTML5 規(guī)范要求腳本按照它們出現(xiàn)的先后順序執(zhí)行,因此第一個(gè)延遲腳本會(huì)先于第二個(gè)延遲腳本執(zhí)行,而這兩個(gè)腳本會(huì)先于 DOMContentLoaded 事件執(zhí)行。在現(xiàn)實(shí)當(dāng)中,延遲腳本并不一定會(huì)按照順序執(zhí)行,也不一定會(huì)在 DOMContentLoaded 事件觸發(fā)前執(zhí)行,因此最好只包含一個(gè)延遲腳本。
"在現(xiàn)實(shí)當(dāng)中,延遲腳本并不一定會(huì)按照順序執(zhí)行,也不一定會(huì)在 DOMContentLoaded 事件觸發(fā)前執(zhí)行,因此最好只包含一個(gè)延遲腳本。" 這段話是《JavaScript 高級(jí)程序設(shè)計(jì)(第三版)》中的一句話,糾結(jié)了很久。自己也嘗試寫了一些例子,但反饋的結(jié)果都是:如果引入的 標(biāo)簽 都使用了 defer 屬性,他們的執(zhí)行順序都是按照他們引入的順序來的。那么作者為什么會(huì)寫上這一句話呢,個(gè)人感覺原因是:即使在 HTML5 規(guī)范中有這么一條,不一定所有的瀏覽器廠商都會(huì)遵照這個(gè)規(guī)定,可能某些瀏覽器廠商并沒有實(shí)現(xiàn)這個(gè)規(guī)范,但支持 defer 屬性,那么就會(huì)出現(xiàn)作者所描述的那種情況,所以為了安全起見,在開發(fā)中使用一個(gè) defer 是非常有必要的。
還有一點(diǎn)需要注意的是,defer 屬性只適用于外部腳本文件。
從圖中可以看出,某些瀏覽器或者在一些低版本的瀏覽器中并不支持defer屬性,因此,把延遲腳本放在頁面底部仍然是最佳選擇。
異步加載說完了延遲加載,然后我們?cè)僬f下異步加載,即使用 async屬性。
HTML5 為
在以上代碼中,可能由于 01.js 下載時(shí)間比較長(zhǎng),由于兩個(gè)
可以看出 IE9 及以下版本都不支持 async屬性,因此,把延遲腳本放在頁面底部仍然是最佳選擇。
標(biāo)簽加載可視化下面將用一張圖來描述 標(biāo)簽三種狀態(tài)下(normal,defer,async)于html加載的關(guān)系:
綠色代表html解析,淡藍(lán)色代表html解析停止,藍(lán)色代表script下載,粉紅色代表script執(zhí)行。從上圖很容易的看出來只要執(zhí)行script,html就會(huì)停止渲染,除此之外也可以清晰的看出他們之間的加載關(guān)系。
小結(jié)所有 標(biāo)簽引進(jìn)的 JavaScript 會(huì)按照他們引入的順序依次被解析,在沒有使用 defer 或者 async 的情況下,只有在解析完前面 元素中的代碼之后,才會(huì)開始解析后面 元素中的代碼。
由于瀏覽器會(huì)先解析完不使用 defer 屬性的 元素中的代碼,然后再解析后面的內(nèi)容,所以一般應(yīng)該把 元素放在頁面最后,即主要內(nèi)容后面, 標(biāo)簽前面。
使用 defer 屬性可以讓腳本在文檔完全呈現(xiàn)之后再執(zhí)行,延遲腳本總是按照指定它們的順序執(zhí)行。
使用 async 屬性可以表示當(dāng)前腳本不必等待其他腳本,也不必阻塞文檔呈現(xiàn)。不能保證異步腳本按照它們?cè)陧撁嬷谐霈F(xiàn)的順序執(zhí)行。
結(jié)束語這篇文章是最近讀了 《JavaScript 高級(jí)程序設(shè)計(jì)(第三版)》后寫的?,F(xiàn)在仔細(xì)閱讀這本書你會(huì)發(fā)現(xiàn)其中真的有很多的樂趣,這些樂趣來自于你可以更深一步的去了解 JavaScript,源自于你原來可以將這個(gè)知識(shí)點(diǎn)弄得這么的透徹,源自于你也許真的對(duì)這么語言有了興趣。其實(shí)我在github上創(chuàng)建了一個(gè)倉庫,用戶記錄自己在讀了這本書中一些知識(shí)點(diǎn)以后的一些理解,算是閱讀筆記吧,也算是鼓勵(lì)自己堅(jiān)持認(rèn)真的把這本書看完,抵抗一下天生的惰性,如果你也想進(jìn)一步深刻的了解 JavaScript這門語言,可以點(diǎn)擊這里,大家一起在github學(xué)習(xí)。最后,如果這篇文章有寫的不對(duì)的地方還望各位大佬指出。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/93276.html
摘要:指定了屬性的元素標(biāo)簽內(nèi)不應(yīng)該再有嵌入的腳本。該屬性定義元素包含或引用的腳本語言。為時(shí)缺省為方式。該屬性指示瀏覽器是否在允許的情況下異步執(zhí)行該腳本。這個(gè)屬性被設(shè)定用來通知瀏覽器該腳本將在文檔完成解析后,觸發(fā)事件前執(zhí)行。 html元素及其屬性,相信大家都很熟悉,但是script的屬性,未必熟悉,故而整理總結(jié),以待查閱。 前言 默認(rèn)情況下,瀏覽器是同步加載 JavaScript 腳本,即渲染...
摘要:指定了屬性的元素標(biāo)簽內(nèi)不應(yīng)該再有嵌入的腳本。該屬性定義元素包含或引用的腳本語言。為時(shí)缺省為方式。該屬性指示瀏覽器是否在允許的情況下異步執(zhí)行該腳本。這個(gè)屬性被設(shè)定用來通知瀏覽器該腳本將在文檔完成解析后,觸發(fā)事件前執(zhí)行。 html元素及其屬性,相信大家都很熟悉,但是script的屬性,未必熟悉,故而整理總結(jié),以待查閱。 前言 默認(rèn)情況下,瀏覽器是同步加載 JavaScript 腳本,即渲染...
摘要:阻塞原理瀏覽器內(nèi)核可以分成兩部分渲染引擎或者和引擎。等引擎運(yùn)行完畢,瀏覽器又會(huì)把控制權(quán)還給渲染引擎,繼續(xù)和的構(gòu)建。執(zhí)行時(shí),解析暫停。從加載完成立即執(zhí)行來看,模式執(zhí)行順序與寫的順序無關(guān),不保證執(zhí)行順序。 js阻塞原理 瀏覽器內(nèi)核可以分成兩部分:渲染引擎(Layout Engine 或者 Rendering Engine)和 JS 引擎。早期渲染引擎和 JS 引擎并沒有十分明確的區(qū)分,但隨...
摘要:徹底搞懂通過瀏覽器的開發(fā)者工具可以直觀的看到,圖中藍(lán)色的線和藍(lán)色的字使用不同的表現(xiàn)形式表示這個(gè)事件觸發(fā)的時(shí)間。當(dāng)腳本下載完后立即執(zhí)行,執(zhí)行順序不確定。 徹底搞懂 defer & async DOMContentLoaded showImg(https://segmentfault.com/img/remote/1460000013480394?w=1309&h=879); 通過 chr...
閱讀 684·2021-11-22 15:32
閱讀 2774·2021-11-19 09:40
閱讀 2390·2021-11-17 09:33
閱讀 1342·2021-11-15 11:36
閱讀 1932·2021-10-11 10:59
閱讀 1537·2019-08-29 16:41
閱讀 1837·2019-08-29 13:45
閱讀 2218·2019-08-26 13:36