開始的流程:
1、先發請求給DNS進行域名解析獲取服務器IP
2、向步驟1獲取的服務器IP發送HTTP請求
//服務器的內部處理
3、服務器接收請求后,解析主機頭對應的站點,把請求傳送給站點
//返回http
4、站點接受轉發的請求作出回應并返回HTTP回應
//解析頭部
5、瀏覽器接到返回的HTTP回應,解析頭信息和HTML主體
6、根據解析的頭信息設置必要的數據,如cookie,編碼,語言等聲明的處理
7、在6的基礎上對HTML主體進行渲染展現;
這個是別人的并發測試;
nodeJS的代碼:

var express = require('express'); var path = require('path'); var favicon = require('serve-favicon'); var logger = require('morgan'); var cookieParser = require('cookie-parser'); var bodyParser = require('body-parser'); var routes = require('./routes/index'); var users = require('./routes/users'); var app = express(); // view engine setup app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'jade'); // uncomment after placing your favicon in /public //app.use(favicon(__dirname + '/public/favicon.ico')); app.use(logger('dev')); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false })); app.use(cookieParser()); app.use('/', function(req, res, next) { setTimeout(function(){ next(); },10000); }); app.use(express.static(path.join(__dirname, 'public'))); app.use('/', routes); app.use('/users', users); // catch 404 and forward to error handler app.use(function(req, res, next) { var err = new Error('Not Found'); err.status = 404; next(err); }); // error handlers // development error handler // will print stacktrace if (app.get('env') === 'development') { app.use(function(err, req, res, next) { res.status(err.status || 500); res.render('error', { message: err.message, error: err }); }); } // production error handler // no stacktraces leaked to user app.use(function(err, req, res, next) { res.status(err.status || 500); res.render('error', { message: err.message, error: {} }); }); require("http").createServer(app).listen(3000); module.exports = app;
我自己測試了下,chrome的結果是6個,對于圖片chrome會先請求加載一個, 后面再一個個加載, 目測一個域名下最多有6個是對的:
FF下的結果也一樣,不過對于圖片請求處理和chrome有點區別:
因為瀏覽器的并發也是有最大值的, 所以把服務器的圖片放到同服務器的的二級域名下,那么就可以突破瀏覽器6個的并發限制, 請求會變成N倍,是hack ,已親測;
首先,瀏覽器要把當前界面進行unload, unload的時間要看當前界面的HTML;
然后,瀏覽器從DOM開頭由上到下步步渲染,link以及script依次加載和執行繪制, 此時的document.readyState為loading或者是interactive, 在線測試地址;
<!DOCTYPE html> <html> <head> <title></title> <meta charset="utf-8"> </head> <body> <script src="js.js"></script> <script> document.write("<br>"+"執行內部js"+ window.performance.now()); </script> </body>
img,link或者是script標簽都是并行下載,但是link和script一開始執行就會阻塞瀏覽器的渲染;(而且此時的script標簽中可以使用document.write往dom中寫入數據;)
如果link或者script都是動態生成的話,他們都是異步加載,異步執行, js可能在link之前或者之后執行,在線測試地址:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>JS Bin</title> </head> <body> <p style="color:#f00"> 紅色的P標簽: </p> <script> var p = document.getElementsByTagName("p")[0]; document.writeln( window.getComputedStyle(p,false)["color"] ); </script> <script> var link = document.createElement('link'); link.href = "p-green.css"; link.rel = "stylesheet"; document.head.appendChild(link); var script = document.createElement('script'); script.src = "p-green.js"; document.head.appendChild(script); </script> </body> </html>
上圖的代碼執行后的有兩種情況:
動態生成的script標簽也是異步的(并行下載,并行執行),點擊查看demo;
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>JS Bin</title> </head> <body> <script> window.onload = function() { alert("加載好了;") }; for(var i=0;i<5;i++) { var sc = document.createElement("script"); sc.src="js"+i+".js"; document.head.appendChild(sc); }; </script> </body> </html
script是順序添加到DOM中,但是沒有按照先后順序;
如果script是異步的也就是有一個async屬性(IE中為defer)屬性或者是動態生成的, 那么這些js會在DOMContentLoaded和onload之前執行;
當界面中的dom以及渲染成樹形了,那么此時document.readyState 就會變成compelete, 觸發DOMContentLoaded的事件(DOM3事件);
<!doctype html> <html> <head> <meta charset="utf-8"> <title>無標題文檔</title> </head> <body> test <iframe src="iframe.html"></iframe> <img src="https://ss0.baidu.com/6ONWsjip0QIZ8tyhnq/it/u=2723971161,380468241&fm=58" /> <script> document.onreadystatechange = function() { console.log(document.readyState); if(document.readyState === "complete") { alert("complete"); }; }; window.onload = function() { alert("onload"); }; window.frames[0].onload = function() { alert("iframeLoad"); }; document.images[0].onload = function() { alert("imgLoad") }; document.addEventListener&&document.addEventListener("DOMContentLoaded",function() { alert("DOMContentLoaded") }) </script> </body> </html>
標準瀏覽器的執行順序為 "DOMContentLoaded", "imgLoad", "iframeLoad", "complete", "load";
DOMContentLoaded以后會下載圖片, iframe等等一些需要網絡的節點, 最后會觸發onload事件, 咕~~(╯﹏╰)b;
onload一旦執行,那么瀏覽器就從加載階段進入了事件驅動階段了,如果js有很多,那么在界面加載的時候會很慢很慢, 可能要很久,用戶才能對看到界面或者進行操作, 優化加載速度可以參考這里;
額外也測試了幾個網站的DOM加載完畢和onload的時間, 加載快的確體驗好點;
www.qq.com 加載DOMContentLoaded用了1.5--2.0秒鐘,onload觸發用了6到10秒,
www.baidu.com 加載DOMContentLoaded用了1.5--2.0秒鐘,onload觸發用了2.5--3.0秒,
www.cnblogs.com 加載DOMContentLoaded用了0.4秒鐘,onload觸發用了1.5--2.0秒(中國銷量遙遙領先),
www.sohu.com 加載DOMContentLoaded用了2.5--3.0秒鐘,onload觸發用了6-7秒,
參考了知乎的回答: openIT ;
在線獲取瀏覽器最大連接數的測試地址: openIT (不好用);
兩年前的資料:openIT;
HTTP1.0協議HTTP1.1協議的區別,openIT; (HTTP1.0只能玩短連接, HTTP1.1可以玩長連接)
參考地址:http://www.iefans.net/liulanqi-zuida-bingfa-lianjieshu/
老外的在線測試并發網站:http://stevesouders.com/hpws/parallel-downloads.php?t=1429612958 (╮(╯﹏╰)╭)
本屌神馬都沒有測試出來:http://www.iefans.net/liulanqi-zuida-bingfa-lianjieshu/
chrome的timeline是好東西: , 可以看到dom加載的時間線渲染js執行的時間重繪等, 然后做對應的優化, chrome使用方法,點擊打開
document.readyState的資料,打開帶我飛;
UI線程的阻塞 ,又一個大神的 一篇好文;
面試題:

var ver = "global"; function test() { var ver = "1111"; var fun = new Function("arg","console.log(ver); console.log(arg); return arg;") ; fun("localVar"); }; test(); function test() { var x = 1; with ({x: 2}) { eval('function foo() { console.log(x); }'); eval('var bar = function() { console.log(x); }'); } foo(); bar(); } test();
作者: NONO
出處:http://www.cnblogs.com/diligenceday/
QQ:287101329
文章列表