本文主要內容:
- AJAX
- GET和POST請求的區別
- 同源策略、JSONP、跨域方式
- 瀏覽器架構
- 輸入一個Url到加載網頁的全過程,發生了什麼?
- 瀏覽器渲染的步驟
- 重繪和迴流
- 頁面渲染優化
AJAX
-
建立請求對象
-
與服務端建立鏈接,執行open方法;
-
發送請求,執行send方法;
-
爲請求對象綁定onreadystate事件,當readyState爲4 且 status爲200時處理數據;
function Ajax(options) {
var xhr = null;
var params = formsParams(options.data);
// 第一步: 建立請求對象
if(window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
} else {
// 兼容IE6
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
// 第二步: 鏈接,執行open和send方法;
if(options.type == 'GET') {
xhr.open(options.type, options.url + '?' + params, options.async);
xhr.send();
} else if(options.type == 'POST') {
xhr.open(options.type, options.url, options.async);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send(params);
}
// 綁定onreadystatechange事件
xhr.onreadystatechange = function() {
if(xhr.readyState == 4 && xhr.status == 200) {
options.success(xhr.responseText);
}
}
function formsParams(data) {
var arr = [];
for(var i in data) {
arr.push(i + '=' + data[i]);
}
arr.join('&');
}
}複製代碼
Ajax({
type: 'GET',
url: 'a.php',
async: true,
data: {
name: 'zhangsan',
age: 10
},
success: function(data) {
console.log(data);
}
});複製代碼
-
實現局部刷新
-
減輕服務器端壓力
-
破壞瀏覽器前進和後退機制;
-
一個頁面ajax請求過多,會形成頁面加載緩慢;
-
數據安全問題不太好,能夠採用數據加密的方式;
2 - send方法已經完成,已經接收到所有相應內容
GET和POST請求的區別
get: 緩存/長度受限(2M)/無反作用(不修改資源)/冪等的場景(請求數據與資源無關)
post: 安全/長度無限制/支持更多編碼類型(ACII & 二進制)
關於安全方面,其實GET和POST二者都不安全。 雖然POST請求的數據不攜帶在URL上,可是由於HTTP在網絡傳輸的時候是明文傳輸的,因此,只要使用抓包工具,能垂手可得的獲取數據; 想要安全傳輸,只有加密,能夠前端將傳輸參數進行加密,也能夠才用HTTPS;
同源策略、JSONP、跨域方式
端口號、域名、協議名,三者必須所有相同才符合同源策略,反之即爲跨域;
原理:動態生成script標籤,利用script不受跨域的限制,可是缺點是隻支持get請求;
function jsonp(url, callback, success) {
var script = document.createElement('script');
script.src = url;
script.async = true;
script.type = 'text/javascript';
window[callback] = function(data) {
success && success(data);
}
document.body.appendChild(script);
}複製代碼
-
設置 CORS: Access-Control-Allow-Origin:*
瀏覽器架構
先解釋一個概念: 線程(Thread):線程是進程的一部分,而且執行進程中的一部分程序; 進程 (Process):啓動一個程序,就會建立一個進程,操做系統爲其分配內存,進程中的全部線程中的全部程序狀態都保存到該內存中,關閉程序,進程也會消失,內存會釋放;
-
多是一個有不少線程的進程
-
也多是有少許線程的多個進程,經過IPC進行通訊
Chrome 就是屬於多進程之間進行通訊,如今是爲每一個標籤建立一個進程,正在嘗試爲每一個站點提供本身的進程;
-
多進程的設計可使多個標籤頁面的加載不受其餘的影響;
-
安全性和沙盒,每一個進程有本身獨立的存儲空間
-
因爲每一個進程都有本身的存儲空間,它一般包含公共基礎結構的副本(例如V8引擎),這樣會消耗不少內存空間;
Chrome瀏覽器爲了節省內存,對進程的數量作了限制,這個因內存和CPU功率而定;
當達到這個限制的時候,瀏覽器會在同一進程中運行從同一站點打開的多個選項卡;
2. 當Chrome瀏覽器遇到更強大的硬件時,會將每一個服務拆分紅不一樣的進程,從而提供更高的穩定性;可是若是資源有限的設備上,會將服務整合到一個進程中,從而節省內存。Android上已經實現了服務的整合;
-
用戶界面(User Interface)
-
瀏覽器引擎(browser engine)
-
渲染引擎(rendering engine)
-
網絡(Networking)
-
用戶界面後段(UI Backend)
-
JavaScript解析器(JavaScript Interpreter)
-
數據存儲(Data persistence)
輸入一個Url到加載網頁的全過程,發生了什麼?
-
域名解析:瀏覽器將URL解析出相對應的服務器的IP地址(如今本地瀏覽器的DNS緩存中查找,沒有的話,再向瀏覽器默認的DNS服務器發送查詢請求,同時緩存),並從url中解析出端口號
-
瀏覽器與目標服務器創建一條TCP鏈接(三次握手);
-
瀏覽器向服務器發送一條HTTP請求報文
-
服務器返回給瀏覽器一條HTTP響應報文
-
關閉鏈接,解析文檔
-
瀏覽器進行渲染
-
若是文檔中資源加載就再次創建鏈接,直至資源所有加載完畢
瀏覽器渲染的步驟
-
HTML解析出DOM Tree
-
CSS解析出Style Rules
-
二者關聯生成Render Tree
-
Layout(佈局)根據Render Tree 計算每一個節點的信息
-
Painting 根據計算好的信息進行渲染整個頁面
瀏覽器解析文檔的過程當中, 若是遇到script標籤,會當即解析腳本,中止解析文檔(由於JS可能會改變DOM和CSS,若是繼續解析會形成浪費)。 若是是外部script, 會等待腳本下載完成以後在繼續解析文檔。如今script標籤增長了defer和async屬性,腳本解析會將腳本中改變DOM和css的地方解析出來,追加到DOM Tree 和 Style Rules上
重繪和迴流
迴流(reflow):當頁面發生從新佈局的過程。元素的幾何尺寸發生變化時,須要從新計算節點信息,也就是執行了渲染步驟的第4步;
重繪(repaint):屏幕的一部分須要從新繪製,好比css背影色變化,顏色變化等。
$('body').css('color', 'red'); // repaint
$('body').css('margin', '2px'); // reflow, repaint
var bstyle = document.body.style; // cache
bstyle.padding = "20px"; // reflow, repaint
bstyle.border = "10px solid red"; // 再一次的 reflow 和 repaint
bstyle.color = "blue"; // repaint
bstyle.backgroundColor = "#fad"; // repaint
bstyle.fontSize = "2em"; // reflow, repaint
// new DOM element - reflow, repaint
document.body.appendChild(document.createTextNode('dude!'));複製代碼
可是瀏覽器不會像上邊那樣,每改一次樣式都會從新reflow和repaint一次。通常來講,瀏覽器會把這樣的操做積攢一波,而後reflow一次。
頁面渲染優化
-
HTML文檔結構層次儘可能少,最好不深於6層
-
腳本儘可能放後邊,避免組織頁面加載
-
少許首屏樣式能夠放在便籤內
-
樣式結構層次儘可能簡單
-
腳本減小DOM操做,減小回流,儘可能緩存訪問DOM的樣式信息
-
儘可能減小JS修改樣式,能夠經過修改class名的方式解決
-
減小DOM查找,緩存DOM查找結果
-
動畫在屏幕外或頁面滾動時,儘可能中止