三.[前端总结]之浏览器篇

1. 跨标签⻚通讯

 

不同标签⻚间的通讯,本质原理就是去运⽤⼀些可以共享的中间介质,因此⽐较常⽤的有以下⽅法:

通过⽗⻚⾯ window.open() 和⼦⻚⾯ postMessage

  异步下,通过 window.open('about: blank') tab.location.href = '*'

设置同域下共享的 localStorage 与监听 window.onstorage

  重复写⼊相同的值⽆法触发

  会受到浏览器隐身模式等的限制

设置共享 cookie 与不断轮询脏检查( setInterval )

借助服务端或者中间层实现

 

2. 浏览器架构

 

⽤户界⾯

主进程内核

  渲染引擎

  JS 

    执⾏栈

事件触发线程

  消息队列

    微任务

    宏任务

⽹络异步线程

定时器线程

 

3.浏览器下事件循环(Event Loop)

 

事件循环是指: 执⾏⼀个宏任务,然后执⾏清空微任务列表,循环再执⾏宏任务,再清微任务列表

微任务 microtask(jobs): promise / ajax / Object.observe (该⽅法已废弃)

macrotask(task): setTimout / script / IO / UI Rendering

 

4.从输 url 到展示的过程

 

DNS

TCP 三次握⼿

发送请求,分 url ,设置请求报⽂(头,主体)

服务器返回请求的⽂件 ( html )

浏览器渲染

  HTML parser --> DOM Tree

    标记化算法,进⾏元素状态的标记

    dom 树构建

CSS parser --> Style Tree

  解 css 代码,⽣成样式树

attachment --> Render Tree

  结合 dom style树,⽣成渲染树

layout :

GPU painting : 像素绘制⻚⾯

 

5. 重绘与回流

 

当元素的样式发⽣变化时,浏览器需要触发更新,重新绘制元素。这个过程中,有两种类型的操作,即重绘与回流

 

重绘(repaint): 当元素样式的改变不影响布局时,浏览器将使⽤重绘对元素进⾏更新,此时由于只需要UI层⾯的重新像素绘制,因此 损耗较少

回流(reflow): 当元素的尺⼨、结构或触发某些属性时,浏览器会重新渲染⻚⾯,称为回流。此时,浏览器需要重新经过计算,计算后还需要重新⻚⾯布  局,因此是较重的操作。会触发回流的操作:

 

⻚⾯初次渲染

浏览器窗⼝⼤⼩改变

元素尺⼨、位置、内容发⽣改变元素字体⼤⼩变化

加或者删除可⻅的 dom 元素

CSS 伪类(例如 :hover 

查询某些属性或调⽤某些⽅法

  clientWidth、clientHeight、clientTop、clientLeft offsetWidth、

  offsetHeight、offsetTop、offsetLeft

  scrollWidth、scrollHeight、scrollTop、scrollLeft

  getComputedStyle()

  getBoundingClientRect()

  scrollTo()

 

回流必定触发重绘,重绘不⼀定触发回流。重绘的开销较⼩,回流的代价较高

 

最佳实践:

css

免使⽤ table 布局

将动画效果应⽤到 position 属性为 absolute fixed 的元素上

 

javascript

避免频繁操作样式,可汇总后统 次修改

尽量使⽤ class 进⾏样式修改

减少 dom 的增删次数,可使⽤ 字符串 或者 documentFragment ⼀次性插⼊

极限优化时,修改样式可将其 display: none 后修改

避免多次触发上⾯提到的那些会触发回流的⽅法,可以的话尽量⽤ 变量存住

 

6.存储

 

我们经常需要对业务中的⼀些数据进⾏存储,通常可以分为 性存储 久性储存。

短暂性的时候,我们只需要将数据存在内存中,只在运⾏时可⽤ 持久性存储,可以分为 浏览器 服务器端

 

浏览器:

cookie : 通常⽤于存储⽤户身份,登录状态等

  http 中⾃动携带 体积上限为 4K 可⾃⾏设置过期时间

localStorage / sessionStorage : ⻓久储存/窗⼝关闭删除 体积限制为 4~5M

indexDB

 

服务器:

分布式缓存 redis

数据库

 

7.Web Worker

 

现代浏览器 JavaScript 创造 多线程环境。可以新建并将部分任务分配 worker 线程并⾏运⾏,两个线程可 独⽴运⾏,互不⼲扰,可通过⾃带的消息机 相互通信。

 

基本⽤法:

 

// 创 建 worker

const worker = new Worker('work.js');

 

// 向主进程推送消息

worker.postMessage('Hello World');

 

// 监听主进程来的消息

worker.onmessage = function (event) { 

    console.log('Received message ' + event.data);

}

 

限制:

 

同源限制

⽆法使⽤ document / window / alert / confirm

⽆法加载本地资源

 

8.内存泄露

 

意外的全局变量: ⽆法被回收

定时器: 未被正确关闭,导致所引⽤的外部变量⽆法被释放事件

监听: 没有正确销毁 (低版本浏览器可能出现)

闭包: 会导致⽗级中的变量⽆法被释放

dom 引⽤: dom 元素被删除时,内存中的引⽤未被正确清空

 

可⽤ chrome 中的 timeline 进⾏内存标记,可视化查看内存的变化情况,找出异常点。

你可能感兴趣的