你的位置:首页 > Java教程

[Java教程]WEB界面onload前的加载流程❤❤


  开始的流程:

    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 setupapp.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 handlerapp.use(function(req, res, next) {  var err = new Error('Not Found');  err.status = 404;  next(err);});// error handlers// development error handler// will print stacktraceif (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 userapp.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;

View Code

 

 

  我自己测试了下,chrome的结果是6个,对于图片chrome会先请求加载一个, 后面再一个个加载, 目测一个域名下最多有6个是对的:

  FF下的结果也一样,不过对于图片请求处理和chrome有点区别:

  

  因为浏览器的并发也是有最大值的, 所以把服务器的图片放到同服务器的的二级域名下,那么就可以突破浏览器6个的并发限制, 请求会变成N倍,是hack ,已亲测;

  

  首先,浏览器要把当前界面进行unload, unload的时间要看当前界面的HTML;

  然后,浏览器从DOM开头由上到下步步渲染,link以及script依次加载和执行绘制, 此时的document.readyStateloading或者是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.writedom中写入数据;)

 

  如果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会在DOMContentLoadedonload之前执行;

  当界面中的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();

View Code