2017-04-20 1 views
0

以下は、Webサーバーです。`lib.js`が読み込まれて評価されるまで、ブラウザ内で次のブロックが表示されるのはなぜですか?

http://localhost:3000/にアクセスした場合、ブラウザブロックはlib.jsがロードされ評価されるまでブロックされます。

なぜですか?

言い換えれば、app.jsがブラウザで実行されないのはなぜですか?lib.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,() => {}); 

編集:この後者の方法でスクリプトを挿入することは非同期で、ドスは、文書の評価をふさがないので

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>`; 

エラーで結果:

がでpageの交換。

答えて

2

lib.jsをロードするスクリプト要素は、app.jsをロードするスクリプト要素の前にDOMに表示されます。

スクリプト要素にdocument.writeステートメントが含まれている可能性があるため、すべてのスクリプト要素は明示的にdeferまたはasyncとマークされていない限り、DOM解析をブロックします。

+0

これは 'document.write'に特有のものですか? 'const el = document.createElement( 'script');ので、 el.src = "./ foo.js"; $( 'body).appendChild(el); 'はブロックされません。 – Ben

+0

@BenAston - これはスクリプトをまったく追加しません。 body要素はまだ存在しません。 – Quentin

+0

appendを 'document.currentScript.parentNode.insertBefore(el、document.currentScript);に変更したのはどうですか?これはブロックされず、 'window.lib'が定義されていないので' app.js'が例外をスローします。 – Ben

関連する問題