zoukankan      html  css  js  c++  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 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;
    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

    作者: NONO
    出处:http://www.cnblogs.com/diligenceday/
    QQ:287101329 

  • 相关阅读:
    Oracle
    注解
    java 算法实现
    ConcurrentHashMap
    hashMap 1.8
    hashmap 1.7
    MySQL优化
    Mysql面试题
    tmux
    mysql 复制表结构、表数据的方法
  • 原文地址:https://www.cnblogs.com/diligenceday/p/4445186.html
Copyright © 2011-2022 走看看