js Task1

網頁

什么是網頁?

  • 網頁 =Html+CSS+JavaScript
    • Html是網頁的內容
    • CSS是網頁的樣式
    • JavaScript是網頁的行為

每個學習編程語言的第一個編程肯定是打印出"Hello World"來看看JavaScript是怎么實現的.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>認識js</title>
</head>
<body>
    <script>
        document.write("Hello World")   //會在頁面中出現Hello World
    </script>
</body>
</html>

來看一下JavaScript的發展歷史

誰也想不到,1995年被當做營銷策略推出的JavaScript語言,在2017年成為了最受歡迎平臺(web)上的核心語言。JavaScript現在不僅可以在瀏覽器中運行,它還被用作開發桌面和手機應用,用于嵌入式設備,甚至NASA還拿它來設計太空組件。

發展
JS標準制定簡史(簡略)
  • 只花了10天時間 Brendan 就開發完成了當時被稱作Mocha的初版 JavaScript 原型,這個新語言類似 Scheme ,它把函數當做一等公民,并以原型鏈為其核心。那時候的JS比較簡陋,沒有數組和字面量的對象的概念,所有的報錯都只能通過丑陋的alert展示,缺乏異常處理機制,出錯時很多運算的結果會是NaN或undefined。
  • 1995年9月,網景公司發布了Netscape Navigator 2.0 beta版,JavaScript也被包裝為LiveScript一同面世。
  • 1995年12月,Netscape Navigator 2.0 beta3發布,LiveScript在這時被改名為JavaScript(當時這個商標為Sun公司所有,現在屬甲骨文公司)。之后不久,網景推出了LiveWire,一種在其服務器(Netscape Enterprise Server)上的JavaScript實現1。
  • 1996年開始,JS語言開始走上規范之路,它已ECMAScript的名字被標準化到ECMA-262規范,
  • 1997年6月ECMA-262的第一版發布,之后一年中,規范依據ISO / IEC 16262國際標準進行了改進,并由ISO認證機構大量審查,1997年6月ECMAScript規范正式發布第二版。
  • 1999年12月,第三版也發布了,這一版的規范帶來了正則表達式,switch,do/while,try/catch,Object#hasOwnProperty以及其它的一些改變
  • 2007年,TC39委員會被迫分為兩部分,一部分負責ES3的漸進加強版ES3.1標準的制定,另一部分則負責重新設計改動巨大的ES4標準。2008年8月,ES3.1被認為是正確的選擇,隨后其更名為ES5,ES4也隨之被廢棄,不過值得慶幸的是 ES4 提出的很多新功能被融入到了 ES6 ,也有一些功能仍然在考慮之中,另一些則已被放棄,拒絕或撤回。兼容ES3.1 成為 ES4 標準提出的功能可能被采納的前提。
  • 2009年12月,ES3發布10周年后,第五版ECMAScript才得以發布。這個版本把十年來各瀏覽器中已有的普遍實踐標準化了,新增了getset,改進了數組原型的函數式特征,原生支持了JSON的解析,提出了嚴格模式。
  • 2015年6月,也就是ES5.1發布的四年后,TC39公布了JS語言有史以來最大的更新 ES6,其中包含了很多ES4中提出草案。本書,我們將深入探索ES6。
  • ES6的發布是JS標準制定歷史上的一個重要里程碑。除了數十種引入注目的新功能,ES6 的發布也標志著 ECMAScript 標準將持續更新。

問題:ES3、ES5、ES6指什么?

  • ES3 ES5 ES6 指的是不同的ECMAScript的版本
    • 1999年12月,ECMAScript 3.0版發布,成為JavaScript的通行標準,得到了廣泛支持。
    • 2009年12月,ECMAScript 5.0版正式發布
    • 2015年6月,ECMAScript 6正式發布

參考:


瀏覽器的渲染機制

了解渲染機制之前,我們先了解幾個概念

  • DOM:Document Object Model,瀏覽器將HTML解析成樹形的數據結構,簡稱DOM。
  • CSSOM:CSS Object Model,瀏覽器將CSS代碼解析成樹形的數據結構。
  • DOM 和 CSSOM 都是以 Bytes → characters → tokens → nodes → object model.這樣的方式生成最終的數據
  • Render Tree:DOM 和 CSSOM 合并后生成 Render Tree

瀏覽器渲染過程

渲染流程圖

渲染流程圖
  1. 用戶輸入一個URL的時候,瀏覽器就會發送一個請求,請求URL對應的資源。
  2. 瀏覽器的HTML解析器會將這個文件解析,并且構建成一棵DOM樹。(在生成DOM的最開始階段(應該是Bytes → characters后),并行發起css、圖片、js的請求,無論他們是否在HEAD里。)
    • 注意:發起js文件的下載request并不需要DOM處理到那個script節點,比如:簡單的正則匹配就能做到這一點,雖然實際上并不一定是通過正則:)。這是很多人在理解渲染機制的時候存在的誤區
  3. 在構建DOM樹的時候,遇到 js
    CSS元素,HTML解析器就換將控制權轉讓給JS解析器或者是CSS解析器。開始構建CSSOM
  4. DOM樹構建完之后,瀏覽器把DOM樹中的一些不可視元素去掉,然后與CSSOM合成一棵render tree
  5. Layout:有了Render Tree,瀏覽器已經能知道網頁中有哪些節點、各個節點的CSS定義以及他們的從屬關系。下一步操作稱之為Layout,顧名思義就是計算出每個節點在屏幕中的位置。
  6. Painting:Layout后,瀏覽器已經知道了哪些節點要顯示(which nodes are visible)、每個節點的CSS屬性是什么(their computed styles)、每個節點在屏幕中的位置是哪里(geometry)。就進入了最后一步:Painting,按照算出來的規則,通過顯卡,把內容畫到屏幕上。

以上幾個步驟因為DOM、CSSOM、Render Tree都可能在第一次Painting后又被更新多次,比如JS修改了DOM或者CSS屬性。LayoutPainting也會被重復執行,除了DOM、CSSOM更新的原因外,圖片下載完成后也需要調用Layout 和 `Painting來更新網頁

關于Repaint 和 Reflow

Repaint Reflow也就是中文中的重繪和回流

  • 重繪(repaints)是一個元素外觀的改變所觸發的瀏覽器行為,例如改變vidibility、outline、背景色等屬性。瀏覽器會根據元素的新屬性重新繪制,使元素呈現新的外觀。重繪不會帶來重新布局,并不一定伴隨回流。
  • 回流(reflow)是更明顯的一種改變,可以理解為渲染樹需要重新計算。

引起RepainReflow的一些操作

  • 當你增加、刪除、修改 DOM 結點時,會導致 Reflow 或 Repaint
  • 當你移動DOM的位置,或是搞個動畫的時候。
  • 當你修改CSS樣式的時候。
  • 當你 Resize 窗口的時候(移動端沒有這個問題),或是滾動的時候。
  • 當你修改網頁的默認字體時
    • 注:display:none 會觸發 reflow,而 visibility:hidden 只會觸發 repaint,因為沒有發現位置變化。

參考:

重繪,回流概念
重繪和回流


如何異步加載腳本

HTML頁面中插入JavaScript的方法,就是使用<script>標簽,我們先來了解一下<script>定義了6個屬性

  • async:異步腳本可選,表示立即下載腳本,但不妨礙頁面中其他操作,只對外部腳本有效
  • defer:延遲腳本可選.表示腳本可以延遲到文檔完全被解析和顯示之后再執行.只對外部腳本文件有效
  • charset:可選,表示通過src屬性指定的代碼的字符集,由于大多數瀏覽器會忽略這個值,因此屬性很少用
  • src:可選,表示包含要執行的外部文件
  • language:已廢棄
  • type:可選,可以看成是language的替代屬性
<script src="script.js"></script>
  • 沒有 deferasync,瀏覽器會立即加載并執行指定的腳本,“立即”指的是在渲染該script 標簽之下的文檔元素之前,也就是說不等待后續載入的文檔元素,讀到就加載并執行
<script async src="script1.js"></script>
<script async src="script2.js"></script>
  • async,加載和渲染后續文檔元素的過程將和 script.js 的加載與執行并行進行(異步)。
  • async不保證按照它們的先后順與執行
  • 異步腳本一定會在頁面的load事件前執行
<script defer src="script.js"></script>
  • defer,加載后續文檔元素的過程將和 script.js 的加載并行進行(異步),但 script.js的執行要在所有元素解析完成之后,DOMContentLoaded事件觸發之前完成。
  • 腳本延遲到文檔解析和顯示后執行,有順序

解釋白屏和 FOUC(無樣式內容閃爍)

  • fouc出現的條件
    1. 使用@import方法導入CSS時,此方式由于IE會先加載整個HTML文檔的DOM,然后再去導入外部的CSS文件,因此,在頁面DOM加載完成到CSS導入完成中間會有一段時間頁面上的內容是沒有樣式的,這段時間的長短跟網速,電腦速度都有關系。
    2. 將樣式表放在頁面底部
    3. 有幾個樣式表,放在html結構的不同位置。

原理:

當樣式表晚于結構性html加載,當加載到此樣式表時,頁面將停止之前的渲染。此樣式表被下載和解析后,將重新渲染頁面,也就出現了短暫的花屏現象。

解決方法:

使用LINK標簽將樣式表放在文檔HEAD中。

CSS 和 JS 放置順序, 異步機制

  • 使用 link 標簽將樣式表放在頂部
  • 將JS放在底部
    • 腳本會阻塞后面內容的呈現
    • 腳本會阻塞其后組件的下載

對于圖片和CSS, 在加載時會并發加載(如一個域名下同時加載兩個文件). 但在加載 JavaScript 時,會禁用并發,并且阻止其他內容的下載. 所以把 JavaScript 放入頁面頂部也會導致 白屏 現象.

白屏

上圖我們可以看到對于chrome瀏覽器來說,等所有的css加載完成并解析完成,CSSOM計算完成,把頁面你全部展示出來,所以會出現解析時間的白屏
FOUC

上圖我們可以看到開始時字體比較小都是html的正常字體大小,然后當css加載完成后會出現加載css央視后的字體,頁面發生了變化,這是firefox的處理機制(無樣式內容閃爍)


最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容