- 博客(112)
- 收藏
- 关注
原创 浏览器工作原理15 [#]消息队列和事件循环:页面是怎么活起来的
如果有一些确定好的任务,可以使用一个单线程来按照顺序处理这些任务,这是第一版线程模型。要在线程执行过程中接收并处理新的任务,就需要引入循环语句和事件系统,这是第二版线程模型。如果要接收其他线程发送过来的任务,就需要引入消息队列,这是第三版线程模型。如果其他进程想要发送任务给页面主线程,那么先通过 IPC 把任务发送给渲染进程的 IO 线程,IO 线程再把任务发送给页面主线程。消息队列机制并不是太灵活,为了适应效率和实时性,引入了微任务。
2025-06-12 14:54:33
364
原创 浏览器工作原理14 [#]编译器和解析器:V8如何执行一段JavaScript代码的
首先我们介绍了编译器和解释器的区别。紧接着又详细分析了 V8 是如何执行一段 JavaScript 代码的:V8 依据 JavaScript 代码生成 AST 和执行上下文,再基于 AST 生成字节码,然后通过解释器执行字节码,通过编译器来优化编译字节码。基于字节码和编译器,我们又介绍了 JIT 技术。最后我们延伸说明了下优化 JavaScript 性能的一些策略。编译器和解释器的相关概念和理论对于程序员来说至关重要,向上能让你充分理解一些前端应用的本质,向下能打开计算机编译原理的大门。
2025-06-11 17:39:42
488
原创 浏览器工作原理13 [#]垃圾回收:垃圾数据如何自动回收
首先我们介绍了不同语言的垃圾回收策略,然后又说明了栈中的数据是如何回收的,最后重点讲解了 JavaScript 中的垃圾回收器是如何工作的。从上面的分析你也能看出来,无论是垃圾回收的策略,还是处理全停顿的策略,往往都没有一个完美的解决方案,你需要花一些时间来做权衡,而这需要牺牲当前某几方面的指标来换取其他几个指标的提升。其实站在工程师的视角,我们经常需要在满足需求的前提下,权衡各个指标的得失,把系统设计得尽可能适应最核心的需求。生活中处理事情的原则也与之类似,古人很早就说过“
2025-06-11 15:20:33
345
原创 浏览器工作原理12 [#]栈空间和堆空间:数据是如何存储的
好了,今天就讲到这里,下面我来简单总结下今天的要点。我们介绍了 JavaScript 中的 8 种数据类型,它们可以分为两大类——原始类型和引用类型。其中,原始类型的数据是存放在栈中,引用类型的数据是存放在堆中的。堆中的数据是通过引用和变量关联起来的。也就是说,JavaScript 的变量是没有数据类型的,值才有数据类型,变量可以随时持有任何类型的数据。然后我们分析了,在 JavaScript 中将一个原始类型的变量 a 赋值给 b,那么 a 和 b 会相互独立、互不影响;
2025-06-10 14:00:00
705
原创 浏览器工作原理11 [#] this:从JavaScript执行上下文视角讲this
当函数作为对象的方法调用时,函数中的 this 就是该对象;当函数被正常调用时,在严格模式下,this 值是 undefined,非严格模式下 this 指向的是全局对象 window;嵌套函数中的 this 不会继承外层函数的 this 值。箭头函数中,因为箭头函数没有自己的执行上下文,所以箭头函数的 this 就是它外层函数的 this。
2025-06-09 21:15:00
1397
原创 浏览器工作原理10 [#]作用域链和闭包:代码中出现相同的变量,JavaScript引擎如何选择
好了,今天的内容就讲到这里,下面我们来回顾下今天的内容:首先,介绍了什么是作用域链,我们把通过作用域查找变量的链条称为作用域链;作用域链是通过词法作用域来确定的,而词法作用域反映了代码的结构。其次,介绍了在块级作用域中是如何通过作用域链来查找变量的。最后,又基于作用域链和词法环境介绍了到底什么是闭包。通过展开词法作用域,我们介绍了 JavaScript 中的作用域链和闭包;
2025-06-09 14:45:57
1008
原创 浏览器工作原理09 [#] 块级作用域:var缺陷以及为什么要引入let和const
由于JavaScript的变量提升存在着变量覆盖、变量污染等设计缺陷,所以ES6引入了块级作用域关键字来解决这些问题。之后我们还通过对变量环境和词法环境的介绍,分析了JavaScript引擎是如何同时支持变量提升和块级作用域的。既然聊到了作用域,那最后我们再简单聊下编程语言吧。经常有人争论什么编程语言是世界上最好的语言,但如果站在语言本身来说,我觉得这种争论没有意义,因为语言是工具,而工具是用来创造价值的,至于能否创造价值或创造多大价值不完全由语言本身的特性决定。
2025-06-07 18:37:16
586
原创 浏览器工作原理08 [#]调用栈:为什么JavaScript代码会出现栈溢出
函数调用就是运行一个函数,具体使用方式是使用函数名称跟着一对小括号。下面我们看个简单的示例代码var a = 2var b = 10return a+badd()这段代码很简单,先是创建了一个add函数,接着在代码的最下面又调用了该函数。那么下面我们就利用这段简单的代码来解释下函数调用的过程。在执行到函数add()之前,JavaScript引擎会为上面这段代码创建全局执行上下文,包含了声明的函数和变量,你可以参考下图:从图中可以看出,代码中全局变量和函数都保存在全局上下文的变量环境中。
2025-06-07 17:36:10
817
原创 浏览器工作原理07 [#] 变量提升:JavaScript代码是按顺序执行的吗
JavaScript代码执行过程中,需要先做变量提升,而之所以需要实现变量提升,是因为JavaScript代码在执行之前需要先编译。在编译阶段,变量和函数会被存放到变量环境中,变量的默认值会被设置为undefined;在代码执行阶段,JavaScript引擎会从变量环境中去查找自定义的变量和函数。如果在编译阶段,存在两个相同的函数,那么最终存放在变量环境中的是最后定义的那个,这是因为后定义的会覆盖掉之前定义的。JavaScript的执行机制:先编译,再执行。
2025-06-06 14:53:30
899
原创 浏览器工作原理06 [#]渲染流程(下):HTML、CSS和JavaScript是如何变成页面的
好了,我们现在已经分析完了整个渲染流程,从HTML到DOM、样式计算、布局、图层、绘制、光栅化、合成和显示。结合上图,一个完整的渲染流程大致可总结为如下渲染进程将HTML内容转换为能够读懂的DOM树结构。渲染引擎将CSS样式表转化为浏览器可以理解的styleSheets,计算出DOM节点的样式。创建布局树,并计算元素的布局信息。对布局树进行分层,并生成分层树。为每个图层生成绘制列表,并将其提交到合成线程。合成线程将图层分成图块,并在光栅化线程池中将图块转换成位图。
2025-06-06 11:12:49
1129
原创 浏览器工作原理05 [#] 渲染流程(上):HTML、CSS和JavaScript是如何变成页面的
从图中可以看出,本节内容我们介绍了渲染流程的前三个阶段:DOM生成、样式计算和布局。浏览器不能直接理解HTML数据,所以第一步需要将其转换为浏览器能够理解的DOM树结构;生成DOM树后,还需要根据CSS样式表,来计算出DOM树所有节点的样式;最后计算DOM元素的布局信息,使其都保存在布局树中。
2025-06-06 10:55:34
1154
原创 浏览器工作原理03 [#] HTTP请求流程:为什么很多站点第二次打开速度会很快
为了便于你理解,我画了下面这张详细的“HTTP请求示意图”,用来展现浏览器中的HTTP请求所经历的各个阶段。从图中可以看到,浏览器中的HTTP请求从发起到结束一共经历了如下八个阶段:构建请求、查找缓存、准备IP和端口、等待TCP队列、建立TCP连接、发起HTTP请求、服务器处理请求、服务器返回请求和断开连接。然后我还通过HTTP请求路径解答了两个经常会碰到的问题,一个涉及到了Cache流程,另外一个涉及到如何使用Cookie来进行状态管理。
2025-06-06 10:22:18
971
原创 浏览器工作原理04 [#]导航流程:从输入URL到页面展示这中间发生了什么
用户输入url并回车浏览器进程检查url,组装协议,构成完整的url浏览器进程通过进程间通信(IPC)把url请求发送给网络进程网络进程接收到url请求后检查本地缓存是否缓存了该请求资源,如果有则将该资源返回给浏览器进程如果没有,网络进程向web服务器发起http请求(网络请求),请求流程如下进行DNS解析,获取服务器ip地址,端口(端口是通过dns解析获取的吗?这里有个疑问)利用ip地址和服务器建立tcp连接构建请求头信息发送请求头信息。
2025-06-06 10:13:17
644
原创 浏览器工作原理02 [#] TCP协议:如何保证页面文件能被完整送达浏览器
互联网中的数据是通过数据包来传输的,数据包在传输过程中容易丢失或出错。IP负责把数据包送达目的主机。UDP负责把数据包送达具体应用。而TCP保证了数据完整地传输,它的连接可分为三个阶段:建立连接、传输数据和断开连接。其实了解TCP协议,是为了全方位了解HTTP,包括其实际功能和局限性,之后才会更加深刻地理解为什么要推出HTTP/2,以及为什么要推出QUIC协议,也就是未来的HTTP/3。这是一个由浅入深、循序渐进的过程,我希望你能稳扎稳打,学好这每一步、每一个协议,后面“水到自然渠成”。
2025-06-06 09:51:05
908
原创 浏览器工作原理01 [#]Chrome架构:仅仅打开了1个页面,为什么有4个进程
计算机中的并行处理就是同一时刻处理多个任务,比如我们要计算下面这三个表达式的值,并显示出结果A = 1+2B = 20/5C = 7*8任务1 是计算A=1+2;任务2 是计算B=20/5;任务3 是计算C=7*8;任务4 是显示最后计算的结果正常情况下程序可以使用单线程来处理,也就是分四步按照顺序分别执行这四个任务。如果采用多线程,会怎么样呢?我们只需分“两步走”:第一步,使用三个线程同时执行前三个任务;第二步,再执行第四个显示任务。
2025-06-06 09:43:07
869
转载 系统安全:页面和系统之间的隔离墙
首先我们分析了单进程浏览器在系统安全方面的不足,如果浏览器存在漏洞,那么黑客就有机会通过页面对系统发起攻击。因此在设计现代浏览器的体系架构时,就考虑到这个问题了。于是,在多进程的基础之上引入了安全沙箱,有了安全沙箱,就可以将操作系统和渲染进程进行隔离,这样即便渲染进程由于漏洞被攻击,也不会影响到操作系统的。由于渲染进程采用了安全沙箱,所以在渲染进程内部不能与操作系统直接交互,于是就在浏览器内核中实现了持久存储、网络访问和用户交互等一系列与操作系统交互的功能,然后通过 IPC 和渲染进程进行交互。
2025-05-30 18:23:04
31
转载 CSRF攻击:陌生链接不要随便点
CSRF 英文全称是 Cross-site request forgery,所以又称为“跨站请求伪造”,是指黑客引诱用户打开黑客的网站,在黑客的网站中,利用用户的登录状态发起的跨站请求。简单来讲,CSRF 攻击就是黑客利用了用户的登录状态,并通过第三方的站点来做一些坏事。通常当用户打开了黑客的页面后,黑客有三种方式去实施 CSRF 攻击。下面我们以极客时间官网为例子,来分析这三种攻击方式都是怎么实施的。#同时支持 POST 和Get。
2025-05-28 11:33:40
42
转载 跨站脚本攻击(XSS):为什么Cookie中有HttpOnly属性?
XSS 全称是,为了与“CSS”区分开来,故简称 XSS,翻译过来就是“跨站脚本”。XSS 攻击是指黑客往 HTML 文件中或者 DOM 中注入恶意脚本,从而在用户浏览页面时利用注入的恶意脚本对用户实施攻击的一种手段。最开始的时候,这种攻击是通过跨域来实现的,所以叫“跨域脚本”。但是发展到现在,往 HTML 文件中注入恶意代码的方式越来越多了,所以是否跨域注入脚本已经不是唯一的注入手段了,但是 XSS 这个名字却一直保留至今。
2025-05-20 19:40:40
40
转载 JS系列(十三) - 迭代器-生成器和await-async
迭代器(iterator),是确使用户可在容器对象(container,例如链表或数组)上遍访的对象,使用该接口无需关心对象的内部实现细节。其行为像数据库中的光标,迭代器最早出现在1974年设计的CLU编程语言中;在各种编程语言的实现中,迭代器的实现方式各不相同,但是基本都有迭代器,比如Java、Python等;从迭代器的定义我们可以看出来,迭代器是帮助我们对某个数据结构进行遍历的对象。在JavaScript中,迭代器也是一个具体的对象,这个对象需要符合。
2025-04-15 09:48:04
34
原创 Tailwind CSS v4.0 发布
Holy shit it's actually done !1 月 22 日,Tailwind CSS 正式发布了 4.0 版本,针对性能和灵活性进行了优化,重新构想了配置和定制体验,并充分利用了 Web 平台提供的最新进展。
2025-01-23 11:12:11
2301
2
转载 react19新特性12.5更新
React 团队于 2024 年 12 月 5 日正式发布了 React v19 稳定版,并在 npm 上可用。此次更新带来了许多令人期待的新特性和改进,开发者们可以通过 React 19 升级指南获取详细的升级步骤和注意事项。让我们看看在新的 19 版本中都带来了哪些变化呢?
2024-12-07 20:15:25
308
原创 算法题纪录(2)
我们可以用代码来模拟小明的赌钱策略,并计算最终是赚还是亏。关键点是赢的情况下钱加倍,输的情况下减半。在 2𝑛场中,赢了 𝑛 场,输了 𝑛 场,最终的结果只与赢输的顺序无关。小明最终不赚也不亏,因为每次押一半的策略使得资金在赢输数量相同的情况下保持恒定。无论赢输顺序如何,小明最终资金与初始资金相同,结果为持平。类似斐波那契数列,可以用双指针移动来解题。输出:小明刚开始有 46 块零花钱。
2024-11-22 10:29:58
340
原创 本地图片预览的方式
得到本地内存容器的URL地址,同步使用,比较方便快捷,多次使用需要注意手动释放内存的问题,性能优秀。胜在直接转为base64格式,可以直接用于业务,无需二次转换格式。
2024-08-17 14:29:59
370
原创 为什么推荐使用ref而不是reactive
reactive在使用过程中存在一些局限性,如果不额外注意这些问题,可能会给开发带来一些不便。与此不同,ref更像是Vue2时代的option API中的data的替代品,可以存放任何数据类型,而reactive声明的数据类型则仅限于对象。总体来说,非必要的情况下最好避免使用reactive。官方文档也强烈推荐使用ref()作为声明响应式状态的主要API。局限性问题: reactive本身存在一些局限性,可能会在开发过程中引发一些问题。这需要额外的注意力和处理,否则可能对开发造成麻烦。数据类型限制。
2024-07-09 21:32:57
1099
原创 跨域发送OPTIONS请求的条件
OPTIONS请求即预检请求,可用于检测服务器允许的http方法。当发起跨域请求时,由于安全原因,触发一定条件时浏览器会在正式请求之前自动先发起OPTIONS请求,即CORS预检请求,服务器若接受该跨域请求,浏览器才继续发起正式请求。
2024-07-03 23:42:25
1242
原创 TypeScript 中的 any 类型,unknown 类型,never 类型
为了解决any类型“污染”其他变量的问题,TypeScript 3.0 引入了unknown类型。它与any含义相同,表示类型不确定,可能是任意类型,但是它的使用有一些限制,不像any那样自由,可以视为严格版的any。unknown跟any的相似之处,在于所有类型的值都可以分配给unknown类型。x = true;// 正确x = 42;// 正确// 正确上面示例中,变量x的类型是unknown,可以赋值为各种类型的值。这与any的行为一致。unknown类型跟any类型的。
2024-07-02 23:16:03
1741
原创 闭包的不同形式
*闭包(closure)**是一个函数以及其捆绑的周边环境状态(lexical environment,词法环境)的引用的组合。换而言之,闭包让开发者可以从内部函数访问外部函数的作用域。在 JavaScript 中,闭包会随着函数的创建而被同时创建。无论通过何种形式,只要将内部函数传递到所在的词法作用域以外,它都会持有对原始作用域的引用,无论在何处执行这个函数都会使用闭包。
2024-07-02 22:57:24
325
原创 javascript 常见设计模式
在软件开发中,设计模式是解决特定问题的经验总结和可复用的解决方案。设计模式可以提高代码的复用性、可维护性和可读性,是提高开发效率的重要手段。
2024-07-01 21:49:01
1258
原创 前端路由三种模式: Hash 模式、 History 模式、 Memory模式
一般路由实现主要有history和hash两种方式hash的实现全部在前端,不需要后端服务器配合,兼容性好,主要是通过监听hashchange事件,处理前端业务逻辑history的实现,需要服务器做以下简单的配置,通过监听pushState及replaceState事件,处理前端业务逻辑。
2024-05-28 23:52:28
2031
转载 控制并发请求
Promise.all() 最简单的控制并发,但是请求出错会导致该组无返回值Promise.allSettled() 解决了Promise.all()的问题,但是却存在慢接口阻塞后续请求,且浪费其余并发位置的问题通过维护一个运行池,当运行池中有请求完成时便从等待队列中取一个心情求入池执行,直到所有的请求都入池介绍了社区的 p-limit库的使用方法和实现原理。
2024-04-28 20:35:35
187
原创 JS 可迭代对象 ( 使 var [a, b] = {a: 1, b: 2} 解构赋值 )
ES6中引入了迭代器与可迭代对象的概念,并且提供了对可迭代对象的相关支持,如for…of循环,Map(iterable)构造器,展开语法…等。让我们对数组外的数据集合的遍历操作也得到极大简化所谓可迭代对象,就是比普通对象多了一个名为Symbol.iterator方法的普通对象,这个方法返回一个迭代器。或者,一个具备Symbol.iterator同时具备next方法的对象也是一个可迭代的对象。。
2024-04-23 12:43:40
678
转载 HTTP 缓存
HTTP 的缓存机制,可以说这是前端工程师需要掌握的重要知识点之一。本文将针对 HTTP 缓存整体的流程做一个详细的讲解,争取做到大家读完整篇文章后,对缓存有一个整体的了解。HTTP 缓存分为 2 种,一种是强缓存,另一种是协商缓存。主要作用是可以加快资源获取速度,提升用户体验,减少网络传输,缓解服务端的压力。在实际使用场景中,图片、不常变化的 JS 等静态资源都会使用缓存来提高页面的加载速度。。
2024-04-14 22:43:00
98
转载 WebSocket 教程
随着 Web 的发展,用户对于 Web 的实时推送要求也越来越高,在 WebSocket 出现之前,大多数情况下是通过客户端发起轮询来拿到服务端实时更新的数据,因为HTTP1.x 协议有一个缺陷就是通信只能由客户端发起,服务端没法主动给客户端推送。这种方式在对实时性要求比较高的场景下,比如即时通讯、即时报价等,显然会十分低效,体验也不好。为了解决这个问题,便出现了WebSocket 协议,实现了客户端和服务端双向通信的能力。介绍WebSocket之前,还是让我们先了解下轮询实现推送的方式。
2024-04-14 21:59:40
126
转载 Cookie 和 Token 的区别
通俗地讲就是验证当前用户的身份,证明“你是你自己”(比如:你每天上下班打卡,都需要通过指纹打卡,当你的指纹和系统里录入的指纹相匹配时,就打卡成功)用户名密码登录邮箱发送登录链接手机号接收验证码只要你能收到邮箱/验证码,就默认你是账号的主人用户授予第三方应用访问该用户某些资源的权限你在安装手机应用的时候,APP 会询问是否允许授予权限(访问相册、地理位置等权限)你在访问微信小程序时,当登录时,小程序会询问是否允许授予权限(获取昵称、头像、地区、性别等个人信息)cookie。
2024-04-14 15:52:08
411
转载 HTTPS 加密原理
HTTPS(SSL/TLS)的加密机制虽然是大家都应了解的基本知识,但网上很多相关文章总会忽略一些内容,没有阐明完整的逻辑脉络,我学习它的时候也曾废了些功夫。对称与非对称加密、数字签名、数字证书等,在学习过程中,除了了解“它是什么”,你是否有想过“为什么是它”?我认为有必要搞清楚后者,否则你可能只是单纯地记住了被灌输的知识,而未真正理解它。本文以问题的形式逐步展开,一步步解开HTTPS的面纱,希望能帮助你彻底搞懂HTTPS!
2024-04-13 23:24:00
200
转载 使用 Web Worker 导出 Excel
在项目开发过程中,导出 Excel 文件是很常见的功能。根据生成 Excel 文件的方式,通常分为后端生成和前端生成。前端实现下载后端生成的 Excel 通常有两种方式,①是后端返回 Excel 文件的临时下载地址前端直接下载,②是后端返回 ArrayBuffer 二进制数据,前端处理后下载。而前端生成 Excel 就简单的多了,后端仅需返回指定格式的 JSON 数据就可以了,生成 Excel 这一步由前端浏览器完成,这样就可以大大减轻服务器压力,节约服务器资源。但是。
2024-04-13 23:19:02
379
原创 Web Worker 使用教程
众所周知,js最初设计是运行在浏览器中的,为了防止多个线程同时操作DOM,带来渲染冲突问题,所以js执行器被设计成单线程。但随着前端技术的发展,js能力远不止如此,当我们遇到需要大量计算的场景时(比如图像处理、视频解码等),js线程往往会被长时间阻塞,甚至造成页面卡顿,影响用户体验。为了解决单线程带来的这一弊端,Web Worker 应运而生。
2024-04-10 21:49:04
485
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人