一、HTML相关
1. HTML5新增特性和函数
- document.querySelector()
- classList: add()、 remove()
- requestFullScreen()
- preload和prefetch:
rel="preload/prefetch" as="font/style/script.."(文件类型) type="font/woff2"
preload:是声明式的fetch,可以强制浏览器请求资源,同时不阻赛文档onload事件。可以用于解决文字加载闪烁问题。
prefetch:提示浏览器这个资源将来可能需要,是否和什么时候加载由浏览器决定。
对于当前页面很有必要的资源使用preload,对于可能在将来使用的资源使用prefetch。同时声明可能导致二次下载。
2. HTML语义化
- 语义化,就是通过HTML标签来表示页面包含信息。
- 语义化标签有header、h1-6、aside、footer等
- 语义化使文档结构清晰,便于维护;利于搜索引擎抓取网页。
3、前端需要注意哪些SEO
- 合理的title、description、keywords
- 语义化的html代码
- 重要内容放在文档结构前面
- 重要内容不要用js输出,爬虫不会抓取执行js后获取的内容
- 少用iframe,搜索引擎不会抓取iframe内容
- 图片加上alt和title
- 保证网站打开速度
4. 解析HTML文档
- 解析HTML,构建DOM树
- 解析CSS,生成CSS规则树
- 合并DOM树和CSS规则,生成render树
- 布局render树(layout/reflow),负责各元素位置和尺寸计算
- 绘制render树(paint),绘制页面像素信息
- 浏览器会将各层信息发送给GPU,GPU会将各层合成(composite),显示在屏幕上
5. 回流/重排和重绘
回流:即重排,元素内容、结构、位置或尺寸发生变化,需要重新计算样式树和渲染树,引发回流
重绘:元素发生的改变只是影响了元素的一些外观(背景色改变,边框颜色改变等),引发重绘
引起回流:
- 页面渲染初始化
- DOM结构改变、位置改变、布局改变
- 窗口resize
- 获取元素位置信息,也会导致回流。(getComputedStyle、offsetTop、scrollTop等)
优化:
- 减少逐项更改样式,一次性更改style或修改class
- 避免循环操作dom,可以创建documentFragment,操作完后再添加到文档中
- 避免多次读取元素位置信息,可以缓存到变量中
- 改变元素样式,使它脱离文档流
6. 简单层与复合层
- 默认只有一个复合图层,所以DOM节点都是在这个复合图层下
- 开启硬件加速后,可以将某个节点变成复合图层
- 复合图层之间的绘制互不干扰
- 简单图层中,即使是absolute布局,变化时不影响整体回流,但是由于在同一个图层中,仍然会影响绘制,因此做动画时性能很低。推荐做动画时开启硬件加速。
7. 外部资源下载
CSS资源下载:
- CSS下载时异步,不会阻赛构建DOM树
- 会阻赛渲染,构建render树会等到CSS下载解析完毕后执行
- media query声明的CSS不会阻赛渲染
JS资源下载:
- 阻赛浏览器解析,需等待脚本下载并执行完后才会继续解析HTML
- defer和async,脚本变成异步,会等到解析完毕后再执行。
- defer是延迟执行,效果就像是将脚本放在body后面。
- async是异步执行,异步下载完毕后就会执行,不确保执行顺序,一定在onload前,但不确定在DOMContentLoaded事件前或后
- DOMContentLoaded事件仅当DOM加载完毕后就会触发,load事件会等页面所有DOM、样式表、脚本、图片都加载完成后执行。
img资源:
- 异步下载,不会阻赛渲染,下载完毕后直接用图片资源替换原有src
8. 浏览器加载白屏
- 请求发出前:资源不合法,如跨域、https用http等;请求队列太多或本资源优先级不够高,资源被delay;dns出问题,劫持,dns服务器挂了等
- 请求发送过程中:没有到达服务器,如cdn挂了;到达服务器但没有到达处理程序,如在队列里堆积,403、401等;服务端500了;成功运行,但是迟迟没有返回,如代码耗时久,死循环等
- 请求返回后:解析阶段报错,返回类型不对;执行阶段报错,死循环或代码错误;
- 用户原因
9. 前端需要注意什么
- 交互优化:请求时间过长,响应间隔过长
- 日志埋点:生成环境操作埋点、报错处理
- 异地容灾:cdn切换、后端环境
- 减少事故、快速处理
- 请求方面:请求合并、顺序依赖、权限控制、大数据查询逻辑拆分
- 前端解耦
- 版本控制
二、CSS相关
1. CSS3新增特性有哪些
- 新增多种选择器
- transform、transtion、animation
- background-clip、background-size、background-origin
- box-sizing
2. CSS预处理器
css预处理器有sass、less和stylus。
3. CSS盒模型
content-box (标准盒模型)、border-box(怪异盒模型)
3. 层叠优先级
从下到上:
层叠上下文background/border < 负z-index < block < float < inline < z-index: auto或z-index: 0或不依赖z-index的层叠上下文(例:transform、opacity) < 正z-index
4. 雪碧图
概念:将多个小图拼接到一个图片中。通过background-position和元素尺寸调节需要显示的图案。
优点:
- 减少HTTP请求数,提高页面加载速度。
- 增加图片信息重复度,提高压缩比,减少图片大小
- 更换风格方便
缺点:
- 图片合并麻烦
- 维护麻烦
5. link和@import的区别
- link是HTML提供的标签,@import是CSS提供的语法规则。
- 加载页面时,link引入的CSS被同时加载;@import引入的CSS在页面加载完后被加载。
- 可以通过操作js控制link标签,@import不行。
- link支持最大限度并行下载;当页面引入过多@import,会导致加载顺序混乱。(在IE浏览器中)
- link优于@import,无兼容性问题。
6. BFC和IFC
构成BFC:
- float值不为none
- position值为absolute或fixed
- dispaly值为inline-block、flex、table-cell等
- overflow值不为visibility
BFC特性:
- 解决了垂直方向外边距折叠问题
- 解决了浮动元素父级元素塌陷问题
- BFC内的子元素不受外部元素影响,也不影响外部元素。
IFC:水平方向上的margin、border和padding在框之间得到保留。在垂直方向上可以以不同方式对齐。line box高度由line-height决定。
三、JS相关
1. AJAX
原理:在用户与服务器之间加了一个中间层(ajax引擎),使用户操作与服务器响应异步化。
优点:
- 无刷新更新数据
- 异步与服务器通信
- 前端和后端负载平衡
缺点:
- 无法浏览器后退和加入书签功能
- 搜索引擎无法搜索
function ajax (url, method) { var xhr = new XmlHttpRequest() xhr.open(method, url) xhr.send() xhr.onreadystatechange = function () { if (xhr.readyState === 4 && xhr.status === 200) { console.log(xhr.responseText) } } } 复制代码
2. 事件冒泡和事件捕获
事件冒泡:事件会从最内层的元素开始发生,一直向上传播,直到document对象。
时间捕获:事件会从最外层开始发生,直到最具体的元素。
element.addEventListener(event, fn, useCapture):useCapture为false则在事件冒泡阶段调用函数,为true则在时间捕获阶段调用函数。
当事件冒泡和事件捕获同时存在,对于非target节点先执行捕获再执行冒泡,对于target节点,谁先注册就先执行谁。
用这一机制,可以实现事件代理。
3. this指向和call、apply和bind
this: ES5中,this永远指向最后调用它的那个对象。箭头函数中,会根据定义时的上下文确定。箭头函数中没有this绑定,必须通过查找作用域决定其值,如果箭头函数被非箭头函数包含,则this绑定的最近一层非箭头函数的this,否则,this为undefined。
非严格模式下,this默认是window对象,严格模式下,则是undefined。
改变this指向:
- 使用es6箭头函数
- 函数内部使用局部变量保存,例var _that = this
- 使用apply、call或bind
- new实例化一个对象
apply、call和bind的区别:
apply方法参数以数组形式传入,非严格模式下,this传null或undefined时会自动指向window对象;call方法参数以不定参形式传入;bind会返回一个新的方法。
4. new期间做了什么
- 创建一个空对象obj
- 将空对象的原型指向其构造函数的原型
- 将this指向obj
- 如果无返回值或返回一个非对象,则直接返回obj,否则返回指定的对象。
5. var、let和const
- 通过var声明的变量存在变量提升特性
- let和const定义块级作用域变量。不会被变量提升,重复声明会报错。
- var在全局声明,会挂载在window对象上;但let和const不会。
- const不是指值不可以修改,是不可以修改内存地址指向。
临时死区(Temporal Dead Zone),TDZ。用let和const声明的变量会放在TDZ中。访问TDZ中的变量会触发运行时错误。只有执行过变量声明语句后,变量才会从TDZ中移出,然后方可访问。
6. arguments和caller、callee
arguments是一个类数组,只具有length属性,可被转换成数组。
callee指向当前执行的函数
caller指向调用对象,在全局调用函数返回null,在函数内部调用函数,返回外部函数引用。
7. requestAnimationFrame
该方法告诉浏览器你希望执行动画并请求浏览器在下一次重绘之前调用指定函数来更新动画。传入一个回调函数作为参数,回调函数会在每次重绘前调用。返回一个long性的id,用于在cancelAnimationFrame(id)以取消回调函数。
8.打开一个网页经历了哪些过程
- 调用DNS服务,如果存在浏览器缓存、本地缓存或路由缓存时,直接返回缓存文件。
- 发起一个http请求,建立TCP连接。
- 服务端接到请求后,处理请求,返回响应报文。
- 客户端拿到返回的html文档流后,开始解析
- 解析DOM生成DOM树,解析CSS生成CSSOM树。然后合并生成render树。
- 进行layout/reflow和paint
- 返回图层信息,使用GPU进行硬件加速
- 触发load事件
9. event loop
- JS分为同步任务和异步任务
- 同步任务都在主线程上执行,形成一个执行栈
- 主线程之外,事件触发线程管理着一个任务队列,只有异步任务有了运行结果,就在任务队列中放置一个事件
- 一旦执行栈中的所有同步任务执行完毕(此时JS引擎线程空闲),系统就会读取任务队列,将可运行的异步任务添加到可执行栈中,开始执行
- 定时器,是由定时器线程控制。当使用setTimeout和setInterval时,就会调用定时器线程。建议用setTimeout模拟setInterval。
- macroTask/task和microTask/jobs
macroaTask:每次执行栈执行的代码就是一个宏任务(包括每次从事件队列中获取一个事件回调并放到执行栈中执行)。每一个task会从头到尾将这个任务执行完毕,不会执行其他;每个task执行结束后,在下一个task开始执行前,对页面进行渲染。
形成macroTask的操作:主代码块,setTimeout、setInterval等
microTask:当前task执行结束后立即执行的任务。在某一个macroTask执行完后,会在它执行期间产生的microTask都执行完毕(在渲染前)。
形成microTask的操作:Promise、process.nextTick等
10. 变量对象、活得对象、执行环境、作用域链
执行环境定义了变量或函数有权访问的其他数据,决定了它们各自的行为。每个执行环境都有一个变量对象,环境中定义的所有变量和函数都保存在这个对象中。
当代码在一个环境中执行时,会创建变量对象的一个作用域链。作用域链保证对执行环境有权访问的所有变量和函数的有序访问。 如果执行环境是函数,活动对象就被作为变量对象。活动对象最开始只包含一个变量,即arguments对象(全局环境不存在arguments对象)。
四、HTTP相关
1. get和post
get和post都是http请求,http底层是TCP/IP,所以它们本质上是TCP链接。
get请求只是把参数放在url中请求数据,post请求则是把参数放在request body中。
get请求产生一个TCP数据包,post会产生两个TCP数据包。get请求会把http header和data一并发送;post请求会先发送header。服务器响应100 continue,浏览器再发送data。
2. options请求
- 检测服务器支持的请求方法,响应报文返回一个allow字段
- cors中的预检请求,请求报文中Access-Control-Request-Method和Access-Control-Request-Headers,响应报文中返回Access-Control-Allow-Origin、Access-Control-Allow-Methods和Access-Control-Allow-Headers。
优化:请求头部添加Access-Control-Max-Age,在有效时间内,同类型请求不会再发送预检请求。
3.五层因特尔协议栈
概括:从应用层发送http请求,到传输层通过三次握手建立tcp/ip链接,网络层进行ip寻址,再到数据链路层封装成帧,最后物理层利用物理介质传输。
- 应用层(dns、http):DNS解析成IP并发送http请求
- 传输层(tcp、udp):简历tcp链接(三次握手)
- 网络层(IP、ARR):IP寻址
- 数据链路层:封装成帧
- 物理层:利用物理介质进行数据传输
OSI七层框架:多了会话层和表示层
- 会话层:管理不同用户和进程之间的对话,如控制登陆和注销过程
- 表示层:主要处理两个通信系统中交换信息的表示方式,包括数据格式交换,数据加密与解密,数据压缩与终端类型转换
4.http报文
报文一般包括:通用头部,请求/响应头部,请求/响应体
HTTP1.0定义了三种请求方法:get、post和head
HTTP1.0默认是短链接,一次http请求建立一次连接,结束就中断连接
HTTP1.1新增了五种请求方法:OPTIONS、PUT、DELETE、TRACE和CONNECT
HTTP1.1默认是长链接
HTTP1.1中,每请求一个资源都需要开启一个tcp连接。当资源数过多,会影响速度
HTTP2.0中,一个tcp连接可以同时请求多个资源,速度显著提升。
HTTP2.0:
- 多路复用(一个tcp连接可以请求多个资源)
- 首部压缩(http头部压缩,减少体积)
- 二进制分帧(在应用层跟传送层之间增加了一个二进制分帧层。改进传输性能,实现低延迟和高吞吐量)
- 服务器端推送(服务端可以对客户端的一个请求发出多个响应,可以主动通知客户端)
- 请求优先级(如果流被赋予了优先级,它就会基于这个优先级来处理,由服务器决定需要多少资源处理该请求)
状态码:
- 200:请求成功,请求资源返回客户端
- 304:请求资源未变更,直接使用本地缓存
- 400:请求有错,如参数传递错误
- 401:请求未经授权,没有权限
- 403:禁止访问,比如未登录时禁止访问
- 404:请求资源未找到
- 500:服务器内部错误
- 503:服务不可用
- 1xx:指示信息,表示请求已接受,继续处理
- 2xx:成功,表示请求已被成功接受
- 3xx:重定向,要求完成请求还须进行更进一步操作
- 4xx;客户端错误,请求有语法错误或请求无法实现
- 5xx:服务端错误,服务器未能实现合法请求
5. cookie和session
cookie:是浏览器的一种本地存储方式,一般用来帮助客户端和服务端通信,常用来进行身份验证,结合服务端session使用。主要内容包括:名字、值、过期时间、路径和域。未设置过期时间,则是浏览器会话时间。
- 用户登录后,服务端会生成一个session,session中有对于用户的信息
- 生成一个sessionid,在客户端页面中写入cookie,值就是:jessionid=xxx
- 以后发送请求时,就会自动带上cookie,自动检验,有效时间内无须二次登陆校验。
cookie中设置httponly,则js无法读取cookie
cookie和session的区别:
- Cookie只能存储ASCII字符串,Session可以存储复杂数据类型
- Cookie存储在客户端,容易泄露。Session存储在服务端,不存在数据泄露风险
- Cookie可以设置过期时间,而Session一般会话结束后就过期
- Cookie保存在客户端,不占用服务端资源;Session保存在服务端,用户很多时会消耗大量服务器内存
- Cookie可以设置为多窗口共享,Session只在本窗口和子窗口有效
- Cookie支持跨域访问,Session仅在他所在域名有效
6. http和https
区别:https在请求前,会建立ssl链接,确保接下来的通信是加密的,无法被轻易截取分析。https开销比http要大(需要建立安全链接和加密),可以配合HTTP2.0提升性能。
过程:
- 浏览器请求建立SSL链接,向服务端发送一个随机数和客户端支持的加密算法,此时是明文传输
- 服务端选择一组加密算法和Hash算法,返回一个随机数,并将自己的身份信息以证书形式返回给客户端(证书里包含了网站地址,非对称加密的公匙,以及证书颁发机构信息等)
- 浏览器收到服务端发来的证书后,验证证书合法性,浏览器会产生新的随机数,然后用证书中的公匙以及指定的加密算法加密后发送给服务端。利用这三个随机数生成对称加密传输key-
session key
。使用预定好的Hash算法计算握手消息,并使用生成的session key
对消息加密传输给服务端。- 服务端收到浏览器的回复后,生成
session key
,解密浏览器发来的握手消息,验证Hash。再使用session key
加密一段握手消息发送给客户端- 浏览器解密并计算握手消息的Hash,如果与服务端发来的Hash一致,握手过程结束。
7. http缓存
缓存分为强缓存(200 from cache)和协商缓存(304)
强缓存:浏览器如果判断本地缓存未过期,就直接使用,无需发送http请求
协商缓存:浏览器会向服务端发送http请求,然后服务端告知浏览器文件未改变,让浏览器继续使用缓存(可以使用ctrl + F5强制刷新使缓存失效)
强缓存头部:http1.0 Pragma/Expires;http1.1 Cache-control/Max-Age
协商缓存头部:http1.0 If-Modified-Since/Last-Modified;http1.1 If-None-Macth/ETag
8. 跨域
因为同源策略,当请求跨域资源时就会出现跨域问题。
CORS(跨域资源共享)实现:
- 浏览器发送请求。如果是简单请求就直接发送CORS请求(头部中增加origin字段);如果是非简单请求则需要发送预检请求(OPTIONS)。
- 如果预检请求检测失败,会返回一个没有任何CORS相关头部信息的报文,请求失败。如果预检请求成功,就可以发送正式的请求到服务端了。
- 简单请求:请求方法是HEAD、GET、POST之一,Content-Type只能是application/x-www-form-urlencoded、multipart/form-data、text/plain之一,不能有自定义头部字段。
解决跨域:
- JSONP解决跨域:利用script标签具有跨域能力。只能用于GET请求。
- 配置CORS
- window.postMessage()
9. 前端安全
XSS攻击:跨站脚本攻击,攻击者通过注入非法Html或者js代码,当用户浏览网页时,从而控制用户浏览器。
XSS防范:设置httpOnly,对用户输入进行转码和过滤。
CSRF攻击:跨站请求伪造。冒充用户发送请求,完成一些违背用户意愿的事情。
CSRF防范:验证码、token、referer check
五、webpack
1. 原理
- optimist将用户配置的webpack.config.js和shell脚本传过来的参数整合成options对象传入下一个流程的控制对象中
- 加载用户配置在webpack.config.js的plugins,根据optimise.argv中参数的值决定是否加载对应插件(例:根据shell中指令,决定是否加载HotModuleReplacementPlugin插件)
- 初始化compiler对象,调用compiler.run()(注:webpack的实际入口),生成Compilation对象。这个对象有两个作用:一是负责组织整个打包过程,包含了每个构建环节及输出环节所对应的方法;二是该对象内部存放着所有module、chunck、生成的asset以及用来生成最后打包文件的template信息
webpack关键事件节点:
- compile 开始编译
- make 从入口点分析模块及其依赖的模块,创建这些模块对象
- build-module 构建模块
- after-compile 完成构建
- seal 封装构建结果
- emit 把各个chunk输出到结果文件
- after-emit 完成输出
- 触发make,调用Compilation.addEntry,通过entry字段找到入口js文件。在addEntry方法中调用私有方法_addModuleChain,该方法主要完成两件事:一是根据模块类型获取对应的模块工厂并创建模块,二是构建模块
- 触发build-module,构建模块:
- 调用各loader处理模块间的依赖,将所有资源都整合成模块
- 调用acorn解析经loader处理后的源文件生成抽象语法书AST
- 遍历AST,将当前模块所依赖的模块添加到依赖模块数组中,然后构建该模块所依赖的模块
- 打包输出,触发seal事件
- 生成最终assets,调用emitAssets(),按照output中的配置项将文件输出到对应的path中