浏览器相关
常见浏览器内核
浏览器最重要或者说核心的部分是“Rendering Engine”,可大概译为“渲染引擎”,不过我们一般习惯将之称为“浏览器内核”。负责对网页语法的解释(如标准通用标记语言下的一个应用HTML、JavaScript)并渲染(显示)网页。 所以,通常所谓的浏览器内核也就是浏览器所采用的渲染引擎,渲染引擎决定了浏览器如何显示网页的内容以及页面的格式信息。不同的浏览器内核对网页编写语法的解释也有不同,因此同一网页在不同的内核的浏览器里的渲染(显示)效果也可能不同。
浏览器 | 内核(渲染引擎) | JavaScript引擎 |
Chrome
|
Blink(28~)
Webkit(Chrome 27)
|
V8
|
FireFox
|
Gecko
|
SpiderMonkey
|
Safari
|
Webkit
|
JavaScriptCore
|
Edge
|
EdgeHTML
|
Chakra(for JavaScript)
|
IE
|
Trident
|
Chakra(for JScript)
|
PhantomJS
|
Webkit
|
JavaScriptCore
|
浏览器组成
浏览器的主要组成部分包括:
- 用户界面:包括地址栏、前进/后退按钮、书签菜单等。除了浏览器主窗口显示的请求外,其他显示的各个部分都属于用户界面。
- 浏览器引擎:在用户界面和呈现引擎之间传送指令。
- 渲染引擎:负责显示请求的内容。如果请求的内容是 HTML,它就负责解析 HTML 和 CSS 内容,并将解析后的内容显示在屏幕上。(渲染引擎是单线程的,除了网络操作以外,几乎所有的事情都在单一的线程中处理,在Firefox和Safari中,这是浏览器的主线程,Chrome中这是tab的主线程。)
- 网络:用户网络调用,比如 HTTP 请求。其接口与平台有关,并为所有平台提供底层实现。(网络操作由几个并行线程执行,并行连接的个数是受限的,通常是2-6个)
- 用户界面后端:用于绘制基本的窗口部件,比如组合框和窗口。其公开了与平台相关的通用接口,并在底层使用操作系统的用户界面方法。
- JavaScript解释器:用于解析和执行 JavaScript 代码。
- 数据存储:这是持久层。浏览器需要在硬盘上保存各种数据,例如 Cookie。新的 HTML 规范 (HTML5) 定义了“网络数据库”,这是个完整(但是轻便)的浏览器内数据库。
回流(重排)和重绘
当Render Tree
中部分或全部元素的尺寸、结构、或某些属性发生改变时,浏览器重新渲染部分或全部文档的过程称为回流。具体表现为重新生成布局,重新排列元素。
当页面中元素样式的改变并不影响它在文档流中的位置时(例如:color
、background-color
、visibility
等),浏览器会将新样式赋予给元素并重新绘制它,这个过程称为重绘。具体表现为某些元素的外观被改变。
单单改变元素的外观,肯定不会引起网页重新生成布局,但当浏览器完成重排之后,将会重新绘制收到此次重排影响的部分,所以重绘不一定会出现重排,重排必然会出现重绘。
重排和重绘的代价是高昂的,它们会破坏用户体验,并且让UI展示非常迟缓,而相比之下,重排对性能的影响更大,在两者无法避免的情况下,宁可选择代价更小的重绘。
重排和重绘的产生
- DOM节点的增删改
- 通过display:none隐藏一个DOM节点会触发重排和重绘,通过visibility:hidden隐藏一个DOM节点只触发重绘
- 移动或者给页面中的DOM节点添加动画
- 添加样式表,调整样式属性
- 用户行为,例如调整窗口大小、改变字号、滚动等
减少或避免重绘重排
1,集中改变样式
2,使用eDocumentFragment
3,提升为合成层
跨域
浏览器同源策略
-
<img src=XXX>
-
<link href=XXX>
-
<script src=XXX>
浏览器出于安全考虑,是同源策略的,只要协议、端口、域名有一个不相同就非同源了。此时,一个域下的文档或脚本试图去请求另一个域下的资源,就产生了我们说的跨域。
虽然同源策略是浏览器的一种安全机制,但是如果为了安全,拒绝了所有的外部请求(跨域实际上请求是发出了,只是浏览器拦截了响应),在实际工作中是不太现实的,因此,我们需要进行跨域请求。下面,简单列举一些常用的跨域方案。
JSONP
jsonp本质上是一个Hack,利用<script>标签不受同源策略限制的特性,通过<script>标签指向一个需要访问的地址并提供一个回调函数来接收数据。
实现
function JSONP({ url, params, callbackKey, callback }){ params = params || {} ; params[callbackKey] = 'jsonpCallback' ; window.jsonpCallback = callback ; const paramKeys = Object.keys(params) ; const paramString = paramKeys .map(key => `${key}=${params[key]}`) .join('&') const script = document.createElement('script'); script.setAttribute('src', `${url}?${paramString}`) document.body.appendChild(script) } JSONP({ url: 'xxx', params: { key: 'aa', }, callbackKey: 'bb', callback(result) { console.log(result.data) } })
优缺点:
- 优点:实现简单,兼容性好
- 缺点:只支持get请求,容易遭受xss攻击,需要服务端配合
cors
var allowCrossDomain = function(req, res, next) { res.header('Access-Control-Allow-Origin', 'http://test.com'); res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE'); res.header('Access-Control-Allow-Headers', 'Content-Type'); next(); }
Nginx
HTML5
WebSocket
window.name + iframe
location.hash + iframe
document.domain + iframe
即时通讯
前端实现即时通讯的常见方式包括以下几种:
短轮询
-
优点:兼容性强,实现⾮常简单
-
缺点:延迟性⾼,⾮常消耗请求资源,浪费带宽,影响性能
comet
⻓轮询
服务端接收客户端请求后暂时挂起,等待数据更新,有数据更新则响应,否则等到达到服务端设置的时间限制后再响应。客户端接收到响应后会再发出请求,重新建立连接,如此往复。
-
优点:兼容性好,减少了请求次数,资源浪费较⼩
-
服务器hold连接会消耗资源,返回数据顺序⽆保证,难于管理维护
⻓连接
-
优点:兼容性好,消息即时到达,不发⽆⽤请求
-
缺点:服务器维护⻓连接消耗资源
Websocket
-
优点:真正意义上的实时双向通信,性能好,低延迟
-
缺点:独⽴与http的协议,因此需要额外的项⽬改造,使⽤复杂度⾼,必须引⼊成熟的库,⽆法兼容低版本浏览器
SSE
-
优点:基于HTTP⽽⽣,因此不需要太多改造就能使⽤,使⽤⽅便,⽽websocket⾮常复杂,必须借助成熟的库或框架
-
缺点:基于⽂本传输效率没有websocket⾼,不是严格的双向通信,客户端向服务端发送请求⽆法复⽤之前的连接,需要重新发出独⽴的请求