Jason Lee
首页
  • 学习笔记

    • 常用资源
    • html&css
    • webpack
    • vue2.x
    • vue3
    • typescript入门
    • 工程化实践
  • css
  • javascript
  • es6常问
  • 手写代码
  • 错误监控
  • webpack
  • vue框架
  • 浏览器相关
  • 计算机网络
  • 数据结构和算法
  • 学习笔记
工具
首页
  • 学习笔记

    • 常用资源
    • html&css
    • webpack
    • vue2.x
    • vue3
    • typescript入门
    • 工程化实践
  • css
  • javascript
  • es6常问
  • 手写代码
  • 错误监控
  • webpack
  • vue框架
  • 浏览器相关
  • 计算机网络
  • 数据结构和算法
  • 学习笔记
工具
  • css
  • javascript
  • 错误监控
  • ES6常问
  • 手写代码
  • webpack
  • vue框架
  • 浏览器相关
    • 跨域
    • 从输入URL到页面展示发生了什么?
    • 浏览器对页面进行渲染,是怎么渲染的
    • 浏览器重绘与重排的区别?
    • 如何触发重排和重绘?
    • 如何避免重绘或者重排?
    • 浏览器缓存策略
      • 目的
      • 强制缓存、协商缓存、缓存机制
      • 储存位置
      • 用户行为
    • xss 和 csrf 攻击
      • XSS
      • CSRF
    • 事件循环机制
    • JS垃圾回收与V8垃圾回收
    • 浏览器存储
    • 前端性能优化
    • 参考资料
  • 计算机网络
  • 数据结构和算法
  • 设计模式
  • interview
jason lee
2021-09-06
目录

浏览器相关

# 跨域

原因: 跨域主要是因为浏览器同源策略引起的,同源策略要求域名、洗衣、端口一致

解决方案:

  1. cors(全局资源共享)(CROS 中的简单请求和非简单请求)
  2. jsonp
  3. postMessage
  4. 代理服务器

# 从输入URL到页面展示发生了什么?

  • 首先在浏览器中输入URL

  • 查找缓存:浏览器先查看浏览器缓存-系统缓存-路由缓存中是否有该地址页面,如果有则显示页面内容。如果没有则进行下一步。

    • 浏览器缓存:浏览器会记录DNS一段时间,因此,只是第一个地方解析DNS请求;
    • 操作系统缓存:如果在浏览器缓存中不包含这个记录,则会使系统调用操作系统, 获取操作系统的记录(保存最近的DNS查询缓存);
    • 路由器缓存:如果上述两个步骤均不能成功获取DNS记录,继续搜索路由器缓存;
    • ISP缓存:若上述均失败,继续向ISP搜索。
  • DNS域名解析:浏览器向DNS服务器发起请求,解析该URL中的域名对应的IP地址。DNS服务器是基于UDP的,因此会用到UDP协议。。

  • 建立TCP连接:解析出IP地址后,根据IP地址和默认80端口,和服务器建立TCP连接

  • 发起HTTP请求:浏览器发起读取文件的HTTP请求,,该请求报文作为TCP三次握手的第三次数据发送给服务器

  • 服务器响应请求并返回结果:服务器对浏览器请求做出响应,并把对应的html文件发送给浏览器

  • 关闭TCP连接:通过四次挥手释放TCP连接

  • 浏览器渲染:客户端(浏览器)解析HTML内容并渲染出来,浏览器接收到数据包后的解析流程为:

    • 构建DOM树:词法分析然后解析成DOM树(dom tree),是由dom元素及属性节点组成,树的根是document对象
    • 构建CSS规则树:生成CSS规则树(CSS Rule Tree)
    • 构建render树:Web浏览器将DOM和CSSOM结合,并构建出渲染树(render tree)
    • 布局(Layout):计算出每个节点在屏幕中的位置
    • 绘制(Painting):即遍历render树,并使用UI后端层绘制每个节点。
  • JS引擎解析过程:调用JS引擎执行JS代码(JS的解释阶段,预处理阶段,执行阶段生成执行上下文,VO,作用域链、回收机制等等)

# 浏览器对页面进行渲染,是怎么渲染的

  • 渲染过程:
    • (1)构建DOM树,将浏览器无法直接理解和使用的HTML,转换为浏览器能够理解的结构--DOM 树。
    • (2)构建CSSOM,把 CSS 转换为浏览器能理解的结构(styleSheets),并转换样式表中的属性值,使其标准化,计算出 DOM 树中每个节点的具体样式(根据继承规则和层叠规则)。
    • (3)创建 Layout 布局树,确定DOM 元素的几何位置信息,遍历 DOM 树中的所有可见节点,加入到布局树(display:none不包含),并计算布局树节点的坐标位置。
    • (4)构建图层树,如果页面有复杂的效果,如常见的页面滚动,或者使用 z 轴排序等,为了更加方便地实现这些效果,渲染引擎还需要为特定的节点生成专用的图层,并生成一棵对应的图层树(LayerTree)。
    • (5)Paint 图层绘制,把一个图层的绘制拆分成很多小的绘制指令,然后再把这些指令按照顺序组成一个待绘制列表(联想自己画画)。
    • (6)tiles:将图层转换成图块。
    • (7)光栅化:通过进程实现图块转换成位图。
    • (8)display:浏览器进程拿到 DrawQuad 信息生成页面显示。

# 浏览器重绘与重排的区别?

  • 重排/回流(Reflow):当DOM的变化影响了元素的几何信息,浏览器需要重新计算元素的几何属性,将其安放在界面中的正确位置,这个过程叫做重排。表现为重新生成布局,重新排列元素。
  • 重绘(Repaint): 当一个元素的外观发生改变,但没有改变布局,重新把元素外观绘制出来的过程,叫做重绘。表现为某些元素的外观被改变。

『重绘』不一定会出现『重排』,『重排』必然会出现『重绘』。

# 如何触发重排和重绘?

任何改变用来构建渲染树的信息都会导致一次重排或重绘:

  • 添加、删除、更新DOM节点
  • 通过display: none隐藏一个DOM节点-触发重排和重绘
  • 通过visibility: hidden隐藏一个DOM节点-只触发重绘,因为没有几何变化
  • 移动或者给页面中的DOM节点添加动画
  • 添加一个样式表,调整样式属性
  • 用户行为,例如调整窗口大小,改变字号,或者滚动。

# 如何避免重绘或者重排?

  1. 集中改变样式,不要一条一条地修改 DOM 的样式。

  2. 不要把 DOM 结点的属性值放在循环里当成循环里的变量。

  3. 为动画的 HTML 元件使用 fixed 或 absoult 的 position,那么修改他们的 CSS 是不会 reflow 的。

  4. 不使用 table 布局。因为可能很小的一个小改动会造成整个 table 的重新布局。

  5. 尽量只修改position:absolute或fixed元素,对其他元素影响不大

  6. 动画开始GPU加速,translate使用3D变化

  7. 提升为合成层

# 浏览器缓存策略

# 目的

是为了节约网络的资源加速浏览,浏览器在用户磁盘上对最近请求过的文档进行存储, 当访问者再次请求这个页面时,浏览器就可以从本地磁盘显示文档,这样就可以加速页面的阅览

# 强制缓存、协商缓存、缓存机制

  • 强制缓存:

    • Expires 是具体的时间点,修改客户端时间会影响
    • ​Cache-Control ​是时间段
    • ​两者区别:
      • Expires 是http1.0的产物,Cache-Control是http1.1的产
      • ​Cache-Control优先级高于Expires
      • Expires其实是过时的产物,现阶段它的存在只是一种兼容性的写法
      • ​​Expires是一个具体的服务器时间,Cache-Control是一个时间段,控制就比较容易
  • 协商缓存:

    • ETag和If-None-Match ​是对该资源的一种唯一标识,只要资源有变化,Etag就会重新生成
    • Last-Modified和If-Modified-Since ​该资源文件最后一次更改时间,以秒为单位
    • ​两者区别:
      • 方式:Etag是对资源的一种唯一标识,而Last-Modified是该资源文件最后一次更改时间
      • ​精确度:Etag精确度要优于Last-Modified。因为一秒变化多次Last-Modified监测不到,负责均衡的服务器生成的Last-Modified也不一样
      • ​性能:Etag要逊于Last-Modified,毕竟Last-Modified只需要记录时间,而Etag需要服务器通过算法来计算出一个hash值。
      • ​​​优先级:服务器校验优先考虑Etag。
  • 缓存机制:

    • ​强制缓存优先于协商缓存
    • 流程:
      • 先比较当前时间和上一次返回200时的时间差,如果没有超过cache-control设置的max-age,则没有过期,命中强缓存。
      • 如果时间过期,则向服务器发送header带有If-None-Match和If-Modified-Since的请求。
      • ​​服务器收到请求后,优先根据Etag的值判断被请求的文件有没有做修改,Etag值一致则没有修改,命中协商缓存,返回304;如果不一致则有改动,直接返回新的资源文件带上新的Etag值并返回200;若无ETag则则将If-Modified-Since和被请求文件的最后修改时间做比对,一致则命中协商缓存,返回304;不一致则返回新的last-modified和文件并返回200。

# 储存位置

  • service: ​可以让我们自由控制缓存哪些文件、如何匹配缓存、如何读取缓存,并且缓存是持续性的。
  • Memory : ​读取高效,缓存时间短
  • Disk Cache: ​​读取速度慢点,但容量大,存储时效性长
  • ​Push Cache: 它只在会话(Session)中存在,一旦会话结束就被释放,并且缓存时间也很短暂,在Chrome浏览器中只有5分钟左右

# 用户行为

  • ​地址栏访问,链接跳转是正常用户行为,将会触发浏览器缓存机制;
  • F5刷新,浏览器会设置max-age=0,跳过强缓存判断,会进行协商缓存判断;
  • ​ctrl+F5刷新,跳过强缓存和协商缓存,直接从服务器拉取资

# xss 和 csrf 攻击

# XSS

XSS(Cross Site Scripting):跨域脚本攻击。

  • 攻击原理: 不需要你做任何的登录认证,它会通过合法的操作(比如在url中输入、在评论框中输入),向你的页面注入脚本(可能是js、hmtl代码块等)。

  • XSS的攻击方式

    • 1、反射型: 发出请求时,XSS代码出现在url中,作为输入提交到服务器端,服务器端解析后响应,XSS代码随响应内容一起传回给浏览器,最后浏览器解析执行XSS代码。这个过程像一次反射,所以叫反射型XSS。

    • 2、存储型: 存储型XSS和反射型XSS的差别在于,提交的代码会存储在服务器端(数据库、内存、文件系统等),下次请求时目标页面时不用再提交XSS代码。

  • XSS的防范措施(encode + 过滤)

    • 1、编码:

    • 2、过滤:

    • 3、校正:

# CSRF

CSRF(Cross-site request forgery):跨站请求伪造。

图片加载失败

  • CSRF的防范措施

方法一、Token 验证:(服务器发送给客户端一个token;户端提交的表单中带着这个token。如果这个 token 不合法,那么服务器拒绝这个请求。

方法二:隐藏令牌: 把 token 隐藏在 http 的 head头中。(方法二和方法一有点像,本质上没有太大区别,只是使用方式上有区别。)

方法三、Referer 验证: Referer 指的是页面请求来源。意思是,只接受本站的请求,服务器才做响应;如果不是,就拦截。

# 事件循环机制

目的:JS是单线程的,为了防止一个函数执行时间过长阻塞后面的代码,所以会先将同步代码压入执行栈中,依次执行,将异步代码推入异步队列,异步队列又分为宏任务队列和微任务队列,因为宏任务队列的执行时间较长,所以微任务队列要优先于宏任务队列。

微任务队列的代表就是,Promise.then,MutationObserver,

宏任务的话就是setImmediate setTimeout setInterval。

事件环的运行机制: 先会执行栈中的内容,栈中的内容执行后执行微任务,微任务清空后再执行宏任务,先取出一个宏任务,再去执行微任务,然后在取宏任务清微任务这样不停的循环。

事件循环可以简单的描述为以下四个步骤:

  • 函数入栈,当Stack中执行到异步任务的时候,就将他丢给WebAPIs,接着执行同步任务,直到Stack为空;
  • 此期间WebAPIs完成这个事件,把回调函数放入队列中等待执行(微任务放到微任务队列,宏任务放到宏任务队列)
  • 执行栈为空时,Event Loop把微任务队列执行清空;
  • 微任务队列清空后,进入宏任务队列,取队列的第一项任务放入Stack(栈)中执行,执行完成后,查看微任务队列是否有任务,有的话,清空微任务队列。重复4,继续从宏任务中取任务执行,执行完成之后,继续清空微任务,如此反复循环,直至清空所有的任务。

# JS垃圾回收与V8垃圾回收

JavaScript 在运行过程中数据主要是存储在栈空间和堆空间,原始类型的数据是存放在栈中,引用类型的数据是存放在堆中的。堆中的数据是通过引用和变量关联起来的。 有些数据被使用之后,可能就不再需要了,我们把这种数据称为垃圾数据。如果这些垃圾数据一直保存在内存中,那么内存会越用越多,所以我们需要对这些垃圾数据进行回收,以释放有限的内存空间。

  • 项目中,如果存在大量不被释放的内存(堆/栈/上下文),页面性能会变得很慢。当某些代码操作不能被合理释放,就会造成内存泄漏。我们尽可能减少使用闭包,因为它会消耗内存。

  • 浏览器垃圾回收机制/内存回收机制:

    • 标记清除: 在js中,最常用的垃圾回收机制是标记清除:当变量进入执行环境时,被标记为“进入环境”,当变量离开执行环境时,会被标记为“离开环境”。垃圾回收器会销毁那些带标记的值并回收它们所占用的内存空间。
    • 谷歌浏览器:“查找引用”,浏览器不定时去查找当前内存的引用,如果没有被占用了,浏览器会回收它;如果被占用,就不能回收。
    • IE浏览器:“引用计数法”,当前内存被占用一次,计数累加1次,移除占用就减1,减到0时,浏览器就回收它。
  • 优化手段:内存优化 ; 手动释放:取消内存的占用即可。

    • (1)堆内存:fn = null 【null:空指针对象】
    • (2)栈内存:把上下文中,被外部占用的堆的占用取消即可。
  • 内存泄漏 在 JS 中,常见的内存泄露主要有 4 种,全局变量、闭包、DOM 元素的引用、定时器

# 浏览器存储

相同点:

存储在客户端。

不同点:

  • cookie数据大小不能超过4k;sessionStorage和localStorage的存储比cookie大得多,可以达到5M+。
  • cookie设置的过期时间之前一直有效;localStorage永久存储,浏览器关闭后数据不丢失除非主动删除数据;sessionStorage数据在当前浏览器窗口关闭后自动删除。
  • cookie的数据会自动的传递到服务器;sessionStorage和localStorage数据保存在本地。

# 前端性能优化

  • 1.只请求当前需要的资源

    • 异步加载
    • 懒加载
    • polyfill的优化 https://polyfill.io/v3/url-builder/ (opens new window)
  • 2.缩减资源体积

    • 打包压缩
    • gzip
    • 图⽚片格式优化, 压缩, 根据屏幕分辨率展示不不同分辨率的图⽚片尽量量
    • 控制cookie⼤大⼩小
  • 3.时序优化

    • js中promise.all

    • ssr

    • prefetch、prerender、preload

      <link rel=“dns-prefetch” href=“xxxxxx” />
      <link rel=“preconnect” href=“xxxxxxx” />
      <link rel=“preload” as=“image” href=“xxxxxxxxx” />
      
  • 4.合理理利利⽤用缓存

    • cdn
    • http缓存
    • localStorage, sessionStorage

# 参考资料

https://www.webpagetest.org (opens new window) webpagetest工具测试

vue框架
计算机网络

← vue框架 计算机网络→

Theme by Vdoing | Copyright © 2019-2022 jason lee | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式