話說兩週前,我發了這樣一條沸點:html
因而我真的就建羣收集了題目,和團隊的同事一塊兒寫答案,咱們也不圖什麼,就是想作一件有意義的事情,如今我整理了下咱們的回答,有的不必定就是很是具體的回答,但也提供了思路和參考資料,你們看看是否還有什麼補充的?前端
和服務端保持鏈接,最簡單粗暴的方法就是經過請求輪詢保持跟服務端的通訊,客戶端不光要花成本維護定時輪詢器,還會使得服務器壓力變大,因此不推薦。vue
還有一種能夠藉助請求超時的設置,將超時時間設置一個足夠大的值,客戶端發起鏈接後,只要服務端不返回消息,整個鏈接階段都會受到阻塞,因此這種方式也不推薦。react
最後一種是WebSocket,當服務器完成協議從HTTP到WebSocket的升級後,服務端能夠主動推送信息給客戶端,解決了輪詢形成的同步延遲問題。因爲 WebSocket 只須要一次 HTTP 握手,服務端就能一直與客戶端保持通訊,直到關閉鏈接,這樣就解決了服務器須要反覆解析 HTTP 協議,減小了資源的開銷。webpack
這個問題能夠拓展講成 JavaScript 中的類型轉換,分爲兩類,顯式類型轉換和隱式類型轉換,當咱們用 Number() 等函數的時候,就是顯式類型轉換,其轉換規則是當是基本類型時,參照規範中的對應表進行轉換,當不是基本類型的時候,先參照規範中的 ToPrimitive
方法轉換爲基本類型,再按照對應錶轉換,當執行 ToPrimitive 的時候,又會根據狀況不一樣,判斷先執行對象的 valueOf 方法仍是 toString 方法進行準換,這個能夠參照 JavaScript 深刻之頭疼的類型轉換(上),而當咱們進行運算的時候,常常發生的就是隱式類型轉換,好比 +
和 ==
運算符,當 + 運算符的時候,更傾向於轉成字符串,而當 ==
的時候,更傾向於轉爲數字,這個在 JavaScript 深刻之頭疼的類型轉換(下)中會講到……可是我還在寫……總之,回答類型轉換的時候,最好是扯到規範中,代表你在研究這塊內容的時候,還專門去看過規範。基本上回答了這裏,對類型轉換說明已經有不少的瞭解,但你能夠再拓展講一下,好比當時我在學習類型轉換的時候,還專門去研究瞭如何花式表示 26 個字母,好比在控制檯打印這樣一句話:git
[[][0] + []][0][5]+[[][[[][0] + []][0][4]+[[][0] + []][0][5]+[[][0] + []][0][1]+[[][0] + []][0][2]] + []][0][8]+[[[] == []][0] + []][0][2]+[[][[[][0] + []][0][4]+[[][0] + []][0][5]+[[][0] + []][0][1]+[[][0] + []][0][2]] + []][0][6]+[[][[[][0] + []][0][4]+[[][0] + []][0][5]+[[][0] + []][0][1]+[[][0] + []][0][2]]+[]][0][23]+[[][0] + []][0][3]+[[][[[][0] + []][0][4]+[[][0] + []][0][5]+[[][0] + []][0][1]+[[][0] + []][0][2]] + []][0][8]+[+[1 + [[][0] + []][0][3] +309][0] + []][0][7]+[[][[[][0] + []][0][4]+[[][0] + []][0][5]+[[][0] + []][0][1]+[[][0] + []][0][2]] + []][0][6]+[[][0] + []][0][0] 複製代碼
花式表示字母的原理你們也能夠探索一下,雖然看起來很無聊,但能夠做爲一個小案例,代表下你對技術的鑽研和興趣。github
這個問題的核心是在問從輸入URL到頁面渲染經歷了哪些過程。web
從耗時過程來看,能夠分爲DNS解析、TCP鏈接、HTTP請求與響應、客戶端瀏覽器解析渲染、鏈接結束。其中瀏覽器解析渲染包含HTML詞法、語法的解析、CSS解析、DOM樹生成、渲染樹創建、屏幕繪製。npm
下面針對幾個較爲重要的過程作下介紹。api
當咱們在瀏覽器中輸入如www.taobao.com
的時候,DNS解析充當了一個翻譯的角色,把網址「翻譯」成了IP地址。DNS解析的過程就是域名到IP地址的轉換的過程。域名解析也叫域名指向、服務器設置、域名配置以及反向IP登記等等。說得簡單點就是將好記的域名解析成IP,服務由DNS服務器完成,把域名解析到一個IP地址,而後在此IP地址的主機上將一個子目錄與域名綁定。
TCP鏈接的重要目的,是爲了保證消息的有序和不丟包,爲了創建可靠的數據傳輸,TCP通訊雙方相互告知初始化序列號,並肯定對方已經收到ISN的,整個連接的過程就是咱們俗稱的三次握手
。
HTTP請求它主要發生在客戶端,發送HTTP請求的過程就是構建HTTP請求報文並經過TCP協議發送到服務器指定端口的過程。
仍是用 www.taobao.com 舉例子。
當在地址欄輸入後,瀏覽器會分析這個url,並設置好請求報文發出。請求報文中包括請求行(包括請求的方法,路徑和協議版本)、請求頭(包含了請求的一些附加的信息,通常是以鍵值的形式成對存在)、空行(協議中規定請求頭和請求主體間必須用一個空行隔開)、請求主體(對於post請求,所須要的參數都不會放在url中,這時候就須要一個載體了,這個載體就是請求主體)。服務端收到這個請求後,會根據url匹配到的路徑作相應的處理,最後返回瀏覽器須要的頁面資源。處理後,瀏覽器會收到一個響應報文,而所須要的資源就就在報文主體上。與請求報文相同,響應報文也有與之對應的起始行(響應報文的起始行一樣包含了協議版本,與請求的起始行不一樣的是其包含的還有狀態碼和狀態碼的緣由短語)、響應頭(對應請求報文中的請求頭,格式一致,可是各自有不一樣的首部)、空行、報文主體(請求所須要的資源),不一樣的地方在於包含的東西不同。
對咱們來講HTML實際上是一坨字符串,而實際上咱們要面對的是"字符流"。爲了把字符流解析成正確的可被瀏覽器識別的結構,咱們須要作的事情分爲兩步:
詞法分析:把字符流初步解析成咱們可理解的"詞",學名叫token。
語法分析:把開始結束標籤配對、屬性賦值好、父子關係鏈接好、構成dom樹。
html結構其實不算太複雜,咱們平時見到的大部分都只是標籤、屬性、註釋、CDATA節點。
DOM樹的生成和渲染樹創建比較好理解這個就不作展開。完成了這「兩棵樹」的構造後,就進入屏幕繪製階段。
在繪製的過程當中,會遍歷渲染樹,調用由瀏覽器的UI組件的paint()方法在屏幕上顯示對應的內容,並根據渲染樹佈局,計算CSS樣式(即每一個節點在頁面中的大小和位置等幾何信息)。
HTML默認是從上到下流式佈局的,CSS和JS的加入會打破這種佈局,改變DOM的外觀樣式以及大小和位置。這就引出兩個很是重要的概念:replaint重繪和reflow重排。
replaint重繪,屏幕的一部分從新繪製,不影響總體佈局,好比某個CSS的背景色變了,但元素的幾何尺寸和位置不變。eflow重排: 意味着元件的幾何尺寸變了,咱們須要從新驗證並計算渲染樹。是渲染樹的一部分或所有發生了變化。不管是重繪仍是重排,對瀏覽器而言都是一種「消耗」,因此咱們應該儘可能減小這兩種狀態的觸發。
CDN的基本原理是普遍採用各類緩存服務器,將這些緩存服務器分佈到用戶訪問相對集中的地區或網絡中,在用戶訪問網站時,利用全局負載技術將用戶的訪問指向距離最近的工做正常的緩存服務器上,由緩存服務器直接響應用戶請求。 最簡單的CDN網絡由一個DNS 服務器和幾臺緩存服務器就能夠組成,當用戶輸入URL按下回車,通過本地DNS系統解析,DNS系統會最終將域名的解析權交給CNAME指向的CDN專用DNS服務器,而後將獲得全局負載均衡設備的IP地址,用戶向全局負載均衡設備發送內容訪問請求,全局負載均衡設備將實時地根據網絡流量和各節點的鏈接、負載情況以及到用戶的距離和響應時間等綜合信息將用戶的請求從新導向離用戶最近的服務節點上,使用戶可就近取得所需內容,解決 Internet網絡擁擠的情況,提升用戶訪問網站的響應速度
通常從以下兩個方面考慮:
經過全局的接口,將捕獲代碼集中寫在一個地方,能夠利用的接口有:
在業務代碼中對單個代碼塊進行包裹,或在邏輯流程中打點,實現有針對性的異常捕獲:
注:詳情可參見Fundebug 發表的 《前端異常監控解決方案研究》
• 分屏加載,當頁面須要渲染的數據較多時,先渲染首屏,下滑時再加載第二屏的數據; • 圖片大小優化,在不影響視覺效果的前提下,把圖片尺寸降到最小; • 圖片懶加載,on appear時再加載圖片; • Code splitting,或者拆包,應用下的某些組件不須要馬上import,能夠採用動態import的方式,打包時也能夠將它們打到不一樣的bundle裏,給index bundle瘦身; • Chrome Devtools - Trace & Timeline等一系列強大的分析工具能夠去研究一下,它們能夠深刻到內核分析應用的性能問題所在;
這一塊建議去讀 webpack4 文檔中對於 library,libraryTarget 的描述。當咱們開發一個 JS 庫的時候,一般最終的 npm package 須要輸出的是一些組件或 api,這個時候咱們須要瞭解webpack4所提供的模塊化的打包能力。經過對libraryTarget的設置,咱們能夠將咱們的工程打包成amd,umd,或commonJS模塊。 webpack.js.org/configurati…
Node.js 中的進程 Process 是一個全局對象,無需 require 直接使用,給咱們提供了當前進程中的相關信息。Node.js 中進程可使用 child_process 模塊建立。
關係:
區別:
這裏選擇的方法應該是節流,能夠拓展講到防抖和節流,防抖是指連續觸發的時候只會執行一次,中止觸發 N 秒後才能繼續執行,而節流是指若是你持續觸發事件,每隔一段時間,只執行一次事件。像防止按鈕屢次點擊就用防抖,像是監聽滾動事件就用節流,函數實現均可以參照 underscore 代碼中的實現,之前我寫過 JavaScript專題之跟着underscore學防抖 和 JavaScript專題之跟着 underscore 學節流 兩篇文章講述了 underscore 中的實現方式