浏览器渲染原理

渲染流程

 

地址栏输入了url后都发生了什么

 

http协议

 http1和http2的区别

http1 服务端到静态目录查找html,若文件存在,返回静态资源后,若有js 或css,再请求资源

http2 服务端找到静态文件html后,循环里面需要的静态文件,做一次服务端推送,而不是请求的时候才返回。(就是第一次请求就把资源都返回)

浏览器收到内容后做什么?

6.将不同图层进行绘制,转交给合成线程处理,最终产生页面,并显示在浏览器上(painting, display)

 为什么css放上面,js放下面

css不阻塞html解析,阻塞页面渲染 

  • css放下面会导致重绘,回流,parse html, parse stylesheet, paint, parse html, parse stylesheet, paint

 

  •  js会阻塞html解析成dom

 js中可能会有加载css,所以js等待css,js里要操作dom节点,dom等待js,导致渲染一段段的

  

所以js放下面

 模拟浏览器解析流程

 node服务,server.js

//请求服务,返回html
const http = reuire('http');
const fs = require('fs');
const path = require('path');

const server = http.createServe((req, res)=>{
    console.log(req.headers);
    res.end(fs.readFileSync(path.resolve(__dirname,'index.html')));
    

})

 client.js用node写客户端

const net = require('net');
const HttpParser = require('./http-parser');
const HtmlParser = require('./htmlparser2');
// 发送请求,监听数据的到来
class HTTPRequest {
    constructor(options = {}) {
        this.host = options.host;
        this.method = options.method || 'GET';
        this.path = options.path || '/';
        this.port = options.port || 80;
        this.headers = options.headers
    }
    send(){
        return new Promise((resolve, reject)=>{
            // 构建http请求
            const rows = [];
            rows.push(`${this.method} ${this.path} HTTP/1.1`); // 模拟浏览器的请求行
            Object.keys(this.headers).forEach(key=>{
                rows.push(`${key}:${this.headers[key]}`)
            })
            let data = rows.join('\r\n') + '\r\n\n\n';
            let socket = net.createConnection({ // 通过主机名端口寻址,拿到通道(tcp连接传输http数据)
                host: this.host
                port: this.port
            },()=>{
                socket.write(data);
            })
            let parser = new HttpParser(); // 解析器
            socket.on('data',function(chunk){ //事件会触发多次
                console.log(chunk.toString);
                // 解析数据 为二进制流
                parser.parse(chunk);
                if(parser.result){
                    resolve(parser.result); //
                }
            })
        })
    }

}
function parserCSS(csstext) {
    let ast = css.parser(csstext)
}
async function request() {
    const request = new HTTPRequest({
        host: '127.0.0.1',
        method:'GET',
        port:3000,
        path: '/',
        headers: {
            name:chao,
            age:20
        }  
    })
    let {responseLine, headers, body} = await request.send();

    // 浏览器会根据响应类型来解析文件  Content-Type:'text/html'
    // html -> html-parser -> dom tree 词法分析 分析html
    // 解析后需要生成tree,典型的栈结构
    let DomTree = [{type:'document',children:[]}]; // 数据结构
    let parser = new HtmlParser.parser({
        onopentag(name, attributes){
            console.log('start', name, attributes);
            let parent = stack[stack.length -1];

            let element ={
                tagName:name,
                attributes,
                children:[],
                parent
            }
            parent.cildren.push(element);
            stack.push(element);
        },
        ontext(text){
            console.log('text', text);
            let parent = stack[stack.length -1];
            let textNode = {
                type:'text',
                text
            }
            parent.children.push(textNode);
        },
        onclosetag(name){
            console.log('close', name);
            if(name === 'style'){
                parserCSS(parent.children[0].text)
            }
            stack.pop();
        },
    });
    console.log(body);        
    parser.end(body);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值