浏览器渲染机制面试_【前端面试必考题】页面渲染机制(一)

页面渲染机制这部分内容会分成两篇来进行讲解,这两篇里我们准备聊一下页面的渲染的过程,包括页面的加载、DOM 树的构建、CSSOM 树的构建、渲染树的构建和最后的渲染过程等。浏览器的渲染机制和网页的优化息息相关,只有知道了页面是怎么渲染出来的,才能在写代码的时候使用最合理的方式,比如知道了 CSS 文件的解析过程后就知道为什么要把 CSS 文件放在 HTML 的前边,知道为什么要少用@import 了。这一部分的内容,我们会先介绍渲染的整体过程,然后再把这个过程中比较重要的部分做详细介绍。

页面的加载和渲染全过程

当我们在浏览器里输入一个 URL 后,最终会呈现一个完整的网页。这中间会经历如下的过程:

HTML 的加载

输入 URL 后,最先拿到的是 HTML 文件。HTML是一个网页的基础,所以要在最开始的时候下载它。HTML下载完成以后就会开始对它进行解析。

其他静态资源下载

HTML 在解析的过程中,如果发现 HTML 文本里面夹杂的一些外部的资源链接,比如 CSS、JS 和图片等时,会立即启用别的线程下载这些静态资源。这里有个特殊的是 JS 文件,当遇到 JS 文件的时候,HTML 的解析会停下来,等 JS 文件下载结束并且执行完,HTML 的解析工作再接着来。这样做是因为 JS 里可能会出现修改已经完成的解析结果,有白白浪费资源的风险,所以 HTML 解析器干脆等 JS 折腾完了再干。

DOM 树构建

在 HTML 解析的同时,解析器会把解析完的HTML转化成DOM 对象,再进一步构建 DOM 树。

CSSOM 树构建

当 CSS 下载完,CSS 解析器就开始对 CSS 进行解析,把 CSS 解析成 CSS 对象,然后把这些 CSS 对象组装起来,构建出一棵 CSSOM 树。

渲染树构建

DOM 树和 CSSOM 树都构建完成以后,浏览器会根据这两棵树构建出一棵渲染树。

布局计算

渲染树构建完成以后,所有元素的位置关系和需要应用的样式就确定了。这时候浏览器会计算出所有元素的大小和绝对位置。

渲染布局计算完成以后,浏览器就可以在页面上渲染元素了。比如从 (x1, y1) 到(x2, y2)的正方形区域渲染成蓝色。经过渲染引擎的处理后,整个页面就显示在了屏幕上。

上面讲了一下浏览器从加载到渲染的大概过程,这部分内容是想让同学们对加载有个大概的印象,接下来我们把这个过程中比较重要的部分再详细讲解下。

DOM 树的构建

页面中的每一个 HTML 标签,都会被浏览器解析成一个对象,我们称它为文档对象(Document Object)。HTML 的本质是一个嵌套结构,在解析的时候会把每个文档对象用一个树形结构组织起来,所有的文档对象都会挂在一个叫做 Document 的东西上,这种组织方式就是 HTML 最基础的结构–文档对象模型(DOM),这棵树里面的每个文档对象就叫做 DOM 节点。

在 HTML 加载的过程中,DOM 树就在开始构建了。构建的过程是先把 HTML 里每个标签都解析成 DOM 节点(每个标签的属性、值和上下文关系等都在这个文档对象里),然后使用深度遍历的方法把这些对象构造成一棵树。

我们以下面的 HTML 文件为例:

Document

文章详情页

文章标题

吃葡萄不吐葡萄皮

文章插图

不吃葡萄倒吐葡萄皮

在构建 DOM 树的时候,就是从最外层 HTML 节点开始,按深度优先的方式构建。之所以用深度优先,是因为 HTML在加载的时候是自上而下的,最先加载的是根节点,然后是根节点的第一个子节点

,再然后是head的第一个子节点…head构建完成后再去构建 body 部分的内容,以此类推。使用深度优先的方式构建这棵树就和文档的加载顺序吻合了。最后,上面这个 html 结构就会生成一棵 DOM 树。

CSSOM 树的构建

在浏览器构建 DOM 树的同时,如果样式也加载完成了,那么 CSSOM 树也在同步地构建。CSS 树和 DOM 类似,它的树形结构记录着所有样式的信息。

我们以给上面的 HTML 加上如下的样式:

body{

font-size: 16px;

}

// 去掉所有p元素的内外边距

p{

margin: 0;

padding: 0;

}

// 页面头部行高50px,文本垂直居中,隐藏

.header{

height: 50px;

line-height: 50px;

display: none;

text-align: center;

}

.header .page-name{

font-size: 20px;

}

// 文本区域左右两边留10px空白

.content{

padding: 0 10px;

}

.contetn .title{

font-seize: 20px;

}

// 内容区行高30px

.content .graph{

line-height: 30px;

}

// 文章中的图片用作块级元素,水平居中

.content img{

display: block;

margin: 0 auto;

}

我们就以这一组样式为例,这样一组样式中有公用的样式 p 和 body,有标题栏 .header 部分的样式,还有内容区 .content 部分的样式。

总结

这一篇讲了渲染的大致过程、DOM 树的构建和 CSSOM 树的构建。到这个阶段,渲染需要的基础工作就准备完成了。下一篇我们继续讲解,感兴趣的同学可以关注我的下一篇文章。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/291896.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OpenJudge/Poj 1226 Substrings

1.链接地址: http://bailian.openjudge.cn/practice/1226/ http://poj.org/problem?id1226 2.题目: 总时间限制:1000ms内存限制:65536kB描述You are given a number of case-sensitive strings of alphabetic characters, find the largest string X, s…

MFC继承表

转载于:https://www.cnblogs.com/Lthis/p/4264967.html

linux之fdisk查看分区和mkfs.ext3删除分区和mount挂载和e2label添加卷标使用总结

一、使用fdisk、mkfs.ext3、和mount、e2lable的原因 有个分区挂载不上,然后需要格式化分区,还需要添加卷标 二、fdisk、mkfs.ext3、mount、e2lable命令介绍 1、fdisk命令介绍 1)、了解分区 分区是将一个硬盘驱动器分成若干个逻辑驱动器,分区是把硬盘连续的区块当做一个…

Task+ConcurrentQueue多线程编程

队列&#xff08;Queue&#xff09;代表了一个先进先出的对象集合。当您需要对各项进行先进先出的访问时&#xff0c;则使用队列。当您在列表中添加一项&#xff0c;称为入队&#xff0c;当您从列表中移除一项时&#xff0c;称为出队。ConcurrentQueue<T>队列是一个高效的…

怎样从一个手机上安两个不同版本的软件_怎么在一部手机上安装两个不同版本的微信?...

今天我们就向大家介绍一个非常简便的方法&#xff0c;帮助我们实现在Android智能手机将应用程序多开。1、安卓微信双卡方法&#xff1a;准备工作从上图我们可以看到&#xff0c;小编在自己的手机上已经安装了两个不同版本的微信。通常在自己的手机上安装同一应用程序时&#xf…

牛人的英语学习方法

牛人的英语学习方法&#xff1a; 总结1&#xff1a;背出来的单词 不背熟单词就去学所谓的听力阅读作文语法&#xff0c;就像没学走路就想学跑步&#xff0c;没吃饭就想拉屎&#xff0c;没脱牛仔裤就想脱内裤一样的痴心妄想。所以想学英语的人要做的第一件事&#xff0c;不是哭&…

02-选择排序

数据结构和算法 基于《算法图解》—Aditya Bhargava和《数据结构》—严蔚敏 第2章 2.1 内存的工作原理 计算机就像是很多抽屉的集合体&#xff0c;每个抽屉都有地址。需要将数据存储到内存是&#xff0c;请求计算机提供存储空间&#xff0c;计算机则分配一个地址。需要存储多…

[SAP ABAP开发技术总结]权限对象检查

20.14. 权限检查 AT SELECTION-SCREEN. DATA: BEGIN OF lt_bukrs OCCURS 0, bukrs TYPE t001-bukrs, END OF lt_bukrs. SELECT bukrs FROM t001 INTO CORRESPONDING FIELDS OF TABLE lt_bukrs WHERE bukrs IN s_bukrs. LOOP AT lt_bukrs. AUTHORITY-C…

linux c之strncpy函数和strncmp函数最简单使用总结

1.原型声明&#xff1a; char * strncpy(char *dest,const char *src, size_t n); strncmp() 用来比较两个字符串的前n个字符&#xff0c;区分大小写&#xff0c;其原型为&#xff1a; int strncmp ( const char * str1, const char * str2, size_t n ); 若str1与str2的前n…

使用ssh tunnel 来做代理或跳板

接前文 http://www.cnblogs.com/piperck/p/6188984.html 使用ssh config配置文件来管理ssh连接 前文说了如何配置自己的ssh config 来方便的管理自己的ssh连接&#xff0c;以及如何使用ssh-add来将自己密钥密码存储起来。接下将讨论一下使用ssh来做转发和跳板的相关实践。 首先…

阻止你变现的,从来都不是开源许可证

文 | lola_chen出品 | OSC开源社区&#xff08;ID&#xff1a;oschina2013&#xff09;之前&#xff0c;《GPL 转闭源&#xff1f;法院判决&#xff1a;一日 GPL 终身 GPL》一文提出一个冷门却又重要的知识点&#xff1a;GPL 许可证之下的开源项目&#xff0c;可以分叉出来闭源…

yum 常用命令

yum是一个用于管理rpm包的后台程序&#xff0c;用python写成&#xff0c;可以非常方便的解决rpm的依赖关系。在建立好yum服务器后&#xff0c;yum客户端可以通过 http、ftp方式获得软件包&#xff0c;并使用方便的命令直接管理、更新所有的rpm包&#xff0c;甚至包括kernel的更…

sparkshelljarlib_Spark应用程序第三方jar文件依赖解决方案

第一种方式操作&#xff1a;将第三方jar文件打包到最终形成的spark应用程序jar文件中应用场景&#xff1a;第三方jar文件比较小&#xff0c;应用的地方比较少第二种方式操作&#xff1a;使用spark-submit提交命令的参数: --jars要求&#xff1a;1、使用spark-submit命令的机器上…

hdu 1460 完数

注意&#xff1a;num1和num2的大小未知&#xff0c;需比较&#xff01; 有两种方法&#xff1a; 法一&#xff1a;素数打印素数分解&#xff08;求因数和公式&#xff09; 1 #include<iostream>2 #include<cstring>3 #include<cstdio>4 #include<string&g…

03-递归

数据结构和算法 基于《算法图解》—Aditya Bhargava和《数据结构》—严蔚敏 第3章 递归 3.1 递归 假设在一堆嵌套的盒子里找钥匙&#xff0c;对比循环和递归。 使用循环解决&#xff1a; #使用while循环&#xff1a;只要盒子堆不是空&#xff0c;就从中取出一个盒子&#x…

linux c之提示format‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long int’ [-Wformat

1、问题 有个long int data;我输出的时候printf("data is %d", data);出现下面警告 自己竟然不知道 长整型怎么打印出来&#xff0c;日了狗。 2、解决办法 md&#xff0c;m为指定的输出字段的宽度。如果数据的位数小于m&#xff0c;则左端补以空格&#xff0c;若大…

PostgreSQL 从源码找出哪些操作需要超级用户权限 - 阿里云rds_superuser和superuser有什么区别...

标签 PostgreSQL , 超级用户 , superuser 背景 在数据库中哪些操作需要超级用户的权限才能执行&#xff1f; 这个问题翻文档可能翻不全面&#xff0c;或者是已经比较难以完成的任务。 但是从源码里面是比较好找出这个答案的。 权限 例如 postgres# select * from pg_authid;rol…

linux c之通过消息队列实现进程通信

1、消息队列的介绍 消息队列提供了一种从一个进程向另一个进程发送一个数据块的方法。 每个数据块都被认为含有一个类型,接收进程可以独立地接收含有不同类型的数据结构。我们可以通过发送消息来避免命名管道的同步和阻塞问题。但是消息队列与命名管道一样,每个数据块都有一…

Asp.Net Core部署:早知道,还是docker!以及一点碎碎念

前言AspNetCore技术栈在我们团队里的使用也有一段时间了&#xff0c;之前的部署方式一直是本地编译之后上传可执行文件到服务器&#xff0c;使用supervisor来管理进程这种很原始的方式。参考之前的文章&#xff1a;Asp.Net Core学习笔记&#xff1a;&#xff08;五&#xff09;…

04-快速排序

数据结构和算法 基于《算法图解》—Aditya Bhargava 和《数据结构》—严蔚敏 第4章 快速排序 4.1 分而治之 divide and conquer , 简称D&C&#xff1a;一种著名的递归式问题解决方法。 例子1&#xff1a; 假设你是农场主&#xff0c;有一小块土地。要求将这块地均匀地分…