1.重绘与重排
重排(也叫回流)reflow/Relayout
当元素的尺寸、结构或触发某些属性时,浏览器会重新渲染页面,称为回流。此时,浏览器需要重新经过计算,计算后还需要重新页面布局,因此是较重的操作。
浏览器渲染页面:浏览器渲染是基于“流式布局”的模型,流实际就使我们常说的文档流。浏览器根据渲染树中每个渲染对象的信息,计算出各自渲染对象的几何信息(DOM对象的位置和尺寸大小),并将其安置在界面中的正确位置。
会引起重排的操作有
- 页面首次渲染。
- 浏览器窗口大小发生改变。
- 元素尺寸或位置发生改变。
- 元素内容变化(文字数量或图片大小等等)。
- 元素字体大小变化。
- 添加或者删除可见的DOM元素。
- 激活CSS伪类(例如::hover)。
- 设置style属性
- 查询某些属性或调用某些方法。
重绘repaint
当元素样式的改变不影响布局时,浏览器将使用重绘对元素进行更新,此时由于只需要UI层面的重新像素绘制,因此损耗较少。比如修改字体颜色、背景、边框类型、阴影、显隐等。
重排一定会重绘,重绘不一定有重排。
避免重排
- 避免设置大量的style属性,因为通过设置style属性改变结点样式的话,每一次设置都会触发一次reflow,所以最好是使用class属性。
- 实现元素的动画,它的position属性,最好是设为absoulte或fixed,这样不会影响其他元素的布局。
- 动画实现的速度的选择。比如实现一个动画,以1个像素为单位移动这样最平滑,但是reflow就会过于频繁,大量消耗CPU资源,如果以3个像素为单位移动则会好很多。
- 不要使用table布局,因为table中某个元素旦触发了reflow,那么整个table的元素都会触发reflow。那么在不得已使用table的场合,可以设置table-layout:auto;或者是table-layout:fixed这样可以让table一行一行的渲染,这种做法也是为了限制reflow的影响范围。
- 如果在一个局部方法中需要多次访问同一个dom,则先暂存它的引用,避免多次访问dom。
- 少用DOM集合(类数组)来遍历,因为集合遍历比数组遍历耗费更高。
- 用事件委托来减少事件处理器的数量。
2.HTML和DOM的区别
- html是一种文档类型、是一种结构化文档、是一种标记语言。
- dom是具有一些API的文档对象模型(对象)。提供了一系列的对页面文档访问和操作的api。
- dom还可以操作其他的结构化文档,比如XML DOM 定义了一套标准的针对 XML 文档的对象。
3. 网页从输入网址到渲染完成经历了哪些过程?
大致可以分为:
- 输入网址;
- 查询本地DNS缓存,如果有这条记录,则直接返回对应的IP。否则请求DNS服务器,并获取对应的服务器ip地址(返回给客户机,并缓存这条记录),如果做了CDN加速的话,会提供访问速度最快的 IP 地址;
- 浏览器通过IP与端口号与服务器建立TCP连接,请求数据。(会与服务器进行3次握手)
- 浏览器向web服务器发送http请求,请求方式如get/post/delete/put/option等。数据在进入服务端之前,可能还会先经过负责负载均衡的服务器或网关,它的作用就是将请求合理的分发到多台服务器或端口上或进行重定向。
- web服务器响应请求,并返回指定url的HTTP报文(或错误信息);
- 首先浏览器会判断返回的状态码是什么,如果是 200 那就继续解析,如果 400 或 500 的话就会报错,如果 300 的话会进行重定向,这里会有个重定向计数器,避免过多次的重定向,超过次数也会报错。
- 一次会话完成,关闭
- 浏览器解析源文件,如果是 gzip 格式的话会先解压一下,然后通过文件的编码格式知道该如何去解码文件。
- 解码完成后浏览器开始渲染流程,生成DOM树,解析css和js,渲染页面,直至呈现完成;(具体的渲染过程参考下文)
http://code.zuifengyun.com/2021/03/2178.html
4.什么是同源策略?
两个页面地址中的协议、域名和端口号一致,则表示同源。
同源策略的限制:
- 存储在浏览器中的数据,如localStroage、Cooke不能通过脚本跨域访问
- 不能通过脚本操作不同域下的DOM
- 不能通过ajax请求不同域的数据
- 跨域请求不能携带cookie信息,需要配置响应头"Access-Control-Allow-Credentials": true
为什么会有同源策略:
目的是为了安全,如果没有同源限制,在浏览器中的cookie等其他数据可以任意读取,不同域下的DOM任意操作,ajax任意请求其他网站的数据,包括隐私数据。
5. 什么是跨域,解决跨域所有方法
用ajax访问非同源的接口地址,或非同源的页面直接传递数据,就会存在跨域问题。
解决跨域的办法:
1.通过jsonp跨域
缺点:
只能使用Get请求
不能注册success、error等事件监听函数,不能很容易的确定JSONP请求是否失败
JSONP是从其他域中加载代码执行,容易受到跨站请求伪造的攻击,其安全性无法确保
2.通过修改document.domain来进行跨域
缺点:只能跨子域
3.HTML5新引进的window.postMessage方法实现跨域传参
缺点:会阻断后续程序的执行。所以只能放到程序最后。
4.CORS跨域(常用),服务器返回数据时修改响应头,使浏览器认为是同源。
Access-Control-Allow-Origin: * //该字段必须,表示接受任意域名的请求
Access-Control-Allow-Methods: POST, GET, OPTIONS //必须,永续请求的方式
Access-Control-Allow-Headers: X-PINGOTHER, Content-Type //可选,允许接受除了6个基本字段:
Cache-Control
、Content-Language
、Content-Type
、Expires
、Last-Modified
、Pragma
外的其他字段。Access-Control-Max-Age: 86400 //指定本次预检请求的有效期,单位为秒。一旦服务器通过了"预检"请求,以后每次浏览器正常的CORS请求,就都跟简单请求一样,会有一个
Origin
请求头信息字段。服务器的回应,也都会有一个Access-Control-Allow-Origin
头信息字段。Access-Control-Allow-Credentials: true //允许浏览器发送cookie
详细信息如下文:
http://code.zuifengyun.com/2017/04/2321.html
5.动态创建script,script标签不受同源策略的限制。具体没考究。
6.iframe中使用利用location.hash 跨域传值
7.web socket协议进行跨域,建立长连接可以跨域。服务器需要配置支持web socket协议。
8.使用网关做反向代理,借助中间层。如nginx反向代理,node中间层反向代理。
6.图片懒加载和预加载
预加载:提前加载图片,当用户需要时直接从缓存中渲染。预加载是为了避免图片的加载过慢造成较差的用户体验,但是会增加服务器前端的压力。
懒加载:当浏览器滚动到相应的位置时再渲染相应的图片。目的是优化前端压力,减少请求数或延迟请求。对服务器前端有一定缓解压力作用。但是若图片较大,则会带来较差的用户体验。
懒加载实现方法:
https://code.zuifengyun.com/2017/04/3196.html
7.简单解释cookie和session
- cookie数据存放在本地浏览器,session数据存放在服务器。
- cookie并不是很安全,别人可以分析和修改cookie,考虑到安全赢个结合session使用。
- cookie结合session可以用来进行登陆或请求验证。session会保存到服务器上,有失效时间。cookie中保存session id
- 单个cookie数据不能超过4k,且很多浏览器限制了一个站点cookie的数量。比如20个。
- 由于安全性,现代ajax请求通常采用token方式取代cookie-session
8.异步加载js方式
① async属性
<script type="text/javascript" src="xxx.js" async="async"></script>
async
属性是HTML5新增属性,需要Chrome、FireFox、IE9+浏览器支持async
属性规定一旦脚本可用,则会异步执行async
属性仅适用于外部脚本- 此方法不能保证脚本按顺序执行
- 他们将在onload事件之前完成
② defer属性
<script type="text/javascript" defer></script>
defer
属性规定是否对脚本执行进行延迟,直到页面加载为止- 如果脚本不会改变文档的内容,可将
defer
属性加入到<script>
标签中,以便加快处理文档的速度 - 兼容所有浏览器
- 此方法可以确保所有设置了
defer
属性的脚本按顺序执行 - 在IE中同时存在defer和async属性时,defer的优先级比较高
③ 异步创建script标签,插入到DOM
(function(){
var scriptEle = document.createElement("script");
scriptEle.type = "text/javasctipt";
scriptEle.async = true;
scriptEle.src = "http://cdn.bootcss.com/jquery/3.0.0-beta1/jquery.min.js";
var x = document.getElementsByTagName("head")[0];
x.insertBefore(scriptEle, x.firstChild);
})();
9. CDN是什么
CDN的全称是Content Delivery Network,即内容分发网络。其通过将站点内容发布至遍布全球的海量加速节点,使其用户可就近获取所需内容,避免因网络拥堵、跨运营商、跨地域、跨境等因素带来的网络不稳定、访问延迟高等问题,有效提升下载速度、降低响应时间,提供流畅的用户体验。 因为CDN的这些特性,我们可以将体积较大的文件或是图片上传到CDN中,通过CDN来加载,减轻了服务器的请求压力,同时也可以通过CDN来获取、加载依赖。
本文固定连接:https://code.zuifengyun.com/2017/10/1909.html,转载须征得作者授权。