最近作的一個項目須要引入一個外部的第三方js腳本。因爲這是一個關於渲染3D建築的腳本,因此體積比較大,大概有2M,加載完成也得要個好幾秒,網速慢的時候十幾秒都有可能。
以前也遇到腳本加載慢的問題,可是沒這麼慢,因此此次就特別寫個文章記錄一下個人解決過程。html
下圖是經過第三方腳本渲染出來的3D建築頁面html5
下圖是首頁,不須要用到第三方腳本dom
我一開始經過<script>標籤直接引入到入口文件的頭部,以下
`
<head>異步
<script src="./DDEarth.js"></script>
</head>
`
這樣頁面是能夠正常加載的,可是頁面出來的很慢,一開始會白屏一段時間等待這個js腳本加載完成。雖然腳本體積大是事實,但這用戶體驗確定是能夠優化的。
後來我又把這個腳本放到了頁面底部,也就是</body>標籤下面。這樣能夠先讓頁面渲染出來,再慢慢加載這個龐大的腳本,因而首頁是出來的很快,可是從首頁跳轉到須要用到這個腳本的頁面就會報錯,以下async
這個錯誤緣由是這個頁面須要用到window.DDEarth這個對象,可是因爲此時這個腳本尚未加載完成,因此window下並無這個對象,因此就報錯了。優化
因而我又想到等腳本加載完成再執行相關方法,這時就須要用到onload這個方法了,onload這個方法在腳本加載完成的時候會執行。我引入腳本的時候給它加了個id,方便之後經過dom找到,代碼以下:this
// 入口文件 </body> <script id="ddEarthScript" src="./DDEarth.js"></script> // PageTwo.js componentDidMount() { const scriptEle = document.getElementById('ddEarthScript'); // 找到腳本節點 if (scriptEle) { scriptEle.onload = () => { // 腳本加載完成執行加載地圖的操做 this.loadEarthMap(); }; } }
有了以上代碼我跳轉到PageTwo這個頁面的時候,會等到DDEarth.js這個腳本加載完成,再執行加載建築地圖的操做,這樣就不會報錯了。
可是這又有一個問題,就是若是我跳轉到PageTwo的以前,DDEarth.js已經加載完成了,onload這個事件在PageTwo這個頁面中就不生效了,loadEarthMap這個方法天然也就不會執行了。
這個時候須要加一個判斷,完整代碼以下:spa
// PageTwo.js componentDidMount() { if (window.DDEarth) { // 若是跳轉到此頁面以前,腳本已加載完成 this.loadEarthMap(); } else { const scriptEle = document.getElementById('ddEarthScript'); if (scriptEle) { scriptEle.onload = () => { this.loadEarthMap(); }; } } }