做者:Jogis
原文連接:https://github.com/yesvods/Bl...
轉載請註明原文連接以及做者信息react
在你們的認知裏,JSONP,每每是另一種異步請求的方式,其主要優勢是支持跨域數據請求。所以,JSONP每每是將一個Script節點動態插入document,隨後瀏覽器會自動發起一個遠程請求。git
除了上述單一用法外,在PCWeb,JSONP具備很是巨大的性能&工程化價值。github
經過【圖說舌尖上的腳本】與【同步vs異步加載】瞭解到,PCWeb受限於插件環境,異步機制變得很是不吃香。異步發起的請求,不管是JSONP等資源加載,抑或XHR(fetch),都會被標記爲低優先級。跨域
同步插件腳本加載完才能發起請求瀏覽器
在主進程的編譯與執行前,會被插件腳本搶佔。緩存
咱們來看一下,發起6個異步JSONP是怎樣的狀況:網絡
<script> function appendScript(src){ var s = document.createElement('script') s.src = src document.body.appendChild(s) } for(let i=0;i<6;i++){ appendScript(`./react.js?v=${i}`) } </script>
結果跟以前分析的異步請求別無二致,異步JSONP默默低下了頭。app
舉個栗子,在實際PC場景,不管採用的是React Or Vue Or what ever. 咱們都須要在渲染前加載一堆組件,數據+模板(JSX etc.)+組件方式,來實現渲染。咱們在渲染頁面前就須要加載一堆資源,有時候甚至能夠達到2M之大!異步
這塊大資源並無錯(有時候利用一塊大資源,比起每次加載不同非緩存資源性能還高),可是在瀏覽器加載這塊大頭時候,腳本的解析、編譯、執行,也隨着體積增加(特別是執行耗時)。固然,這也有一些辦法能夠減輕這些負擔(未完,待續..)。然而,咱們能夠利用上面介紹到的同步JSONP優雅地減小頁面加載時間!咱們先來回顧一下部分原理:性能
由於主線程被阻礙了,後面的解析工做沒有辦法繼續往下進行, 當遇到這種狀況,WebKit會啓動另一個線程去遍歷後面的HTML, 收集須要的資源URL,而後發送請求,這樣就能夠避免阻塞。 ———— 《WebKit技術內幕》
咱們把資源都當作一個大致積Bundle,在HTML解析到這個腳本時,因爲無需下載(memory cached Or disk cached),接下來就是漫長的解析、編譯、執行。可是,咱們可不能讓瀏覽器閒着,經過同步JSONP,在Bundle後面聲明一堆之後渲染要用的頁面數據。這樣,瀏覽器主進程漫長的阻塞執行過程當中,相關的數據已經被網絡模塊準備就緒,因爲模塊數據相對體積小,所以沒有解析/編譯/執行成本。
<script src="BigBundle.js"></script> <script src="parallelData1.js"></script> <script src="parallelData2.js"></script> <script src="parallelData3.js"></script> <script src="parallelData4.js"></script> <script src="parallelData5.js"></script> <script src="parallelData6.js"></script>
咱們一直提到的是,在PCWeb頁面初始化場景,異步加載都會面臨性能問題。而上述的方案經過全部資源同步的方式實現,用最高優先級來渲染初始頁。
在鄙人的某些業務場景下,真實用到同步加載Bundle,異步獲取資源,首屏渲染時間慘不忍睹。僅僅經過資源JSONP同步化,還沒作其餘優化?,首屏時間直接從2.1s,降低至1.4s?。