標準盒子模型:寬度=內容的寬度(content)+ border + padding (box-sizing)html
低版本IE盒子模型:寬度=內容寬度(content+border+padding)前端
用戶輸入URL地址html5
瀏覽器解析URL解析出主機名android
瀏覽器將主機名轉換成服務器ip地址(瀏覽器先查找本地DNS緩存列表 沒有的話 再向瀏覽器默認的DNS服務器發送查詢請求 同時緩存)ios
瀏覽器將端口號從URL中解析出來nginx
瀏覽器創建一條與目標Web服務器的TCP鏈接(三次握手)es6
瀏覽器向服務器發送一條HTTP請求報文web
數據庫
關閉鏈接 瀏覽器解析文檔跨域
若是文檔中有資源 重複6 7 8 動做 直至資源所有加載完畢
HTML解析出DOM Tree
CSS解析出Style Rules
將兩者關聯生成Render Tree
Layout 根據Render Tree計算每一個節點的信息
Painting 根據計算好的信息繪製整個頁面
兼容性,PC考慮的是瀏覽器的兼容性,而移動端開發考慮的更多的是手機兼容性,由於目前不論是android手機仍是ios手機,通常瀏覽器使用的都是webkit內核,因此說作移動端開發,更多考慮的應該是手機分辨率的適配,和不一樣操做系統的略微差別化。
在部分事件的處理上,移動端多出來的事件是觸屏事件,而缺乏的是hover事件。 另外包括移動端彈出的手機鍵盤的處理,這樣的問題在PC端都是遇不到的。
在佈局上,移動端開發通常是要作到佈局自適應的,rem此時就有很大的用處了。
動畫處理,PC端因爲要考慮IE的兼容性,因此一般使用JS作動畫的通用性會更好一些,可是CSS3作了很大的犧牲, 而在手機端,若是要作一些動畫、特效等,第一選擇確定是CSS3, 既簡單、效率又高。
頁面性能,PC端網絡通常比較穩定,而移動端網絡狀況就比較複雜,不穩定的網絡鏈接對頁面性能帶來的挑戰是移動端的頁面資源不能太大,不然在惡劣網絡狀況下時,頁面將會沒法訪問 ,嚴重影響用戶體驗。
移動端上存在的300ms的延遲,在PC端是沒有的。
漸進加強:一開始就針對低版本瀏覽器進行構建頁面,完成基本的功能,而後再針對高級瀏覽器進行效果、交互、追加功能達到更好的體驗。
優雅降級:一開始就構建站點的完整功能,而後針對低版本瀏覽器測試和修復。
NodeJS 處理併發的能力強,但處理計算和邏輯的能力反而很弱。
所以,咱們把複雜的邏輯運算搬到前端(客戶端)完成,而 NodeJS 只須要提供異步 I/O,這樣就能夠實現對高併發的高性能處理。
這是 NodeJS 最理想的應用場景,能夠處理數萬條鏈接,自己沒有太多的邏輯,只須要請求 API,組織數據進行返回便可。
它本質上只是從某個數據庫中查找一些值並將它們組成一個響應。
因爲響應是少許文本,入站請求也是少許的文本,所以流量不高,一臺機器甚至也能夠處理最繁忙的公司的 API 需求。
實時聊天、客戶端邏輯強大的單頁 APP,具體的例子好比說:本地化的在線音樂應用,本地化的在線搜索應用,本地化的在線 APP 等。
Apache 因爲其多線程高併發共享內存地址空間的特性,那就意味着若是服務器足夠強大,處理器足夠高核,Apache 的運做將會很是良好,因此適用於(併發)異步處理相對較少,後臺計算量大,後臺業務邏輯複雜的應用程序。
優勢:高併發(最重要的優勢)、適合 I/O 密集型應用
缺點:
不適合CPU密集型應用(CPU密集型應用給Node帶來的挑戰主要是:因爲JavaScript單線程的緣由,若是有長時間運行的計算(好比大循環),將會致使 CPU 時間片不能釋放,使得後續 I/O 沒法發起)
只支持單核CPU,不能充分利用CPU
可靠性低,一旦代碼某個環節崩潰,整個系統都崩潰 緣由:單進程、單線程 解決方案: (1)Nnigx 反向代理,負載均衡,開多個進程,綁定多個端口; (2)開多個進程監聽同一個端口,使用cluster模塊 (3)線上使用 PM2 管理進程,出現問題自動重啓項目
Debug 不方便,錯誤沒有 stack trace
html5 websocket
WebSocket 經過 Flash
XHR長時間鏈接
XHR Multipart Streaming
不可見的Iframe
var EventUtil = { //根據狀況分別使用dom2 || IE || dom0方式 來添加事件 addHandler: function(element,type,handler) { if(element.addEventListener) { element.addEventListener(type,handler,false); } else if(element.attachEvent) { element.attachEvent("on" + type,handler); } else { element["on" + type] = handler; } }, //根據狀況分別獲取DOM或者IE中的事件對象,事件目標,阻止事件的默認行爲 getEvent: function(event) { return event ? event: window.event; }, getTarget: function(event) { return event.target || event.srcElement; }, preventDefault: function(event) { if(event.preventDefault) { event.preventDefault(); } else { event.returnValue = false; } } //根據狀況分別使用dom2 || IE || dom0方式 來刪除事件 removeHandler: function(element,type,handler){ if(element.removeHandler) { element.removeEventListener(type,handler,false); } else if(element.detachEvent) { element.detachEvent("on" + type,handler); } else { element["on" + type] = null; } } //根據狀況分別取消DOM或者IE中事件冒泡 stopPropagation: function(event) { if (event.stopPropagation) { event.stopPropagation(); } else { event.cancelBubble = true; } } } var btn = document.getElementById("myBtn"), handler = function () { alert("Clicked"); }; EventUtil.addHandler(btn,"click",handler); EventUtil.removeHandler(btn,"click",handler);
Set數據結構相似數組,但全部成員的值惟一。
let a = new Set(); [1,2,2,1,3,4,5,4,5].forEach(x=>a.add(x)); for(let k of a){ console.log(k) }; // 1 2 3 4 5
基本使用
let a = new Set([1,2,3,3,4]); [...a]; // [1,2,3,4] a.size; // 4 // 數組去重 [...new Set([1,2,3,4,4,4])];// [1,2,3,4]
方法
add(value):添加某個值,返回 Set 結構自己。
delete(value):刪除某個值,返回一個布爾值,表示刪除是否成功。
has(value):返回一個布爾值,表示該值是否爲Set的成員。
clear():清除全部成員,沒有返回值。
let a = new Set(); a.add(1).add(2); // a => Set(2) {1, 2} a.has(2); // true a.has(3); // false a.delete(2); // true a => Set(1) {1} a.clear(); // a => Set(0) {}
//利用for嵌套for,而後splice去重 function unique(arr){ for(var i=0; i<arr.length; i++){ for(var j=i+1; j<arr.length; j++){ if(arr[i]==arr[j]){ //第一個等同於第二個,splice方法刪除第二個 arr.splice(j,1); j--; } } } return arr; } var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}]; console.log(unique(arr))
apply、call 都是能夠改變 this 的指向的,
apply 和 call 的區別是 call 方法接受的是若干個參數列表,而 apply 接收的是一個包含多個參數的數組。
// apply var a ={ name : "Cherry", fn : function (a,b) { console.log( a + b) } } var b = a.fn; b.apply(a,[1,2]) // 3
// call var a ={ name : "Cherry", fn : function (a,b) { console.log( a + b) } } var b = a.fn; b.call(a,1,2) // 3
爲了提供查詢的性能,會將查詢後的數據放到內存中進行緩存,下次查詢時,直接從內存緩存直接返回,提升響應效率。
代理服務器緩存
代理服務器是瀏覽器和源服務器之間的中間服務器,瀏覽器先向這個中間服務器發起Web請求,通過處理後(好比權限驗證,緩存匹配等),再將請求轉發到源服務器。代理服務器緩存的運做原理跟瀏覽器的運做原理差很少,只是規模更大。能夠把它理解爲一個共享緩存,爲大量用戶提供服務,所以在減小相應時間和帶寬使用方面頗有效,同一個副本會被重用屢次。
CDN緩存
CDN緩存,也叫網關緩存、反向代理緩存。CDN緩存通常是由網站管理員本身部署,爲了讓他們的網站更容易擴展並得到更好的性能。瀏覽器先向CDN網關發起Web請求,網關服務器後面對應着一臺或多臺負載均衡源服務器,會根據它們的負載請求,動態將請求轉發到合適的源服務器上。雖然這種架構負載均衡源服務器之間的緩存無法共享,但卻擁有更好的處擴展性。從瀏覽器角度來看,整個CDN就是一個源服務器。
瀏覽器緩存是瀏覽器端保存數據用於快速讀取或避免重複資源請求的優化機制,有效的緩存使用能夠避免重複的網絡請求和瀏覽器快速地讀取本地數據,總體上加速網頁展現給用戶。
應用層緩存指的是從代碼層面上,經過代碼邏輯和緩存策略,實現對數據,頁面,圖片等資源的緩存,能夠根據實際狀況選擇將數據存在文件系統或者內存中,減小數據庫查詢或者讀寫瓶頸,提升響應效率。
200 OK 客戶端請求成功
301 Moved Permanently 請求永久重定向
302 Moved Temporarily 請求臨時重定向
304 Not Modified 文件未修改,能夠直接使用緩存的文件。
400 Bad Request 因爲客戶端請求有語法錯誤,不能被服務器所理解。
401 Unauthorized 請求未經受權。這個狀態代碼必須和WWW-Authenticate報頭域一塊兒使用
403 Forbidden 服務器收到請求,可是拒絕提供服務。服務器一般會在響應正文中給出不提供服務的緣由
404 Not Found 請求的資源不存在,例如,輸入了錯誤的URL
500 Internal Server Error 服務器發生不可預期的錯誤,致使沒法完成客戶端的請求。
503 Service Unavailable 服務器當前不可以處理客戶端的請求,在一段時間以後,服務器可能會恢復正常。
JSONP跨域
跨域資源共享(CORS)
nginx代理跨域
Nodejs中間件代理跨域
WebSocket 協議跨域
document.domain + iframe 跨域
location.hash + iframe跨域
window.name + iframe跨域