今天是『question 系列』的 http 和 performance 部分, js 部分我们放在最后。
下面我们开始吧。
network部分
- 304的缓存原理(添加Etag标签.last-modified)
304 网页上次请求没有更新,节省带宽和开销
- 服务器首先产生Etag,服务器可在稍后使用它来判断页面是否被修改。本质上,客户端通过该记号传回服务器要求服务器验证(客户端)缓存)
- 304是 HTTP的状态码,服务器用来标识这个文件没有被修改,不返回内容,浏览器接受到这个状态码会去去找浏览器缓存的文件
- 流程:客户端请求一个页面(A)。 服务器返回页面A,并在给A加上一个ETag。客户端展现该页面,并将页面连同ETag一起缓存。 客户再次请求页面A,并将上次请求时服务器返回的ETag一起传递给服务器。 服务器检查该ETag,并判断出该页面自上次客户端请求之后还未被修改,直接返回响应304(未修改——Not Modified)和一个空的响应体。
=> 有了Last-Modified,为什么还要用ETag?
- 因为如果在一秒钟之内对一个文件进行两次更改,Last-Modified就会不正确(Last—Modified不能识别秒单位的修改)
- 某些服务器不能精确的得到文件的最后修改时间
- 一些文件也行会周期新的更改,但是他的内容并不改变(仅仅改变修改的事件),这个时候我们并不希望客户端认为文件被修改,而重新Get
=> 有了ETag,为什么还要用Last-Modified?
- 两者互补,ETag的判断的缺陷,比如一些图片等静态文件的修改
- 如果每次扫描内容都生成ETag比较,显然要比直接比较修改时间慢的多。ETag是被请求变量的实体值(文件的索引节,大小和最后修改的时间的Hash值)
- ETag的值服务器端对文件的索引节,大小和最后的修改的事件进行Hash后得到的。
- TCP的三次握手和四次挥手
三次握手
第一次握手:客户端发送一个SYN码给服务器,要求建立数据连接;
第二次握手:服务器SYN和自己处理一个SYN(标志);叫SYN+ACK(确认包);发送给客户端,可以建立连接
第三次握手:客户端再次发送ACK向服务器,服务器验证ACK没有问题,则建立起连接;
四次挥手
第一次挥手:客户端发送FIN(结束)报文,通知服务器数据已经传输完毕;
第二次挥手: 服务器接收到之后,通知客户端我收到了SYN,发送ACK(确认)给客户端,数据还没有传输完成
第三次挥手:服务器已经传输完毕,再次发送FIN通知客户端,数据已经传输完毕
第四次挥手:客户端再次发送ACK,进入TIME_WAIT状态;服务器和客户端关闭连接;
- 为什么建立连接是三次握手,而断开连接是四次挥手呢?
建立连接的时候, 服务器在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。
而关闭连接时,服务器收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,而自己也未必全部数据都发送给对方了,所以己方可以立即关闭,也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接,因此,己方ACK和FIN一般都会分开发送,从而导致多了一次。
- http协议的理解
超文本的传输协议,是用于从万维网服务器超文本传输到本地资源的传输协议
基于TCP/IP通信协议来传递数据(HTML,图片资源)
基于运用层的面向对象的协议,由于其简洁、快速的方法、适用于分布式超媒体信息系统
http请求信息request:
请求行(request line)、请求头部(header),空行和请求数据四部分构成请求行,用来说明请求类型,要访问的资源以及所使用的HTTP版本.
请求头部,用来说明服务器要使用的附加信息
空行,请求头部后面的空行是必须的
请求数据也叫主体,可以添加任意的其他数据。
5.http相应信息Response
状态行、消息报头、空行和响应正文
状态行,由HTTP协议版本号, 状态码, 状态消息 三部分组成
消息报头,用来说明客户端要使用的一些附加信息
空行,消息报头后面的空行是必须的
响应正文,服务器返回给客户端的文本信息。
- http和https
https:是以安全为目标的HTTP通道,简单讲是HTTP的安全版本,通过SSL加密
http:超文本传输协议。是一个客服端和服务器端请求和应答的标准(tcp),使浏览器更加高效,使网络传输减少
- web缓存
- web缓存就是存在于客户端与服务器之间的一个副本、当你第一个发出请求后,缓存根据请求保存输出内容的副本
- 缓存的好处
(1)减少不必要的请求
(2)降低服务器的压力,减少服务器的消耗
(3)降低网络延迟,加快页面打开速度(直接读取浏览器的数据)
- CDN(内容分发网络)
- 尽可能的避开互联网有可能影响数据传输速度和稳定性的瓶颈和环节。使内容传输的更快更稳定。
- 关键技术:内容存储和分发技术中
- 基本原理:广泛采用各种缓存服务器,将这些缓存服务器分布到用户访问相对的地区或者网络中。当用户访问网络时利用全局负载技术
将用户的访问指向距离最近的缓存服务器,由缓存服务器直接相应用户的请求(全局负载技术)
- 从输入url到获取页面的完整过程
- 查询浏览器缓存,系统缓存,路由器缓存
- 查询NDS(域名解析),获取域名对应的IP地址
- 浏览器与服务器建立tcp链接(三次握手)
- 浏览器向服务器发送http请求(请求和传输数据)
- 服务器接受到这个请求后,根据路经参数,经过后端的一些处理生成html代码返回给浏览器
- 浏览器拿到完整的html页面代码开始解析和渲染,如果遇到外部的css或者js,图片一样的步骤
- 浏览器根据拿到的资源对页面进行渲染,把一个完整的页面呈现出来
- 浏览器渲染原理及流程 DOM -> CSSOM -> render -> layout -> print
流程:解析html以及构建dom树 -> 构建render树 -> 布局render树 -> 绘制render树
概念:
1.构建DOM树: 渲染引擎解析HTML文档,首先将标签转换成DOM树中的DOM node(包括js生成的标签)生成内容树
2.构建渲染树: 解析对应的css样式文件信息(包括js生成的样式和外部的css)
3.布局渲染树:从根节点递归调用,计算每一个元素的大小,位置等。给出每个节点所在的屏幕的精准位置
4.绘制渲染树:遍历渲染树,使用UI后端层来绘制每一个节点
重绘:
当盒子的位置、大小以及其他属性,例如颜色、字体大小等到确定下来之后,浏览器便把这些颜色都按照各自的特性绘制一遍,将内容呈现在页面上
触发重绘的条件:改变元素外观属性。如:color,background-color等
重绘是指一个元素外观的改变所触发的浏览器行为,浏览器会根据元素的新属性重新绘制,使元素呈现新的外观
注意:table及其内部元素需要多次计算才能确定好其在渲染树中节点的属性值,比同等元素要多发时间,要尽量避免使用table布局
重排(重构/回流/reflow)
当渲染书中的一部分(或全部)因为元素的规模尺寸,布局,隐藏等改变而需要重新构建,这就是回流。
每个页面都需要一次回流,就是页面第一次渲染的时候
重排一定会影响重绘,但是重绘不一定会影响重排
- 为什么css放在顶部而js写在后面
- 浏览器预先加载css后,可以不必等待HTML加载完毕就可以渲染页面了
- 其实HTML渲染并不会等到完全加载完在渲染页面,而是一边解析DOM一边渲染。
- js写在尾部,主要是因为js主要扮演事件处理的功能,一方面很多操作是在页面渲染后才执行的。另一方面可以节省加载时间,使页面能够更加的加载,提高用户的良好体验
但是随着JS技术的发展,JS也开始承担页面渲染的工作。比如我们的UI其实可以分被对待,把渲染页面的js放在前面,时间处理
- 存储方式与传输方式
- indexBD: 是h5的本地存储库,把一些数据存储到浏览器中,没网络,浏览器可以从这里读取数据,离线运用。5m
- Cookie: 通过浏览器记录信息确认用户身份,最大4kb,这也就限制了传输的数据,请求的性能会受到影响
- Session: 服务器端使用的一种记录客户状态的机制(session_id存在set_cookie发送到客服端,保存为cookie)
- localStroage: h5的本地存储,数据永久保存在客服端
- token、cookie、session三者的理解???!!!
- token就是令牌,比如你授权(登录)一个程序时,他就是个依据,判断你是否已经授权该软件(最好的身份认证,安全性好,且是唯一的用户身份的验证方式)
- cookie是写在客户端一个txt文件,里面包括登录信息之类的,这样你下次在登录某个网站,就会自动调用cookie自动登录用户名。服务器生成,发送到浏览器、浏览器保存,下次请求再次发送给服务器(存放着登录信息)
- session是一类用来客户端和服务器之间保存状态的解决方案,会话完成被销毁(代表的就是服务器和客户端的一次会话过程)。cookie中存放着sessionID,请求会发送这个id。sesion因为request对象而产生。
- 基于Token的身份验证:(最简单的token: uid用户唯一的身份识别 + time当前时间戳 + sign签名)
- 用户通过用户名和密码发送请求
- 服务器端验证
- 服务器端返回一个带签名的token,给客户端
- 客户端储存token,并且每次用于发送请求
- 服务器验证token并且返回数据
每一次请求都需要token
- cookie与session区别
- cookie数据存放在客户的浏览器上,session数据放在服务器上。
- cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗考虑到安全应当使用session。
- session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能考虑到减轻服务器性能方面,应当使用COOKIE。
- 单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。
- session与token区别
- session认证只是把简单的User的信息存储Session里面,sessionID不可预测,一种认证手段。只存在服务端,不能共享到其他的网站和第三方App
- token是Auth Token,提供的是认证和授权,认证针对用户,授权是针对App,目的就是让某APP有权访问某用户的的信息。Token是唯一的,token不能转移到其他的App,也不能转到其他用户上。(适用于App)
- session的状态是存在服务器端的,客户端只存在session id,Token状态是存储在客户端的
- HTTP 缓存有哪几种?
ETag 是通过对比浏览器和服务器资源的特征值(如MD5)来决定是否要发送文件内容,如果一样就只发送 304(not modified)
Expires 是设置过期时间(绝对时间),但是如果用户的本地时间错乱了,可能会有问题
CacheControl: max-age=3600 是设置过期时长(相对时间),跟本地时间无关。
- RESTful常用的方法和介绍
rest请求方法有4种,包括get,post,put,delete.分别对应获取资源,添加资源,更新资源及删除资源
- csrf跨站攻击怎么解决
CSRF, 跨站请求伪造,它可以在用户毫不知情的情况下以用户名义伪造请求发送给受攻击站点,从而对用户或者网站造成攻击. 预防措施如下:
=> 服务器端验证HTTP Referer字段, Referer记录了该HTTP请求的来源地址
=> 在请求地址中添加token并验证
=> 在HTTP头中自定义属性并验证
- 对web安全的理解
=> CSRF 攻击和防范
跨站请求伪造,可以理解为攻击者盗用了用户的身份,以用户的名义发送恶意请求,造成用户隐私及财产损失
过程:
- 登录受信任网站并在本地生成cookie;
- 在不登出 网站 的情况下访问危险网站
防范: 关键操作只接受POST请求, 使用验证码, 检测Referer, 使用token(或者JWT)
=> XSS 攻击和防范
全称Cross-site script,跨站脚本攻击,是Web程序中常见的漏洞。
原理是攻击者向有XSS漏洞的网站中输入恶意的脚本,当其它用户浏览该网站时候,该脚本会自动执行,从而达到攻击的目的(盗取Cookie,破坏页面结构,重定向到钓鱼网站等)。
区分: 分为持久型XSS和非持久性XSS. 持久型XSS是将攻击的脚本植入到服务器,从而导致每个访问的用户都会遭到此XSS脚本的攻击。非持久型XSS是将恶意脚本包装在页面的URL参数中,通过URL链接骗取用户访问,从而进行攻击.
防范: 对用户输入进行HTML转义, 对敏感信息进行过滤
=> SQL 注入与防范
通过把SQL命令插入到表单中并提交或页面请求的参数中,最终使得服务器执行恶意的SQL命令.
防范: 对用户的输入进行校验或限制长度;对特殊字符进行转换, 不要使用动态拼装SQL,为每个应用使用单独的权限有限的数据库连接。对隐私信息进行加密
=> DDOS 攻击
分布式拒绝服务(DDoS:Distributed Denial of Service)攻击指借助于客户/服务器技术,将多个计算机联合起来作为攻击平台,对一个或多个目标发动DDoS攻击,从而成倍地提高拒绝服务攻击的威力。
- base64为什么能提升性能以及它的缺点是什么
优点:
• 无额外请求
• 适用于很小或者很简单的图片
• 可像单独图片一样使用,比如背景图片等
• 没有跨域问题,不需要考虑缓存、文件头或者cookies问题
缺点:
• CSS 文件体积的增大, 造成CRP(关键渲染路径)阻塞
• 页面解析CSS生成的CSSOM时间增加
- 介绍webp图片文件格式
WebP是一种支持有损压缩和无损压缩的图片文件格式,根据Google的测试,无损压缩后的WebP比PNG 文件少了45%的文件大小,即使这些PNG文件经过其他压缩工具压缩之后,WebP 还是可以减少28%的文件大小。
•优点
更小的文件尺寸
更高的质量——与其他相同大小不同格式的压缩图像比较
•缺点
编码和解码速度比较慢,存在一定兼容性
- 说说H5手机端的适配的几种方案
js实现一
(function (
(function (doc, win) { var docEl = doc.documentElement, resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize', recalc = function () { var clientWidth = docEl.clientWidth; var fontSize = 20; docEl.style.fontSize = fontSize + 'px'; var docStyles = getComputedStyle(docEl); var realFontSize = parseFloat(docStyles.fontSize); var scale = realFontSize / fontSize; console.log("realFontSize: " + realFontSize + ", scale: " + scale); fontSize = clientWidth / 750 * 20; if(isIphoneX()) fontSize = 19; fontSize = fontSize / scale; docEl.style.fontSize = fontSize + 'px'; }; // Abort if browser does not support addEventListener if (!doc.addEventListener) return; win.addEventListener(resizeEvt, recalc, false); doc.addEventListener('DOMContentLoaded', recalc, false); // iphoneX判断 function isIphoneX(){ return /iphone/gi.test(navigator.userAgent) && (screen.height == 812 && screen.width == 375) } })(document, window);
js实现二
(function(
(function(base) { var _base = base|| 75; var ua = navigator.userAgent; var matches = ua.match(/Android[\S\s]+AppleWebkit\/(\d{3})/i); var isIos = navigator.appVersion.match(/(iphone|ipad|ipod)/gi); var dpr = window.devicePixelRatio || 1; if(!isIos && !(matches && matches[1] > 534)) { // 如果非iOS, 非Android4.3以上, dpr设为1; dpr = 1; } var scale = 1/ dpr; var metaEl = document.querySelector('meta[name="viewport"]'); if(!metaEl) { metaEl = document.createElement('meta'); metaEl.setAttribute('name', 'viewport'); window.document.head.appendChild(metaEl); } metaEl.setAttribute('content', 'width=device-width,user-scalable=no,initial-scale='+ scale + ',maximum-scale='+ scale + ',minimum-scale='+ scale); document.documentElement.style.fontSize = document.documentElement.clientWidth / (750/ _base) + 'px'; })(75);
3.css @media媒介查询(苏宁易购实现方式)
4.手淘的lib-flexible实现方式
性能优化部分
关于webpack的面试题总结
- webpack打包文件体积过大?(最终打包为一个js文件)
- 异步加载模块
- 提取第三库
- 代码压缩
- 去除不必要的插件
- 如何优化webpack构建的性能
一、减少代码体积
- 使用CommonsChunksPlugin 提取多个chunk之间的通用模块,减少总体代码体积
- 把部分依赖转移到CDN上,避免每次编译过程都由Webpack处理
- 对一些组件库采用按需加载,避免无用的代码
二、减少目录检索范围
在使用loader的时候,通过制定exclude和include选项,减少loader遍历的目录范围,从而加快webpack编译速度
三、减少检索路经
resolve.alias可以配置webpack模块解析的别名,对于比较深的解析路径,可以对其配置alias
- 移动端的性能优化
- 首屏加载和按需加载,懒加载
- 资源预加载
- 图片压缩处理,使用base64内嵌图片
- 合理缓存dom对象
- 使用touchstart代替click(click 300毫秒的延迟)
- 利用transform:translateZ(0),开启硬件GUP加速
- 不滥用web字体,不滥用float(布局计算消耗性能),减少font-size声明
- 使用viewport固定屏幕渲染,加速页面渲染内容
- 尽量使用事件代理,避免直接事件绑定
- Vue的SPA 如何优化加载速度
- 减少入口文件体积
- 静态资源本地缓存
- 开启Gzip压缩
- 使用SSR,nuxt.js
- 有哪些常见 loader 和 plugin,你用过哪些
loader:让webpack能够处理非js文件(自身职能理解js),然后你就可以利用 webpack 的打包能力,对它们进行处理。
例如:css-loader、style-loader、postcss-loader、sass-loader
plugins:从打包优化和压缩,一直到重新定义环境中的变量.
例如:uglify-webpack-plugin、clean-webpack-plugin、babel-polyfill
- 如何优化网站的SEO
- 网站结构布局优化:尽量简单, 提倡扁平化结构. 一般而言,建立的网站结构层次越少,越容易被“蜘蛛”抓取,也就容易被收录。
- img标签必须添加“alt”和“title”属性,告诉搜索引擎导航的定位,做到即使图片未能正常显示时,用户也能看到提示文字。
- 把重要内容HTML代码放在最前搜索引擎抓取HTML内容是从上到下,利用这一特点,可以让主要代码优先读取,广告等不重要代码放在下边。
- 控制页面的大小,减少http请求,提高网站的加载速度。
- 合理的设计title、description和keywords
• title标题:只强调重点即可,尽量把重要的关键词放在前面,关键词不要重复出现,尽量做到每个页面的title标题中不要设置相同的内容。
• meta keywords页面/网站的关键字。
• meta description网页描述,需要高度概括网页内容,切记不能太长,过分堆砌关键词,每个页面也要有所不同。 - 语义化书写HTML代码,符合W3C标准尽量让代码语义化,在适当的位置使用适当的标签,用正确的标签做正确的事。让阅读源码者和“蜘蛛”都一目了然。
- a标签:页面链接,要加 “title” 属性说明,链接到其他网站则需要加上 el=”nofollow” 属性, 告诉 “蜘蛛” 不要爬,因为一旦“蜘蛛”爬了外部链接之后,就不会再回来了。
- 图标使用IconFont替换
- 使用CDN网络缓存,加快用户访问速度,减轻服务器压力
- 启用GZIP压缩,浏览速度变快,搜索引擎的蜘蛛抓取信息量也会增大
- SSR技术
- 预渲染技术
- 如何优化用户体验
• 页面渲染前使用骨架屏或者加载动画,避免大块白屏
• 使用预渲染或者ssr技术提高首屏加载时间
• 动画使用css3硬件加速,避免用户操作动画卡顿
• 计算密集型业务使用web worker或者js分片处理,避免js线程阻塞
• 页面状态监控,给用户提供反馈机制
• 静态资源走CDN缓存或者oss服务,提高用户访问速度
• 避免用户操作报错,提供404页面或则错误提示页面
- webpack和gulp的优缺点
gulp | webpack | |
---|---|---|
定位 | 基于任务流的自动化打包工具 | 模块化打包工具 |
优点 | 易于学习和理解, 适合多页面应用开发 | 可以模块化的打包任何资源,适配任何模块系统,适合SPA单页应用的开发 |
缺点 | 不太适合单页或者自定义模块的开发 | 学习成本低,配置复杂,通过babel编译后的js代码打包后体积过大 |
- 本文作者: Jambo
- 版权声明: 本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。转载请注明出处!