国产九色porn网址_亚洲综合伊人_91麻豆精品视频_免费吸乳羞羞网站视频

您好,微網歡迎您! 登錄  |  注冊
汕頭公司 |  深圳公司              咨詢熱線:400-830-8248               微網優點  |  視頻介紹 |  服務支持
開店咨詢
咨詢電話:400-830-8248
微網商學院
中國第一微商學院
網絡商學院
首頁 > 微信商城
美團點評CEO王興:送外賣機器人將很快出現
文章出處:http://www.yixieshi.com/80147.html  更新時間:2017-04-20  點擊率:
美團點評CEO王興:送外賣機器人將很快出現-互聯網的一些事

導讀:BigPipe是服務器chunked輸出html內容,BigRender是服務器一次性輸出的,究竟淘寶商品詳情頁的BigRender方式是如何效仿Facebook的BigPipe方式的?存放大塊HTML代碼的最佳方式又是什么?文中為您揭曉答案。

內容如下:

對于復雜頁面,為了將用戶關注的內容盡可能快渲染出來,至少有兩種方式:

一、Facebook的BigPipe方式。

先輸出頁面整體布局,然后逐步輸出腳本塊,一邊輸出一邊執行,將內容渲染回頁面布局中。這樣可以讓服務端的運算、網絡傳輸和瀏覽器端的渲染變成并行。BigPipe最主要解決的問題是服務端的運算時間,當服務端的運算時間大于300~500ms時才能體現出優勢。當服務端響應非常快(小于100ms),BigPipe退化為下面要講的BigRender.

二、淘寶商品詳情頁的BigRender方式。

淘寶的商品詳情頁,服務端平均響應時間為52ms,采用BigPipe chunked輸出意義不大。這次優化主要在瀏覽器端。頁面下載完畢后,要經過Tokenization---Tree Construction—Rendering。要讓首屏盡快出來,得給瀏覽器減輕渲染首屏的工作量。可以從兩方面入手:

減少DOM節點數。節點數越少,意味著Tokenization, Rendering等操作耗費的時間越少。(對于典型的淘寶商品詳情頁,經測試發現,每增加一個DOM節點,會導致首屏渲染時間延遲約0.5ms.)

減少腳本執行時間。腳本執行和UI Update共享一個thread,腳本耗的時間越少,UI Update就能越發提前。

減少首屏DOM節點數

對于BigPipe來說,初始輸出的只有頁面布局,DOM節點數不多。首屏的DOM節點數主要取決于首屏腳本塊中,字符串化的html代碼:

  1. big_pipe.onPageletArrive({ "content": { /* data */ } })   
  2.  

這種方式下,頁面中的DOM節點是逐步增加的。尚未渲染的DOM節點,不會影響TTI區域。

對于BigRender來說,減少DOM節點數的方式有:

和Facebook的BigPipe一樣,調整頁面代碼為頁面布局+腳本塊。BigPipe是服務器chunked輸出html內容,BigRender是服務器一次性輸出,其他都是一樣的。

盡量少調整頁面代碼,但通過某種方式,將首屏不需要的html代碼先存放起來。渲染好首屏后,再將存儲好的html代碼逐步渲染出來。

用js字符串來存放html代碼

最容易想到的一種方式是學習Facebook好榜樣,用js字符串來存放:

  1. <script>   
  2.  
  3. var data = "<p>some data</p>...";   
  4.  
  5. </script>   

這種方式對于BigRender來說,并不是很好:

1.由于存放在js字符串變量中,需要對雙引號或單引號轉義。

2.由于script是內嵌的,需要對script ETAGO轉義。

3.服務器端需要將html代碼轉化為一行。(也可以不轉成一行,用續行符來做。)

4.當html代碼中含有script時,需要先去除script中的單行注釋,否則轉化成一行時,會出問題。這一步,看似簡單,實際上很不容易,特別是對于淘寶旺鋪這種有第三方代碼的情況。(移除注釋的方法可以參考:Simple but Safe Comment Removal, 使用正則的方式很難做到0 bug,不用正則的話,需要引入html parser和javascript parser,效率更低。)

把代碼規范做好,把校驗工作做好,再加上預處理和緩存,js字符串的方式也是非常不錯的。但對于淘寶詳情頁來說,目前用js字符串的方式需要做的改動比較多,增加的服務器消耗不少,不是很合適。

我們這次優化的目標是:

1.大幅度減少首屏渲染時間。

2.盡量不改變原有開發習慣。

3.用盡量少的代碼做盡量多的優化。

用注釋來存放html代碼

為了便于獲取注釋內容,添加一層包裹:

  1. <div id="comment-data"><!--   
  2.  
  3. html code   
  4.  
  5. --></div>   

這樣,獲取代碼很簡單:

  1. var htmlCode = document.getElementById('comment-data').  
  2. childNodes[0].nodeValue;  
  3.  

缺點是:

1.服務端,html中的-->要替換為某種特殊標記。(不能簡單轉義為--&gt;)

2.服務端,html中的--也要替換為某種特殊標記。否則在Firefox低版本中存在bug.

3.瀏覽器端,得到html Code后,要將上面的特殊標記替換回原值。

當html code很大時,替換的效率不高。依賴特殊標記的替換理論上也不完美。

還有什么存放方式呢?

HTML的元素類型

HTML元素分為五大類:

  1. Void elements。像hr,br,base這種。
  2. Raw text elements。有兩個:script和style.
  3. RCDATA elements。也有兩個:textarea和title.
  4. Foreign elements。來自MATHML和SVG的元素。
  5. Normal elements。除了以上四種類型之外的所有元素,比如p,div,iframe等。

顯然,Void elements和Foreign elements不適合用來存放html代碼。

對于Normal elements,里面的<字符會被當做tag open來解析,有一個方式是通過display:none來避免渲染。

  1. <div style="display:none"> 
  2.  
  3. html code   
  4.  
  5. </div>   

這樣做,減少的只是可見的DOM節點數,DOM總數依舊不變。Tokenization — Tree Construction等操作的耗時并沒減少。

我們將重點放到Raw text elements和RCDATA elements上來。

CDATA,PCDATA和RCDATA

先了解下CDATA(Character Data) 的相關知識點。

在XML中,不包含子元素的元素的內容默認必須是PCDATA(Parsed Character Data):

  1. <data>&lt;p&gt;some text&lt;/p&gt;</data>   

“Parsed”是指<和&字符要轉換成&lt;和&amp;實體字符形式。如果不想寫一大堆&xx;,可以直接標記為CDATA:

  1. <data><![CDATA[<p>some text</p>]]></data>   

這是XML的習慣,很嚴格,但對用戶并不友好。在HTML中,如果要兼容XML,得像如下一樣:

  1.  <script>   
  2.  
  3.  //<![CDATA[   
  4.  
  5.  var t = "<p>";   
  6.  
  7.  //]]>   
  8.  
  9. </script>   
  10.  

增加的<![CDATA]很無聊。script中本就是CDATA.

為了讓用戶更舒心,讓代碼更自然,HTML將script和style定義為Raw text elements。也就是說,這兩個元素里面的內容是raw text,里面出現的>就表示>字符本身,不會被當作tag open來解析;&gt;也不會根據實體字符來轉義,就表示&gt;字串自身。這就是CDATA.

Raw text elements有一個限制:里面的內容不能有自身的ETAGO標記,也就是說,script里的內容不能含有</script(\s|\\|>),否則就會導致script提前結束:

  1. <script>   
  2.  
  3.  document.write('<script>alert("O HAI")</script>');   
  4.  
  5.  </script> 

上面的代碼會出錯,必須打破&lt/script組合:

  1. <script>   
  2.  
  3. 2 // Using string concatenation:   
  4.  
  5. 3 document.write('<script>alert("heh")<' + '/script>'); // Lame.   
  6.  
  7. 4 // Using a string literal escape:   
  8.  
  9. 5 document.write('<script>alert("huh")<\x3Cscript>'); // Lame.   
  10.  
  11. 6 // Simply escaping the solidus character with a reverse solidus (\):   
  12.  
  13. 7 document.write('<script>alert("O HAI")<\/script>'); // Awesome!   
  14.  
  15. </script>   
  16.  

style也類似,不多說。

除了Raw text elements,還有RCDATA elements。我們來看看。

RCDATA(Replaceable Character Data)表示里面可以有&xx;等實體字符,也可以包含<字符而不會被當作tag open來解析。比如:

  1. 1<textarea><p>&lt;</p></textarea> 
  2.  

在RCDATA里,&lt;可替換為<(Replaceable的含義),拿到值(比如textarea.value)后,是無從得知源碼里是否有&lt;等實體字符的。

用script來存放html代碼

回到正題。在Raw text elements里,可以用script來存放數據:

  1. <script type="text/html" id="script-data">   
  2.  
  3. <p>some text</p>   
  4.  
  5. </script>   
  6.  

獲取也很簡單:

  1. var htmlCode = document.getElementById('script-data').innerHTML;   

這個方案比用注釋來存放的方案更好,但依舊存在以下缺點:

服務端,要將script里html中的</script替換為某種特殊標記。

瀏覽器端,得到htmlCode后,要將上面的特殊標記替換回原值。

注意:特殊標記不能是<\/script,因為有可能存在以下代碼:

  1. <script type="text/html" id="script-data">   
  2.  
  3. <script>   
  4.  
  5. 3 var str = '<\/script>';   
  6.  
  7. <\/script>   
  8.  
  9. </script>   
  10.  

這樣替換回原值時,會誤傷str字符串。

用textarea來存放html代碼

textarea中的內容會按照RCDATA規則來解析:

遇到&時,會盡可能得到實體字符。

遇到</textarea(\s|\\|>)時,會結束解析。

其他都直接作為textarea的內容。

  1. <textarea id="area-data">   
  2.  
  3. <p>some text</p>   
  4.  
  5. </textarea>   
  6.  

獲取非常簡單:

  1. 1 var htmlCode = document.getElementById('area-data').value;   
  2.  

缺點:

服務端,要將html中的&轉義成&amp;

服務端,要打破ETAGO,將</textarea轉義成&lt;/textarea

優點很明顯,在瀏覽器端,只需通過textarea.value取值即可,無需進行任何轉義替換操作。

并且理論上不會出現任何bug.

存放大塊HTML代碼的最佳方式

經過上面的分析,結果已經很明顯,用RCDATA elements來存放數據是最妥當的。title元素明顯不合適,因此最后的選擇就剩下一個了:textarea并且從語義上講,用 text area來存放html text也說得過去。

回到首屏渲染優化

可以根據實際情況,將頁面劃分成幾大區域。非首屏區域,簡單轉義后,直接用textarea包裹起來。這樣,DOM數立刻就減少了。瀏覽器在拿到html代碼時,首次 Tokenization — Tree Construction的速度就會大大加快。

完整的優化,還需要:

給瀏覽器合理的喘息(UI Update)時間,等首屏真正在顯示器上繪制出來后,再進行下一步操作。

得到textarea.value,填充回DOM樹時,得妥善處理內嵌的script代碼。

對內嵌script代碼中的document.write要妥善處理。

通過textarea回填,里面的非defer和async腳本會從同步變成異步。要妥善處理依賴關系,不破壞原有腳本邏輯。

對于優化項目來說,完備的測試和監控非常重要。

這次還做了AssetsTransfer。用戶第一次訪問時,會將首屏相關的腳本和樣式內嵌,并做預加載。用戶再次訪問時,則改成外鏈方式,這樣能充分利用瀏覽器緩存,并減少 html傳輸量。

最后,給一張優化成果圖: 

這是一個典型的淘寶詳情頁的首屏時間趨勢圖。可看出,首屏時間從優化前的3s降低到了優化后的1.5s左右,快了一倍!

更深度的優化需要對頁面內容(包括腳本)做進一步的細粒度模塊化,區分出優先級,然后根據需求,靈活自由地控制各個模塊的下載和執行等等。

這篇博客寫得比較雜,關于BigRender優化的更多細節,以后有機會再細說。歡迎反饋、拍磚。歡迎業界各位朋友嘗試BigRender優化,希望國內的站點速度都越來越快!


文章轉載于:http://www.yixieshi.com/80147.html

聲明:本網部份文章為轉載文章,在每篇文章底部有說明,文章的觀點和立場僅代表作者個人立場,不代表微網立場,若是文章轉載中有侵范您的權益,請發郵件到 493149@qq.com或致電13922854199通知刪除,謝謝!

QQ咨詢  技術總監  微網顧問  陳經理  渠道經理  

免費電話 免費熱線:400-830-8248  

微信咨詢  

注冊開店

代理加盟

返回頂部