2017-04-20 41 views
0

接下來是一個Web服務器。爲什麼在加載和評估`lib.js`之前,瀏覽器中的以下塊?

當訪問http://localhost:3000/時,瀏覽器會阻塞,直到加載並評估lib.js

爲什麼?

換句話說:爲什麼app.jslib.js之前沒有在瀏覽器中運行?

var express = require('express'); 
var app = express(); 

const page = `<html> 
<head> 
    <script> 
     document.write('<scr' + 'ipt src="./lib.js"></scr' + 'ipt>'); 
    </script> 
    <script src="./app.js"></script> 
</head> 
</html>`; 

const libJs = `window.lib = function() { console.log('the library is loaded!'); };`; 
const appJs = `window.lib();`; 

app.get('/', (req, res) => { 
    res.send(page) 
}); 

app.get('/lib.js', (req, res) => setTimeout(() => res.send(libJs), 10000)); 

app.get('/app.js', (req, res) => res.send(appJs)); 

app.listen(3000,() => {}); 

編輯:

與更換page

const page = `<html> 
<head> 
    <script> 
     const el = document.createElement('script'); 
     el.src="./lib.js"; 
     document.currentScript.parentNode.insertBefore(el, document.currentScript); 
    </script> 
    <script src="./app.js"></script> 
</head> 
</html>`; 

結果錯誤,因爲在後一種方式插入腳本是異步和DOS不阻止文檔的評估。

回答

2

加載lib.js的腳本元素出現在加載app.js的腳本元素之前的DOM中。

由於腳本元素可能包括document.write聲明,所有的腳本元素將阻止DOM解析,除非它們被明確標記deferasync

+0

所以這是'document.write'特有的?因爲'const el = document.createElement('script'); el.src = 「./ foo.js」; $('body).appendChild(el);'不會阻塞。 – Ben

+0

@BenAston - 根本不會添加腳本。 body元素尚不存在。 – Quentin

+0

如果我改變附加到'document.currentScript.parentNode.insertBefore(el,document.currentScript);'?這不會阻塞,並會導致'app.js'拋出一個異常,因爲'window.lib'沒有被定義。 – Ben

相關問題