javascript歷史
Nombas 和 ScriptEase
大概在 1992 年陨仅,一家稱作 Nombas 的公司開發(fā)了一種叫做 C 減減(C-minus-minus,簡稱 Cmm)的嵌入式腳本語言灼伤。Cmm 背后的理念很簡單:一個(gè)足夠強(qiáng)大可以替代宏操作(macro)的腳本語言,同時(shí)保持與 C (和 C ++)足夠的相似性撞鹉,以便開發(fā)人員能很快學(xué)會(huì)颖侄。這個(gè)腳本語言捆綁在一個(gè)叫做 CEnvi 的共享軟件中,它首次向開發(fā)人員展示了這種語言的威力览祖。
Nombas 最終把 Cmm 的名字改成了 ScriptEase,原因是后面的部分(mm)聽起來過于消極又活,同時(shí)字母 C “令人害怕”锰悼。
現(xiàn)在 ScriptEase 已經(jīng)成為了 Nombas 產(chǎn)品背后的主要驅(qū)動(dòng)力。
Netscape 發(fā)明了 JavaScript
當(dāng) Netscape Navigator 嶄露頭角時(shí)箕般,Nombas 開發(fā)了一個(gè)可以嵌入網(wǎng)頁中的 CEnvi 的版本。這些早期的試驗(yàn)被稱為 Espresso Page(濃咖啡般的頁面)可柿,它們代表了第一個(gè)在萬維網(wǎng)上使用的客戶端語言。而 Nombas 絲毫沒有料到它的理念將會(huì)成為萬維網(wǎng)的一塊重要基石复斥。
當(dāng)網(wǎng)上沖浪越來越流行時(shí),對(duì)于開發(fā)客戶端腳本的需求也逐漸增大评汰。此時(shí)痢虹,大部分因特網(wǎng)用戶還僅僅通過 28.8 kbit/s 的調(diào)制解調(diào)器連接到網(wǎng)絡(luò),即便這時(shí)網(wǎng)頁已經(jīng)不斷地變得更大和更復(fù)雜奖唯。而更加加劇用戶痛苦的是,僅僅為了簡單的表單有效性驗(yàn)證坯墨,就要與服務(wù)器進(jìn)行多次地往返交互病往。設(shè)想一下,用戶填完一個(gè)表單停巷,點(diǎn)擊提交按鈕,等待了 30 秒的處理后蕾各,看到的卻是一條告訴你忘記填寫一個(gè)必要的字段。
那時(shí)正處于技術(shù)革新最前沿的 Netscape示损,開始認(rèn)真考慮開發(fā)一種客戶端腳本語言來解決簡單的處理問題嚷硫。
當(dāng)時(shí)工作于 Netscape 的 Brendan Eich,開始著手為即將在 1995 年發(fā)行的 Netscape Navigator 2.0 開發(fā)一個(gè)稱之為 LiveScript 的腳本語言脆贵,當(dāng)時(shí)的目的是在瀏覽器和服務(wù)器(本來要叫它 LiveWire)端使用它。Netscape 與 Sun 及時(shí)完成 LiveScript 實(shí)現(xiàn)卖氨。
就在 Netscape Navigator 2.0 即將正式發(fā)布前,Netscape 將其更名為 JavaScript柏腻,目的是為了利用 Java 這個(gè)因特網(wǎng)時(shí)髦詞匯系吭。Netscape 的賭注最終得到回報(bào),JavaScript 從此變成了因特網(wǎng)的必備組件肯尺。
三足鼎立
因?yàn)?JavaScript 1.0 如此成功,Netscape 在 Netscape Navigator 3.0 中發(fā)布了 1.1 版槐臀。恰巧那個(gè)時(shí)候氓仲,微軟決定進(jìn)軍瀏覽器,發(fā)布了 IE 3.0 并搭載了一個(gè) JavaScript 的克隆版讥巡,叫做 JScript(這樣命名是為了避免與 Netscape 潛在的許可糾紛)舔哪。微軟步入 Web 瀏覽器領(lǐng)域的這重要一步雖然令其聲名狼藉,但也成為 JavaScript 語言發(fā)展過程中的重要一步捉蚤。
在微軟進(jìn)入后炼七,有 3 種不同的 JavaScript 版本同時(shí)存在:Netscape Navigator 3.0 中的 JavaScript、IE 中的 JScript 以及 CEnvi 中的 ScriptEase豌拙。與 C 和其他編程語言不同的是,JavaScript 并沒有一個(gè)標(biāo)準(zhǔn)來統(tǒng)一其語法或特性捉超,而這 3 種不同的版本恰恰突出了這個(gè)問題唯绍。隨著業(yè)界擔(dān)心的增加,這個(gè)語言的標(biāo)準(zhǔn)化顯然已經(jīng)勢在必行况芒。
標(biāo)準(zhǔn)化
1997 年,JavaScript 1.1 作為一個(gè)草案提交給歐洲計(jì)算機(jī)制造商協(xié)會(huì)(ECMA)耐版。第 39 技術(shù)委員會(huì)(TC39)被委派來“標(biāo)準(zhǔn)化一個(gè)通用、跨平臺(tái)粪牲、中立于廠商的腳本語言的語法和語義”(http://www.ecma-international.org/memento/TC39.htm)。由來自 Netscape湿滓、Sun舌狗、微軟、Borland 和其他一些對(duì)腳本編程感興趣的公司的程序員組成的 TC39 錘煉出了 ECMA-262痛侍,該標(biāo)準(zhǔn)定義了名為 ECMAScript 的全新腳本語言。
在接下來的幾年里赵哲,國際標(biāo)準(zhǔn)化組織及國際電工委員會(huì)(ISO/IEC)也采納 ECMAScript 作為標(biāo)準(zhǔn)(ISO/IEC-16262)。從此枫夺,Web 瀏覽器就開始努力(雖然有著不同的程度的成功和失敾婷啤)將 ECMAScript 作為 JavaScript 實(shí)現(xiàn)的基礎(chǔ)。
瀏覽器的渲染機(jī)制
- 獲取 HTML 文檔及樣式表文件
- 解析成對(duì)應(yīng)的樹形數(shù)據(jù)結(jié)構(gòu)
- DOM tree
- CSSOM tree
- 計(jì)算可見節(jié)點(diǎn)形成 render tree
- 計(jì)算 DOM 的形狀及位置進(jìn)行布局
- 將每個(gè)節(jié)點(diǎn)轉(zhuǎn)化為實(shí)際像素繪制到視口上(柵格化)
render tree(頁面上所顯示的最終結(jié)果)是由 DOM tree(開發(fā)工具中所顯示的 HTML 所定義的內(nèi)容結(jié)構(gòu))與 CSSOM tree(樣式表所定義的規(guī)則結(jié)構(gòu))合并并剔除不可見的節(jié)點(diǎn)所形成的扒最,其中不包含如下節(jié)點(diǎn):
- 本身不可見的
- <html>
- <head>
- <meta>
- <link>
- <style>
- <script>
- 設(shè)置了 display: none; 樣式的
css樣式j(luò)avascript樣式在html中的位置
CSS文件的引入位置放在頭部(<head>標(biāo)簽內(nèi)部)
將js文件的引入位置放在底部(</body>前面)
白屏&FOUC (Flash of Unstyled Content) 無樣式內(nèi)容閃爍
- 不同的瀏覽器對(duì)于CSS和HTML的處理方式不同华嘹,有的是等待CSS加載完成之后,對(duì)HTML元素進(jìn)行渲染和展示(白屏問題)耙厚。有的是先對(duì)HTML元素進(jìn)行展示,然后等待CSS加載完成之后重新對(duì)樣式進(jìn)行修改(FOUC無樣式內(nèi)容閃爍)
- 如果把js文件放在頭部纠拔,腳本會(huì)阻塞后面內(nèi)容的呈現(xiàn)泛豪,腳本會(huì)阻塞其后組件的下載侦鹏,出現(xiàn)白屏問題臀叙。
repaint和 reflow的概念
- repaint:不改變位置的更改樣式操作
- reflow:改變位置的的更改樣式操作
- reflow和repaint都需要運(yùn)算。所有需要優(yōu)化盡量減少運(yùn)算量劝萤。(如:減少DOM元素直接操作、)
如何異步加載腳本
- repaint:不改變位置的更改樣式操作
- reflow:改變位置的的更改樣式操作
- reflow和repaint都需要運(yùn)算跨释。所有需要優(yōu)化盡量減少運(yùn)算量厌处。(如:減少DOM元素直接操作、)
js的加載會(huì)阻塞后面元素的加載
- 有必要使用異步加載阔涉,可以設(shè)置加載數(shù)據(jù)
<script src="script.js"></script>
<script defer src="script.js"></script>
<script async src="script.js"></script>
- defer:腳本延遲到文檔解析和顯示后執(zhí)行蹲诀,有順序
- async:不保證順序
- 沒有 defer 或 async,瀏覽器會(huì)立即加載并執(zhí)行指定的腳本椭住,“立即”指的是在渲染該 script 標(biāo)簽之下的文檔元素之前,也就是說不等待后續(xù)載入的文檔元素函荣,讀到就加載并執(zhí)行。