浏览器相关

常见浏览器内核

 浏览器最重要或者说核心的部分是“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 

 

浏览器组成

浏览器的主要组成部分包括:

  1. 用户界面:包括地址栏、前进/后退按钮、书签菜单等。除了浏览器主窗口显示的请求外,其他显示的各个部分都属于用户界面。
  2. 浏览器引擎:在用户界面和呈现引擎之间传送指令。
  3. 渲染引擎:负责显示请求的内容。如果请求的内容是 HTML,它就负责解析 HTML 和 CSS 内容,并将解析后的内容显示在屏幕上。(渲染引擎是单线程的,除了网络操作以外,几乎所有的事情都在单一的线程中处理,在Firefox和Safari中,这是浏览器的主线程,Chrome中这是tab的主线程。)
  4. 网络:用户网络调用,比如 HTTP 请求。其接口与平台有关,并为所有平台提供底层实现。(网络操作由几个并行线程执行,并行连接的个数是受限的,通常是2-6个)
  5. 用户界面后端:用于绘制基本的窗口部件,比如组合框和窗口。其公开了与平台相关的通用接口,并在底层使用操作系统的用户界面方法。
  6. JavaScript解释器:用于解析和执行 JavaScript 代码。
  7. 数据存储:这是持久层。浏览器需要在硬盘上保存各种数据,例如 Cookie。新的 HTML 规范 (HTML5) 定义了“网络数据库”,这是个完整(但是轻便)的浏览器内数据库。

回流(重排)和重绘

Render Tree中部分或全部元素的尺寸、结构、或某些属性发生改变时,浏览器重新渲染部分或全部文档的过程称为回流。具体表现为重新生成布局,重新排列元素。

当页面中元素样式的改变并不影响它在文档流中的位置时(例如:colorbackground-colorvisibility等),浏览器会将新样式赋予给元素并重新绘制它,这个过程称为重绘。具体表现为某些元素的外观被改变。

单单改变元素的外观,肯定不会引起网页重新生成布局,但当浏览器完成重排之后,将会重新绘制收到此次重排影响的部分,所以重绘不一定会出现重排,重排必然会出现重绘。

重排和重绘的代价是高昂的,它们会破坏用户体验,并且让UI展示非常迟缓,而相比之下,重排对性能的影响更大,在两者无法避免的情况下,宁可选择代价更小的重绘。

重排和重绘的产生

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

减少或避免重绘重排

1,集中改变样式

2,使用eDocumentFragment

通过createDocumentFragment创建⼀个游离于DOM树之外的节点,然后在此节点上批量操作,最后插⼊DOM树中,因此只触发⼀次重排

 3,提升为合成层

跨域

 浏览器同源策略

同源策略限制了从同⼀个源加载的⽂档或脚本如何与来⾃另⼀个源的资源进⾏交互。这是⼀个⽤于隔离潜在恶意⽂件的重要安全机制。
同源是指"协议+域名+端⼝"三者相同,即便两个不同的域名指向同⼀个ip地址,也⾮同源。
浏览器中的⼤部分内容都是受同源策略限制的,但是以下三个标签可以不受限制:
  • <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

cors是⽬前主流的跨域解决⽅案,跨域资源共享(CORS) 是⼀种机制,它使⽤额外的 HTTP 头来告诉浏览器 让运⾏在⼀个 origin (domain) 上的Web应⽤被准许访问来⾃不同源服务器上的指定的资源。当⼀个资源从与该资源本身所在的服务器不同的域、协议或端⼝请求⼀个资源时,资源会发起⼀个跨域 HTTP 请求。
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

nginx是⼀款极其强⼤的web服务器,其优点就是轻量级、启动快、⾼并发。
⽤node或者java开发的服务通常都需要经过nginx的反向代理。反向代理的原理很简单,即所有客户端的请求都必须先经过nginx的处理,nginx作为代理服务器再讲请求转发给node或者java服务,这样就规避了同源策略。

HTML5

XMLHttpRequest 有⼀个API,postMessage()⽅法允许来⾃不同源的脚本采⽤异步⽅式进⾏有限的通信,可以实现跨⽂本档、多窗⼝、跨域消息传递。

WebSocket 

WebSocket 是⼀种双向通信协议,在建⽴连接之后,WebSocket 的 server 与 client 都能主动向对⽅发送或接收数据,连接建⽴好了之后 client 与 server 之间的双向通信就与 HTTP ⽆关了,因此可以跨域。

window.name + iframe

window.name属性值在不同的⻚⾯(甚⾄不同域名)加载后依旧存在,并且可以⽀持⾮常⻓的 name 值,我们可以利⽤这个特点进⾏跨域。

location.hash + iframe

a.html欲与c.html跨域相互通信,通过中间⻚b.html来实现。 三个⻚⾯,不同域之间利⽤iframe的location.hash传值,相同域之间直接js访问来通信。

document.domain + iframe

该⽅式只能⽤于⼆级域名相同的情况下,⽐如 a.test.com 和 b.test.com 适⽤于该⽅式,我们只需要给⻚⾯添加 document.domain ='test.com' 表示⼆级域名都相同就可以实现跨域,两个⻚⾯都通过js强制设置document.domain为基础主域,就实现了同域。

即时通讯

前端实现即时通讯的常见方式包括以下几种:

短轮询

短轮询的原理就是每隔⼀段时间客户端就发出⼀个请求,去获取服务器最新的数据,⼀定程度上模拟实现了即时通讯。
  • 优点:兼容性强,实现⾮常简单
  • 缺点:延迟性⾼,⾮常消耗请求资源,浪费带宽,影响性能

comet

comet有两种主要实现⼿段,⼀种是基于 AJAX 的⻓轮询(long-polling)⽅式,另⼀种是基于 Iframe 及 htmlfile 的流(streaming)⽅式,通常被叫做⻓连接。

⻓轮询

服务端接收客户端请求后暂时挂起,等待数据更新,有数据更新则响应,否则等到达到服务端设置的时间限制后再响应。客户端接收到响应后会再发出请求,重新建立连接,如此往复。

  • 优点:兼容性好,减少了请求次数,资源浪费较⼩
  • 服务器hold连接会消耗资源,返回数据顺序⽆保证,难于管理维护

 ⻓连接

  • 优点:兼容性好,消息即时到达,不发⽆⽤请求
  • 缺点:服务器维护⻓连接消耗资源

Websocket

Websocket是⼀个全新的、独⽴的协议,基于TCP协议,与http协议兼容、却不会融⼊http协议,仅仅作为html5的⼀部分,其作⽤就是在服务器和客户端之间建⽴实时的双向通信。
  • 优点:真正意义上的实时双向通信,性能好,低延迟
  • 缺点:独⽴与http的协议,因此需要额外的项⽬改造,使⽤复杂度⾼,必须引⼊成熟的库,⽆法兼容低版本浏览器

SSE

SSE(Server-Sent Event,服务端推送事件)是⼀种允许服务端向客户端推送新数据的HTML5技术。
  • 优点:基于HTTP⽽⽣,因此不需要太多改造就能使⽤,使⽤⽅便,⽽websocket⾮常复杂,必须借助成熟的库或框架
  • 缺点:基于⽂本传输效率没有websocket⾼,不是严格的双向通信,客户端向服务端发送请求⽆法复⽤之前的连接,需要重新发出独⽴的请求
posted on 2019-09-24 19:34  紅葉  阅读(200)  评论(0编辑  收藏  举报