你说我不讲武德,我说你不够了解我!浏览器如何解析html,css,js

海阔凭鱼跃,天高任鸟飞。Hey 你好!我是........。

众所周知,浏览器可谓是目前使用率最高的软件之一。从 1992年 世界上第一个图形网页浏览器( Erwise )的诞生发展到现在,市面上主流的浏览器有 IE、Firefox、Safari、Chrome及Opera。万恶的ie果断已经被微软放弃,这对于我们前端程序员来说,简直是出了一口恶气!

老师问小明:4+1等于几

小明说:等于6-1。

老师说:你明明知道答案,为什么不说?

小明说:年轻人不讲5的

web服务器对静态网页的处理过程

  • 用户通过浏览器向服务器发出的静态网页请求
  • web服务器找到这个网页
  • 分析其中相关联的各种文件(如图片,css,js等等)
  • 找到这些相关联的文件
  • 一并传回到浏览器的缓冲区
  • 浏览器进行解析执行文件
  • 浏览器呈现网页内容

浏览器加载的资源都能在本地找得到

我们每安装一个浏览器之后,都会在电脑里面生成一个该浏览器用来存放文件的临时文件夹。每请求一个网页,该网页所有使用到的所有文件、图片、视频等资源都会缓存到这个临时文件夹,这就是为什么第二次访问相同网页比第一次要快的原因。这里拿ie和chrome举例。

现在我们来找找这个临时文件夹的位置!

(ie)打开ie浏览器在设置里面找到intemet选项–>常规–>设置–>intemet临时文件–>查看文件。这时候我们就能找到ie的临时文件夹。删除里面的所有文件,然后再访问页面,再刷新这个文件夹,我们会发现这个文件夹又多了一堆文件,并且里面的文件都能在该网页上找到。

chrome也是如此,这里介绍一下chrome的临时文件查找方法。

在Chrome浏览器地址栏中输入 chrome://version, 打开所有URL列表页面–>找到“个人资料路径”对应的磁盘。哪里就是谷歌的临时文件夹,不同的是谷歌的文件是分开放的

看到这里,可以得出结论

服务器上存放着网页的相关文件,包括html文件、css文件、js文件、图片等。当我们打开浏览器,输入网址,我们的计算机就会对这些文件发出HTTP请求。服务器收到请求之后,会把这些文件通过HTTP协议,传输到我们的计算机中(保存到了刚才那个临时文件夹中)。这些文件,将在我们计算机本地的浏览器中,进行渲染、呈递。我们平时上网的时候,是有真实的、物理的文件传输的!

浏览器如何解析html

html文件在没有写入html标签之前和txt文本是一个性质的,不含任何样式。只是单纯的文本预览文件。一旦加入了html标签,表示内容有了语义!浏览器的渲染引擎才会根据标签的语义开始解析。

我们现在所看到的html原本分为html和xhtml两个版本,它们的区别是xhtml比html更为严格,规范性更强。由于html比xhtml更加“宽松”,使网页作者的生活变得轻松。所以这使得html很流行。

渲染引擎的基本工作流程

  • 解析HTML构建DOM树
  • 渲染树构建
  • 渲染树布局
  • 绘制渲染树

渲染引擎会解析HTML文档并把标签转换成内容树中的DOM节点。它会解析style元素和外部文件中的样式数据。样式数据和HTML中的显示控制将共同用来创建另一棵树——渲染树。渲染引擎会尝试尽快的把内容显示出来。它不会等到所有HTML都被解析完才创建并布局渲染树。它会 在处理后续内容的同时把处理过的局部内容先展示出来。

不同浏览器使用的内核也许不同,但是整个渲染流程大同小异。

开始解析

解析一个文档意味着把它翻译成有意义的结构以供代码使用。解析的结果通常是一个表征文档的由节点组成的树,称为解析树或句法树。 解析器通常把工作分给两个组件——分词程序负责把输入切分成合法符号序列,解析程序负责按照句法规则分析文档结构和构建句法树。词法分析器知道如何过滤像空格,换行之类的无关字符。

解析器输出的树是由DOM元素和属性节点组成的。DOM的全称为:Document Object Model。它是HTML文档的对象化描述,也是HTML元素与外界(如Javascript)的接口。

DOM与标签几乎有着一一对应的关系,如下面的标签

            

Hello World

我们都知道代码是逐行执行的,解析也是如此。这里涉及到一个解析算法,算法太复杂,简单的理解为:解析由两部分组成:分词与构建树。它把输入解析成符号序列。在HTML中符号就是开始标签,结束标签,属性名称和属性值。分词器识别这些符号并将其送入树构建者,然后继续分析处理下一个符号,直到输入结束。

像这段代码很明显不符合规范,尽管如此,浏览器还是在解析的过程中修复了html作者的错误内容并继续工作。具体是怎么修复的,咱不做深入了解。要保证的是我们在敲代码的时候一定要按照规范来,尽量少给浏览器添堵。

浏览器如何解析css

这里主要讲一下css解析选择器的匹配规则,我们都知道css的选择器都是全局的。这样有好也有坏!好处是代码重用率高、可以把css文件合并、拆分做的像硬件一样。坏处是css写法特别的灵活,也因为灵活,所以容易耦合在一起。

加载css

通过link标签可以引入css,加载过程是异步的,不会影响DOM树的构建。在css样式树没有处理好之前,构建好的DOM树是不会显示出来。当一切准备完毕,DOM树(layout tree)样式树(style tree) 会组合产生 渲染树(render tree),最终通过解析渲染树来作为页面呈现。

CSS 选择器解析顺序

实际上CSS选择器的读取顺序是从右向左

#molly div.haha span{color:#f00}

如上面的代码,浏览器会按照从右向左的顺序去读取选择器。先找到span然后顺着往上找到class为“haha”的div再找到id为“molly”的元素。成功匹配到则加入结果集,如果直到根元素html都没有匹配,则不再遍历这条路径,从下一个span开始重复这个过程。整个过程会形成一条符合规则的索引树,树由上至下的节点是规则中从右向左的一个个选择符匹配的节点。

如果从左向右的顺序读取,在执行到左边的分支后发现没有相对应标签匹配,则会回溯到上一个节点再继续遍历,直到找到或者没有相匹配的标签才结束。如果有100个甚至1000个分支的时候会消耗很多性能。反之从右向左查找极大的缩小的查找范围从而提高了性能。这就解释了为什么id选择器大于类选择器,类选择器大于元素选择器。

浏览器如何解析js

在浏览器中有一个“js解析器”的工具,专门用来解析我们的js代码。在这里我们只需要关注解析的其中两个步骤就行了,其它的不做研究。

  • js预解析
  • 逐行解析代码

当浏览器遇到js代码时,立马召唤“js解析器”出来工作。这个时候还不慌,得先做好准备工作。解析器会找到js当中的所有变量、函数、参数等等一大堆。并且把变量赋值为未定义(undefined),把函数取出来成为一个函数块,然后存放到仓库当中。这件事情做完了之后才开始逐行解析代码(由上向下,由左向右),然后再去和仓库进行匹配。

  

再看一下这段代码

在js预解析的时候,在遇到变量和函数重名的时候,只会保留函数块。在逐行解析代码的时候表达式(+、-、*、/、%、++、–、 参数 ……)会改变仓库里对应的值。

来!继续深入…

我们来了解一个词“作用域”,现在把这个词拆分一下。

作用:读、写操作

域:空间、范围、区域…

连起来就是能够进行读写操作的一个区域。

“域”:函数、json、……都是作为一块作用域。

全局变量、局部变量、全局函数

一段 也是一块域。在域解析的时候,也是由上向下开始解析。这就解释了为什么引用的外部公共js文件(比如:jquery)应该放到自定义js上边的原因。

再来看一下这段代码

继续跟踪一下解析器的解析过程:首先函数fn()外部的a是一个全局变量,fn()里面的a是一个局部变量。fn()函数同时是一个作用域,只要是作用域,就得做预解析和逐行解析的步骤。所以第一个alert打印的是fn()作用域的仓库指向的变量a,即为undefined。第二个alert打印的是全局的变量a,即为1。

接下来继续看代码,基本雷同的代码,我改变其中一小个地方。

看到这里当解析到fn()的时候,发现里面并没有任何变量,所以也就不往仓库里面存什么,此时的仓库里面是空的,啥也没有。但是这个时候解析并没有结束,而是从函数里面向外开始找,找到全局的变量a。此时打印的正式全局变量a的值。

这里就涉及到一个作用域链的问题。整个解析过程像是一条链子一样。由上向下,由里到外!局部能够读写全局,全局无法读写局部。

来,继续看代码,基本雷同的代码,我再次改变其中一小个地方。

千万不能忘了,在预解析的时候浏览器除了要找变量和函数之外还需要找一些参数,并且赋值为未定义。所以这里的fn(a)相当于fn(var a),这个时候的逻辑就和第一段实例代码一样了。

继续搞事情,继续看代码,基本雷同的代码,我再次改变其中一小个地方。

当代码执行到fn(a);的时候调用的fn()函数并且把全局变量a作为参数传递进去。此时打印的自然是1,要记住function fn(a)相当于function fn(var a),所以这时候a=2;改变的是局部变量a,并没有影响到全局变量a,所以第二次打印的依然是1。

完结撒花 ---- 并非大意,我闪了

撒花、撒花

小编是一个有着7年工作经验的前端工程师,关于web前端,自己有做材料的整合,一个完整学习web前端的学习路线,学习材料和工具。需要的伙伴可以私信我,发送“前端”等3秒后就可以获取领取地址,免费送给大家

作者:_秦爱德_
链接:https://juejin.cn/post/6899593590108848142
来源:掘金

delphi启动ie调用本地html传参数_年轻人不讲武德啊!了解下浏览器如何解析html、css,js相关推荐

  1. rpc 调用webservice怎样传递参数_五分钟让你了解RPC原理详解

    欢迎关注专栏[以架构赢天下]--每天持续分享Java相关知识点 以架构赢天下​zhuanlan.zhihu.com 以架构赢天下--持续分享Java相关知识点 每篇文章首发此专栏 欢迎各路Java程序 ...

  2. jsf 传参数_在JSF 2中对定制验证器进行参数化

    jsf 传参数 在JSF 2中编写自定义验证器并不是一项复杂的任务. 您实现Validator接口,添加@FacesValidator批注,并在faces-config.xml中插入validator ...

  3. bootstrapinput传参数_***文件上传控件bootstrap-fileinput的使用和参数配置说明

    特别注意: 引入所需文件后页面刷新查看样式奇怪,浏览器提示错误等,可能是因为js.css文件的引用顺序问题,zh.js需要在fileinput.js后面引入.bootstrap最好在fileinput ...

  4. jsx怎么往js里传参数_给js文件传参数(详解)

    一.利用全局变量 这是最简单的一种方式,比如Google Adsense: 缺点是引入了全局变量.其中引入文件的方式还有两个变体: // 变体1:用document.write输出 document. ...

  5. python调用shell脚本的参数_使用python执行shell脚本 并动态传参 及subprocess的使用详解

    最近工作需求中 有遇到这个情况 在web端获取配置文件内容 及 往shell 脚本中动态传入参数 执行shell脚本这个有多种方法 最后还是选择了subprocess这个python标准库 subpr ...

  6. Silverlight中多个Xaml之间的切换/调用/弹出/传参数(转)

    原文:http://www.cnblogs.com/bingyun84/archive/2010/01/22/1654243.html 1.A.xaml跳转到B.xaml (a)首先需要定义一个公用的 ...

  7. java调用R语言传参数时,RserveException: eval failed Syntax error

    首先将执行的source语句如下 source('D:/xxx/xxx/xxx/py/test.R') ,如果有函数,则继续执行如下 myFunc(1,2) //myFunc是R脚本中的方法名,其中参 ...

  8. python调用exe程序 传入参数_关于使用c#调用python脚本文件,脚本文件需要传递参数...

    最近工作中需要干这个事,网上搜了搜资料,改了改,基本是这样 建立一个控制台应用程序: 比如 加入我在命令行直接调用python脚本,命令为 y安装python后,添加环境变量,path下面,加入路径. ...

  9. 函数传参数_算法笔记(7)第二章C、C++快速入门函数,main函数,

    #includevoid change(int x){ x=x+1;}int main(){ int x=10; change(x); prinf("%d\n",x); retur ...

  10. typecho本地上传头像_用ProGet搭建本地私有NuGet仓库

    搭建ProGet 下载 官网下载Windows版本的Inedo Hub (https://inedo.com/proget/download) 下载下来的软件名: ProGetInstaller.ex ...

最新文章

  1. crc32库 qt_Qt 打包32位库(包括WebEngineView)
  2. 拥抱.NET Core系列:MemoryCache 缓存过期
  3. 栈在前端中的应用,顺便再了解下深拷贝和浅拷贝!
  4. 图像处理-RBG图像和灰度图像
  5. 5,线程池,进程池,协程,IO模型
  6. Android Studio3.2经常用的一些依赖(以后再加)
  7. Doris之动态分区(全面)
  8. tomcat启动内存设置以及字符集设置
  9. 放弃用了7年的MyBatis !我选择 JDBCTemplate!
  10. spring session 考虑问题解答
  11. 计算机的输入法如何使用简短描述,应用电脑(1)第一章 计算机组成与中文输入法...
  12. 统计推断—假设检验(hypothesis testing)
  13. 互联网产品经理的主要职责(产品经理工作职责)
  14. 线程的条件变量(cond)
  15. 【操作系统】CSAPP学习笔记
  16. register int 的作用
  17. 贝尔宾九种团队角色理论总结(转)
  18. Kubernetes 多租户简介
  19. 2012年北京地铁规划图(我好不容易找到的哦)
  20. python解常微分方程

热门文章

  1. SQL分类,DDL,DML,DCL
  2. 团队项目第一阶段站立会议01
  3. Android View 如何测量
  4. 机器学习 —— 概率图模型(CPD)
  5. Rob Pike:走进Go语言
  6. 艾伟_转载:编写自文档化的代码
  7. 物理内存管理之zone详解
  8. 同步与互斥的基本原理
  9. Android-- bionic介绍
  10. sort()函数关于结构内容要怎么写