天天看点

【超级长文】从输入URL到页面加载的过程?如何由一道题完善自己的前端知识体系!

前言

超级长文,本文仅摘录了提纲,可参考 完整全文链接

大纲

  • 对知识体系进行一次预评级
  • 为什么说知识体系如此重要?
  • 梳理主干流程
  • 从浏览器接收url到开启网络请求线程
    • 多进程的浏览器
    • 多线程的浏览器内核
    • 解析URL
    • 网络请求都是单独的线程
    • 更多
  • 开启网络线程到发出一个完整的http请求
    • DNS查询得到IP
    • tcp/ip请求
    • 五层因特网协议栈
  • 从服务器接收到请求到对应后台接收到请求
    • 负载均衡
    • 后台的处理
  • 后台和前台的http交互
    • http报文结构
    • cookie以及优化
    • gzip压缩
    • 长连接与短连接
    • http 2.0
    • https
  • 单独拎出来的缓存问题,http的缓存
    • 强缓存与弱缓存
    • 缓存头部简述
    • 头部的区别
  • 解析页面流程
    • 流程简述
    • HTML解析,构建DOM
    • 生成CSS规则
    • 构建渲染树
    • 渲染
    • 简单层与复合层
    • Chrome中的调试
    • 资源外链的下载
    • loaded和domcontentloaded
  • CSS的可视化格式模型
    • 包含块(Containing Block)
    • 控制框(Controlling Box)
    • BFC(Block Formatting Context)
    • IFC(Inline Formatting Context)
    • 其它
  • JS引擎解析过程
    • JS的解释阶段
    • JS的预处理阶段
    • JS的执行阶段
    • 回收机制
  • 其它
  • 总结

对知识体系进行一次预评级

看到这道题目,不借助搜索引擎,自己的心里是否有一个答案?

这里,以目前的经验(了解过一些处于不同阶段的相关前端人员的情况),大概有以下几种情况:(以下都是以点见面,实际上不同阶段人员一般都会有其它的隐藏知识点的)

level1:

完全没什么概念的,支支吾吾的回答,一般就是这种水平(大致形象点描述):

  • 浏览器发起请求,服务端返回数据,然后前端解析成网页,执行脚本。。。

这类人员一般都是:

  • 萌新(刚接触前端的,包括0-6个月都有可能有这种回答)
  • 沉淀人员(就是那种可能已经接触了前端几年,但是仍然处于初级阶段的那种。。。)

当然了,后者一般还会偶尔提下**

http

后台

浏览器渲染

js引擎

**等等关键字,但基本都是一详细的问就不知道了。。。

level2:

已经有初步概念,但是可能没有完整梳理过,导致无法形成一个完整的体系,或者是很多细节都不会展开,大概是这样子的:(可能符合若干条)

  • 知道浏览器输入url后会有http请求这个概念
  • 有后台这个概念,大致知道前后端的交互,知道前后端只要靠http报文通信
  • 知道浏览器接收到数据后会进行解析,有一定概念,但是具体流程不熟悉(如render树构建流程,layout、paint,复合层与简单层,常用优化方案等不是很熟悉)
  • 对于js引擎的解析流程有一定概念,但是细节不熟悉(如具体的形参,函数,变量提升,执行上下文以及VO、AO、作用域链,回收机制等概念不是很熟悉)
  • 如可能知道一些http规范初步概念,但是不熟悉(如http报文结构,常用头部,缓存机制,http2.0,https等特性,跨域与web安全等不是很熟悉)

到这里,看到这上面一大堆的概念后,心里应该也会有点底了。。。

实际上,大部分的前端人员可能都处于level2,但是,跳出这个阶段并不容易,一般需要积累,不断学习,才能水到渠成

这类人员一般都是:

  • 工作1-3年左右的普通人员(占大多数,而且大多数人员工作3年左右并没有实质上的提升)
  • 工作3年以上的老人(这部分人大多都业务十分娴熟,一个当好几个用,但是,基础比较薄弱,可能没有尝试写过框架、组件、脚手架等)

大部分的初中级都陷在这个阶段,如果要突破,不断学习,积累,自然能水到渠成,打通任督二脉

level3:

基本能到这一步的,不是高阶就是接近高阶,因为很多概念并不是靠背就能理解的,而要理解这么多,需形成体系,一般都需要积累,非一日之功。

一般包括什么样的回答呢?(这里就以自己的简略回答进行举例),一般这个阶段的人员都会符合若干条(不一定全部,当然可能还有些是这里遗漏的):

  • 首先略去那些键盘输入、和操作系统交互、以及屏幕显示原理、网卡等硬件交互之类的(前端向中,很多硬件原理暂时略去。。。)
  • 对浏览器模型有整体概念,知道浏览器是多进程的,浏览器内核是多线程的,清楚进程与线程之间得区别,以及输入url后会开一个新的网络线程
  • 对从开启网络线程到发出一个完整的http请求中间的过程有所了解(如dns查询,tcp/ip链接,五层因特网协议栈等等,以及一些优化方案,如

    dns-prefetch

  • 对从服务器接收到请求到对应后台接收到请求有一定了解(如负载均衡,安全拦截以及后台代码处理等)
  • 对后台和前台的http交互熟悉(包括http报文结构,场景头部,cookie,跨域,web安全,http缓存,http2.0,https等)
  • 对浏览器接收到http数据包后的解析流程熟悉(包括解析html,词法分析然后解析成dom树、解析css生成css规则树、合并成render树,然后layout、painting渲染、里面可能还包括复合图层的合成、GPU绘制、外链处理、加载顺序等)
  • 对JS引擎解析过程熟悉(包括JS的解释,预处理,执行上下文,VO,作用域链,this,回收机制等)

可以看到,上述包括了一大堆的概念,仅仅是偏前端向,而且没有详细展开,就已经如此之多的概念了,所以,个人认为如果没有自己的见解,没有形成自己的知识体系,仅仅是看看,背背是没用的,过一段时间就会忘光了。

再说下一般这个阶段的都可能是什么样的人吧。(不一定准确,这里主要是靠少部分现实以及大部分推测得出)

  • 工作2年以上的前端(基本上如果按正常进度的话,至少接触前端两年左右才会开始走向高阶,当然,现在很多都是上学时就开始学了的,还有部分是天赋异禀,不好预估。。。)
  • 或者是已经十分熟悉其它某门语言,再转前端的人(基本上是很快就可以将前端水准提升上去)

一般符合这个条件的都会有各种隐藏属性(如看过各大框架、组件的源码,写过自己的组件、框架、脚手架,做过大型项目,整理过若干精品博文等)

level4:

由于本人层次尚未达到,所以大致说下自己的见解吧。

一般这个层次,很多大佬都并不仅仅是某个技术栈了,而是成为了技术专家,技术leader之类的角色。所以仅仅是回答某个技术问题已经无法看出水准了, 可能更多的要看架构,整体把控,大型工程构建能力等等

不过,对于某些执着于技术的大佬,大概会有一些回答吧:(猜的)

  • 从键盘谈起到系统交互,从浏览器到CPU,从调度机制到系统内核,从数据请求到二进制、汇编,从GPU绘图到LCD显示,然后再分析系统底层的进程、内存等等

总之,从软件到硬件,到材料,到分子,原子,量子,薛定谔的猫,人类起源,宇宙大爆炸,平行宇宙?感觉都毫无违和感。。。

这点可以参考下本题的原始出处:

fex.baidu.com/blog/2014/0…

为什么说知识体系如此重要?

为什么说知识体系如此重要呢?这里举几个例子

假设有被问到这样一道题目(随意想到的一个):

  • 如何理解

    getComputedStyle

在尚未梳理知识体系前,大概会这样回答:

  • 普通版本:

    getComputedStyle

    会获取当前元素所有最终使用的CSS属性值(最终计算后的结果),通过

    window.getComputedStyle

    等价于

    document.defaultView.getComputedStyle

    调用
  • 详细版本:

    window.getComputedStyle(elem, null).getPropertyValue("height")

    可能的值为

    100px

    ,而且,就算是css上写的是

    inherit

    getComputedStyle

    也会把它最终计算出来的。不过注意,如果元素的背景色透明,那么

    getComputedStyle

    获取出来的就是透明的这个背景(因为透明本身也是有效的),而不会是父节点的背景。所以它不一定是最终显示的颜色。

就这个API来说,上述的回答已经比较全面了。

但是,其实它是可以继续延伸的。

譬如现在会这样回答:

  • getComputedStyle

    会获取当前元素所有最终使用的CSS属性值,

    window.

    document.defaultView.

    等价...
  • getComputedStyle

    会引起回流,因为它需要获取祖先节点的一些信息进行计算(譬如宽高等),所以用的时候慎用,回流会引起性能问题。然后合适的话会将话题引导回流,重绘,浏览器渲染原理等等。当然也可以列举一些其它会引发回流的操作,如

    offsetXXX

    scrollXXX

    clientXXX

    currentStyle

    等等

再举一个例子:

  • visibility: hidden

    display: none

    的区别

可以如下回答:

  • 普通回答,一个隐藏,但占据位置,一个隐藏,不占据位置
  • 进一步,

    display

    由于隐藏后不占据位置,所以造成了dom树的改变,会引发回流,代价较大
  • 再进一步,当一个页面某个元素经常需要切换

    display

    时如何优化,一般会用复合层优化,或者要求低一点用

    absolute

    让其脱离普通文档流也行。然后可以将话题引到普通文档流,

    absolute

    文档流,复合图层的区别,
  • 再进一步可以描述下浏览器渲染原理以及复合图层和普通图层的绘制区别(复合图层单独分配资源,独立绘制,性能提升,但是不能过多,还有隐式合成等等)

上面这些大概就是知识系统化后的回答,会更全面,容易由浅入深,而且一有机会就可以往更底层挖

前端向知识的重点

此部分的内容是站在个人视角分析的,并不是说就一定是正确答案

首先明确,计算机方面的知识是可以无穷无尽的挖的,而本文的重点是梳理前端向的重点知识

对于前端向(这里可能没有提到

node.js

之类的,更多的是指客户端前端),这里将知识点按重要程度划分成以下几大类:

  • 核心知识,必须掌握的,也是最基础的,譬如浏览器模型,渲染原理,JS解析过程,JS运行机制等,作为骨架来承载知识体系
  • 重点知识,往往每一块都是一个知识点,而且这些知识点都很重要,譬如http相关,web安全相关,跨域处理等
  • 拓展知识,这一块可能更多的是了解,稍微实践过,但是认识上可能没有上面那么深刻,譬如五层因特网协议栈,hybrid模式,移动原生开发,后台相关等等(当然,在不同领域,可能有某些知识就上升到重点知识层次了,譬如hybrid开发时,懂原生开发是很重要的)

为什么要按上面这种方式划分?

这大概与个人的技术成长有关。

记得最开始学前端知识时,是一点一点的积累,一个知识点一个知识点的攻克。

就这样,虽然在很长一段时间内积累了不少的知识,但是,总是无法将它串联到一起。每次梳理时都是很分散的,无法保持思路连贯性。

直到后来,在将浏览器渲染原理、JS运行机制、JS引擎解析流程梳理一遍后,感觉就跟打通了任督二脉一样,有了一个整体的架构,以前的知识点都连贯起来了。

梳理出了一个知识体系,以后就算再学新的知识,也会尽量往这个体系上靠拢,环环相扣,更容易理解,也更不容易遗忘

文章篇幅过长,后续完整内容

继续阅读