浏览器原理
一、 浏览器进程和线程
1.1 有哪些进程?
- 浏览器进程(Browser Process) :负责管理界面显示、用户交互、子进程管理和网络资源管理等。
- 渲染进程(Renderer Process) :每个Tab页一般对应一个渲染进程,负责HTML、CSS、JavaScript的解析和页面渲染。
- 网络进程(Network Process) :处理所有Tab页的网络请求,如HTTP/HTTPS请求。
- GPU进程(GPU Process) :用于处理与图形和视频加速相关的任务,比如硬件加速的Compositing层、3D绘制等,减轻了CPU负担并提高了图形处理效率。
- 插件进程(Plugin Process) :运行浏览器插件,如Flash插件,每个插件在一个独立的进程中运行以提高稳定性。
- 扩展进程(Extension Process) :部分浏览器扩展也可能运行在它们自己的进程中,以保持独立性和稳定性。
1.2 为什么采用多进程架构?
- 安全隔离:如果某个网页或插件出现问题,只会影响其所在的渲染进程,不会影响到浏览器的其他部分或其他标签页。
- 稳定性:类似地,一个页面崩溃不会导致整个浏览器崩溃。
- 性能:多进程可以利用多核CPU进行并行处理,提升渲染速度和响应能力。
1.3 渲染进程中有哪些主要线程?
- 主线程:负责执行JavaScript代码、样式计算、布局和绘制等任务。
- GUI线程:与操作系统交互,更新界面元素。
- 事件处理线程:监听和分发用户输入等事件到主线程。
- 定时器线程:管理setTimeout和setInterval等定时器,到达时间后将任务添加到主线程的任务队列中。
- 渲染线程:负责页面的布局和绘制,但需要注意的是,并非所有浏览器都严格区分渲染线程,某些操作可能仍在主线程中完成。
二、带着 浏览器 tab页是子进程吗?肯定是一个进程吗?什么情况下不是一个进程? 问题看一下内容
在现代浏览器的多进程架构中,每个Tab页通常对应一个独立的渲染进程(Renderer Process),这是为了实现更好的隔离性和稳定性。因此,从这个意义上说,可以认为每个Tab页对应的是一个子进程。
然而,也有例外情况,主要是为了优化资源使用和效率,浏览器可能会选择不为每个Tab分配独立的进程,具体如下:
- 同一站点的多个Tab共享进程:如果多个Tab属于同一个站点(即具有相同的eTLD+1,即有效顶级域加一级域名),浏览器可能会让它们共享一个渲染进程。这样做可以减少内存消耗,因为共享进程可以共享一些资源,如缓存的JavaScript文件和样式表。
- 进程限制:浏览器会根据系统的资源状况限制渲染进程的数量。当打开大量Tab页时,为了防止资源过度消耗,浏览器可能会开始复用已有的渲染进程,即使这些Tab属于不同的站点。
- 特殊页面或内嵌框架:浏览器内置页面(如新标签页、设置页)或者页面内的iframe可能不遵循普通Tab的进程分配规则,它们可能运行在特定的进程中或与父Tab共享进程。
总的来说,尽管大多数情况下每个Tab页背后是一个独立的渲染进程,但在某些优化策略或特定场景下,可能会出现Tab页不完全对应一个独立进程的情况。这种设计旨在平衡资源使用、安全性和性能。
三、了解什么是Web Worker?它解决了什么问题!
Web Worker是HTML5引入的一个API,它允许在浏览器后台独立于主线程运行脚本,即允许JavaScript脚本进行多线程处理。Web Worker解决了以下问题:
- 避免阻塞UI:通过将耗时的计算任务移到Worker线程中执行,主线程可以继续处理用户交互和页面渲染,从而避免页面卡顿。
- 提升用户体验:使复杂应用能够实现更流畅的交互和更快的响应。
四、前端实现安全的XSS(跨站脚本攻击)防护
1. 输入验证与过滤
- 始终验证用户输入:不论是表单提交、URL参数还是任何其他用户可控的数据,都应该进行严格的验证,确保数据符合预期的格式和内容。
- 使用白名单过滤:只允许特定字符或模式通过,拒绝不合法的输入。避免使用黑名单过滤,因为很难覆盖所有可能的恶意输入。
2. HTML编码(转义)
- 对输出到HTML中的所有用户提供的数据使用适当的编码(如使用
htmlspecialchars()函数在PHP中,或者在JavaScript中使用.innerText而非.innerHTML),以防止数据被解释为HTML或JavaScript代码。
3. 使用HTTP头部保护
- 设置
Content-Security-Policy (CSP)头部,限制哪些源可以加载脚本、样式等资源,有效阻止未授权的脚本执行。 - 启用
X-XSS-Protection头部,虽然现代浏览器逐渐不再支持这个头部,但它过去被用来指示浏览器是否应该开启自身的XSS过滤机制。
4. 使用安全的API
- 当需要插入不可信数据到DOM时,使用像
textContent而不是innerHTML,这样可以避免执行潜在的恶意脚本。 - 利用DOM的API,如
document.createElement()和属性设置方法,来创建和修改DOM元素,而不是直接拼接HTML字符串。
5. JSON.parse与JSON.stringify
- 接收和发送JSON数据时,使用
JSON.parse解析JSON字符串,避免使用eval,因为它可以执行任意JavaScript代码。 - 发送数据回服务器时,使用
JSON.stringify序列化对象,确保数据的安全传输。
6. 同源策略与CORS
- 理解并利用同源策略限制不同源之间的数据交互,对于需要跨域的请求,正确配置CORS(跨源资源共享)策略,严格控制允许访问的源。
7. 教育与培训
- 提升开发团队对XSS攻击及其防范方法的认识,定期进行安全培训,确保所有成员都能遵循最佳安全实践。
8. 使用安全框架和库
- 采用已知的安全Web框架和库,这些工具通常内置了一些XSS防护机制,减少手动编写安全代码的负担。
9. 定期安全审计与测试
- 定期进行代码审查,专门检查XSS漏洞。
- 使用自动化安全扫描工具进行定期的安全测试,包括动态应用安全测试(DAST)和静态应用安全测试(SAST),以及渗透测试。
五、DOMContentLoaded事件和load事件的区别
在Web开发中,DOMContentLoaded事件和load事件都是用于监听文档加载状态的,但它们之间存在一些关键区别:
DOMContentLoaded 事件
- 触发时机:
DOMContentLoaded事件在文档解析完成时触发,这意味着此时DOM树已经构建完成,JavaScript可以访问和操作所有的DOM元素。但这并不意味着所有外部资源(如图片、样式表、外部脚本等)都已经加载完毕。 - 用途:如果你的脚本只需要访问和操作DOM元素,而不需要等待图片或其他外部资源加载完成,那么绑定到
DOMContentLoaded事件是一个好选择。这样可以尽快执行脚本,提升页面的初始渲染速度和交互性。
load 事件
- 触发时机:
load事件在页面所有资源(包括图片、脚本、样式表等)加载完成后触发。这意味着不仅DOM树构建完成,而且所有相关资源都已加载完毕,页面达到了完全加载的状态。 - 用途:如果你的脚本需要依赖于某些外部资源(如图片尺寸、特定脚本的执行结果等)才能正常运行,那么你应该将脚本绑定到
load事件上。但要注意,由于必须等待所有资源加载完毕,这可能导致页面的初始化过程变慢。
总结
- 执行时机:
DOMContentLoaded通常比load事件更早触发。 - 资源依赖:
DOMContentLoaded仅需DOM构建完成,而load需要所有资源加载完毕。 - 应用场景:如果你的脚本主要关注DOM操作,使用
DOMContentLoaded;如果脚本执行需要依赖页面上的所有资源,使用load事件。
选择合适的事件,可以确保脚本在最恰当的时机执行,既不延误也不提前,从而优化用户体验和页面性能。
六、 优化前端页面的加载速度方法!
1. 压缩资源文件
- 压缩CSS、JavaScript:使用工具如UglifyJS(JavaScript)和CleanCSS(CSS)来压缩代码,移除不必要的空白字符、注释和缩短变量名,减小文件体积。
- 图片压缩:对图片进行有损或无损压缩,使用像ImageOptim、TinyPNG等工具,减小图片文件大小而不牺牲太多质量。
2. 使用CDN(内容分发网络)
- 将静态资源(如图片、CSS、JavaScript文件)部署到CDN上,利用CDN的全球节点,让用户从最近的服务器获取资源,减少延迟。
3. 异步加载和延迟加载
- 异步加载脚本:使用
async或defer属性加载JavaScript文件,避免它们阻塞页面渲染。 - 懒加载图片:仅在图片即将进入可视区域时才开始加载,可以使用Intersection Observer API实现。
4. 代码拆分与按需加载
- 将大的JavaScript和CSS文件拆分成小块,仅在需要时加载相应的代码块,减少初次加载的资源量。
5. 开启GZIP压缩
- 服务器端开启GZIP压缩,进一步压缩文本资源(如HTML、CSS、JavaScript),在传输过程中减小数据量。
6. 优化缓存策略
- 使用HTTP缓存策略,如设置合理的Expires或Cache-Control头,让浏览器缓存静态资源,减少重复请求。
7. 减少HTTP请求
- 合并CSS和JavaScript文件,减少文件数量,从而减少HTTP请求次数。
- 使用CSS Sprites技术合并小图标为一张大图,减少图片请求。
8. 使用预加载和预读取
- 利用
<link rel="preload">提前加载关键资源,如首屏需要的CSS和JavaScript。 - 利用
<link rel="prefetch">预读取后续可能需要的资源,如下一页的内容。
9. 优化CSS和JavaScript执行
- 避免在CSS中使用昂贵的选择器,减少样式计算的开销。
- 将JavaScript放在文档底部,或使用
defer属性,确保DOM构建不受脚本加载和执行的阻塞。
10. 可以根据浏览器WEB性能衡量指标来针对性的优化
- 首字节时间 (Time to First Byte, TTFB) :TTFB是指浏览器向服务器发出请求到接收到响应的第一个字节之间的时间。它反映了服务器处理请求的速度,包括网络传输时间和服务器处理时间。
- 首次内容绘制 (First Contentful Paint, FCP) :FCP是页面开始在视口渲染任何文本、图像或其他媒体内容的时间点。这是用户感受到页面开始加载的第一个视觉信号。
- 最大内容绘制 (Largest Contentful Paint, LCP) :LCP测量的是页面最大的可见元素(如图像、视频或文本块)完成渲染的时间。它是衡量页面主要内容加载完成的一个重要指标。
- 首次输入延迟 (First Input Delay, FID) :FID衡量的是用户首次与页面交互(如点击按钮)到浏览器实际能够响应该交互之间的时间差。它反映了页面对用户交互的响应能力。
- 累计布局偏移 (Cumulative Layout Shift, CLS) :CLS用来量化页面在加载过程中发生的意外布局偏移,导致用户注意力被分散或点击错误的情况。值越低代表用户体验越好。
- 完全加载时间 (Fully Loaded Time) :这个指标指的是从页面开始加载到所有资源(包括第三方脚本、图片等)完全下载完毕所需的时间。
- 页面速度指数 (Page Speed Index, PSI) :PSI尝试模拟真实用户感受的页面加载速度,通过视频录制加载过程并分析可视内容的显示情况来评分。
- 可交互时间 (Time to Interactive, TTI) : TTI指页面达到可交互状态所需的时间,即用户可以流畅地与页面进行交互(如点击、滚动)而不会感到延迟的时间点。
后续总结了其他问题再进行补充添加!!!希望多多支持~~~谢谢🤡🤡🤡