-
HTML
-
doctype
-
web页面使用哪个HTML版本的指令
- 不是HTML标签
-
html5
- <!DOCTYPE html>
-
CSS
-
盒模型
- 盒模型描述这些矩形盒子中的每一个。这个模型描述了元素所占空间的内容。每个盒子有四个边:外边距, 边框, 内填充边与 内容。
- 将所有元素表示为一个矩形盒
-
两种
-
标准
- box-sizing: content-box
- width = content
-
IE
- box-sizing: border-box
- width = content+padding+margin
- IE盒模型用的最多,也是被推荐使用的
-
常见定位方案
-
普通流 normal flow
-
按照先后位置从上而下布局
- 行内元素水平排列,直到当行被沾满然后换行
- 块级元素则会被渲染为完整的新行
- 所有元素都是普通流定位
-
BFC
- Block Formatting Context
- 定义
- 是区域:布局过程中生成块级盒子的区域,独立的容器和布局环境
- 有规则:浮动元素与其他元素的交互限定区域
- 通俗来讲
- BFC是一个封闭的大箱子,内部无论如何变化,都不会影响到外部
- 创建
- 根元素 body
- overflow 值不为 visible 的块元素
- 浮动元素 float不为none
- 绝对定位元素
- position为absolute和fixed
- 行内块元素
- inline-block
- 弹性元素
- 网格元素
- 规则
- 继承了普通流的定位规则
- 容器里的子元素不会影响到外面的元素
- BFC的高度包含了内部的浮动元素
- BFC区域不会与外部的浮动元素重叠
- 垂直方向的距离由margin决定。属于同一个BFC的两个相邻的Box的margin会发生重叠。
- 应用
- 外边距折叠(Margin collapsing)
- 有的译成外边距塌陷
- 规范
- 相邻盒子(可以是兄弟或祖先关系?)的外边距可以结合成一个单独的外边距
- 发生情况
- 属于同一个BFC的块级元素
- 在normal flow的布局中
- 也就是说绝对定位元素和浮动元素不会发生折叠
- 垂直方向相邻
- 块级盒子
- 也就是说inline-block不会发生折叠
- 也就是说水平方向不会发生折叠
- 解决
- 放在两BFC中
- BFC可以包含浮动的元素
- 场景描述
- 一个block元素中,包含一个浮动元素,此时block元素会失去高度
- 解决
- 为block元素加入overflow:hidden属性,触发BFC
- 那么容器就回包裹着元素
- 阻止被浮动元素覆盖
- 两列布局
-
浮动 float
- 元素首先按照普通流的位置出现
- 然后脱离文档流,根据浮动的方向尽可能的向左或右偏移
-
绝对定位 absolute positioning
- 元素整体脱离普通流
- 不会影响其兄弟元素
- 具体坐标由决定定位的坐标决定
-
position和zindex
-
zindex
- z-index值只决定同一父元素中的同级子元素的堆叠顺序
- z-index只能在position属性值为relative或absolute或fixed
- z-index值可以控制定位元素在垂直于显示屏方向(Z 轴)
-
Style标签放置的最佳位置
- head 里,提前加载样式
-
常见行内元素和块级元素
-
行内
- b, em, strong,
- a, br, img, span, sub, sup
- button, input, label, select, textarea
-
块级
- canvas,div,dl,footer,form,h1,header,hr,p,pre,section,table,ul,li
-
居中
-
水平居中
-
行内元素
- text-align: center
-
块级元素
- 定宽
- margin: 0 auto
- 不定宽
- flex
- inline-block + text-align:center
-
垂直居中布局
-
文本垂直居中
- line-height:height
- margin + translate
- 表格
-
flex
- justify-content
- 主轴
- align-center
- 交叉轴
- margin: auto
- margin + top
-
很好用的css3技能但可能比较少人知道的点
- vw、vh
- calc
- transition
-
inline和inline-block
-
inline
- 不会独占一行
- 多个相邻的行内元素会排列在同一行里,直到一行排列不下
- 置width,height属性无效
- 水平margin、padding无效,垂直margin、padding有效
-
block
- 独占一行
- 默认情况下,block元素宽度自动填满其父元素宽度
- 可以设置width,height属性
- 可以设置margin和padding属性
- margin和padding属性,水平方向产生效果
-
inline-block
- 对象呈现为inline对象,但是对象的内容作为block对象呈现
-
margin: 0 auto水平居中原因
- 水平方向独占一行
- auto是自动分配剩余空间的意思
-
清除浮动
- 利用overflow清除浮动
-
clear
- 利用伪元素(clearfix)
- 父元素结束标签之前插入清除浮动的块级元素
- 利用clear样式
-
css *号
- *可以继承
- 从后向前
-
权重
- !important>行内样式>ID选择器 > 类选择器 | 属性选择器 | 伪类选择器 > 元素选择器
-
选择器匹配规则
- 从右向左
-
探究 CSS 解析原理
- https://juejin.im/entry/5a123c55f265da432240cc90
-
JS
-
XMLHttpRequest
- new XMLHttpRequest()
- xhr.open
-
onload
- this.status == 200||this.status == 304
- jquery实现Ajax
-
dom操作
-
基础
-
查
- document.getElementById
- document.querySelector
-
创建
- document.createElement
- document.createTextNode
-
修改
- appendChild
- insertBefore
- replaceChild
-
删除
- removeChild
- JS交换两个节点如何实现
-
事件
-
本质
-
事件驱动
- 浏览器中很多行为是异步
- 会创建事件并放入执行队列,等待当前代码执行完成
- GUI渲染线程与JS引擎线程互斥
-
绑定,监听,委托的区别
-
绑定
- HTML直接绑定
- 在JavaScript代码中绑定
- 绑定事件监听函数
-
事件委托
- 一般来讲,会把一个或者一组元素的事件委托到它的父层或者更外层元素上,真正绑定事件的是外层元素,当事件响应到需要绑定的元素上时,会通过事件冒泡机制从而触发它的外层元素的绑定事件上,然后在外层元素上去执行函数。
-
好处
- 减少重复工作
- 减少内存消耗
-
异步事件驱动
- 浏览器有一个内部大消息循环,Event Loop(事件循环),会轮询大的事件队列并处理事件
- 只有前面的处理完毕了,空闲了才会执行这个事件
-
事件流
-
冒泡
- 事件捕获
- 目标阶段
- 事件冒泡 (常用)
-
宏任务&微任务
- promise & setTimeout
-
new & Object.create
- Object.create(proto, [propertiesObject])
- new 的过程?
-
Object.create(null)
- 无原型的对象
-
JavaScript是单线程还是多线程
- 单线程的,每个window包含一个JS线程
-
深拷贝和浅拷贝区别
- 子对象
-
模块化
-
好处
- 封装
- 可复用性
-
分类
-
CommonJS
- 服务端环境
- 在浏览器端,模块需要提前编译打包处理
- 基于文件
- 同步加载
- 首次加载模块后,会缓存
- 输出的是一个值的拷贝
-
AMD?
- AMD规范则是非同步加载模块,允许指定回调函数
- 为浏览器环境设计
- 异步
- 回调函数形式
-
ES6 import
- 标准
- 输入值的引用
- 基于文件
- 静态分析
- 必须被用在其他语句或表达式的外部,而不能使用在if等代码块内部
- 原因之一是模块语法需要让 JS 能静态判断需要导出什么,正因为此,你只能在模块的顶级作用域使用 export与import
- 异步
-
CMD
- CMD规范专门用于浏览器端,模块的加载是异步的,模块使用时才会加载执行
-
UMD
- 整合AMD和CMD,自动判断当前环境
-
循环引用问题
-
commonjs
- 加载时执行
- 输入已执行部分
-
ES6
- 动态引用,不存在这个问题
- 遇到import不会去执行模块,而是只生成一个引用
- 而是用到的时候再去取值
-
js异步操作
-
回调函数
- 执行一个函数时,在函数内部处理操作,把操作结果以参数形式传入回调函数中
-
坏处
- 回调地狱
- 不利于阅读
- 不利于调整回调顺序
-
好处
- 代码清晰地表达出了执行关系
- 监听事件
-
定时器
- 宏任务
-
ajax
- Ajax请求确实是异步的,这请求是由浏览器新开一个线程请求,事件回调的时候是放入Event loop单线程事件队列等候处理
-
Promise
- 标准
- 立即执行
- 微任务
- 同步的立即执行函数
-
generator
- 交出函数的执行权
- 调用 Generator 函数,会返回一个内部指针
- next 方法的作用是分阶段执行 Generator 函数
- 流程不方便管理
-
async/await
-
好
- 异步操作的同步写法
-
坏
- 反设计
- 容易引起性能问题
- async返回一个promise
- await让出线程,跳出async函数体
- Generator/function* 来实现
- await是一个让出线程的标志。await后面的表达式会先执行一遍,将await后面的代码加入到microtask中,然后就会跳出整个async函数来执行后面的代码。
- Observable
-
事件循环
- 执行一个宏任务(栈中没有就从事件队列中获取)
- 执行过程中如果遇到微任务,就将它添加到微任务的任务队列中
- 宏任务执行完毕后,立即执行当前微任务队列中的所有微任务(依次执行)
- 当前宏任务执行完毕,开始检查渲染,然后GUI线程接管渲染
- 渲染完毕后,JS线程继续接管,开始下一个宏任务(从事件队列中获取)
-
上下文
-
作用域链
-
本质
- 是指向变量对象的指针列表
- 变量对象
- arguments
- this
- 局部属性和方法
-
定义
- 每个函数都有自己的执行环境
- 当代码在一个环境中执行时,会创建作用域链
-
作用
- 保证对执行环境的所有变量和函数的有序访问
-
链
- 前端
- 当前代码所在环境的的变量对象
- 下一个变量,来自外部执行环境
- 最外层为全局执行环境
- 作用域链的尽头
- node
- global
- web
- window
- 变量搜索
- 静态作用域
-
变量对象
- 变量 (var, 变量声明);
- 函数的形参
- 函数声明 (FunctionDeclaration, 缩写为FD);
-
this
- this是面向对象的表示
- 通过对象调用
-
其它
- window
-
本质
- this引用的是函数据以执行的环境对象
- 执行环境
- 全局执行环境
- 创建
- 当执行流进入一个函数时,函数的执行环境就会被推入环境栈中
- 销毁
- 在函数执行完之后,栈将其环境弹出,该环境被销毁
- 定义
- 每个执行环境都有一个与之关联的变量对象
- 环境中定义的所有变量和函数都保存在这个对象中
- 函数执行环境
- 函数调用时时
- 函数入栈
- 创建执行环境
- 创建作用域链
-
闭包
-
定义
- 函数和其相关引用对象组成的实体
-
闭包原理
- 从scheme语言借鉴来
-
基础
- 词法作用域
- 函数的变量作用范围可以超越创建的它的环境
- 在一些语言中,函数可以嵌套函数,当内部函数引用了外部函数的变量时,就有可能会形成闭包
- 由于有引用,不会被垃圾回收
-
弊端
- 内存占用过多
-
应用场景
-
模仿块级作用域
- settimeout 拿到正确的值
- 创建私有变量
-
封装相关的功能集
- 模块化
- jquery
- 设计单例模式?
- 惰性求值?
-
原型
-
两方面
-
对constructor模式的改善
- 对constructor模式的改善
- 避免重复定义
-
设计思想
- JS的设计思想
- 不同于面向类,基于原型的语言是对实例友好的
- 实现继承
-
铁三角
-
构造函数
- prototype指向原型对象
- constructor指向构Function
-
原型对象
- constructor指向构造函数
- prototype指向原型的原型
-
实例
- prototype指向原型对象
- constructor指向构造函数
- 组合继承?
-
读写
-
读
- 先遍历自身的属性,如果没有一层层往上层寻找
-
写
- 如果原型存在该属性,则对该实例自身创建属性
-
ES6
-
let
-
暂时性死区
- 存在,但是不让使用
- 所以提前使用会报错
- const
- 块级作用域
- =>
- 解构
-
module
-
和CMD的区别
- ES6
- 静态分析
- 引用方式
- 异步
- Set
- map
- Object.observer()
-
symbol
- 不可改变且唯一的
- 以被用做对象属性的键
- 对原始数据类型的隐式对象包装器。
- 可以用来避免被覆盖
- 模板字符串
-
数组判断
- Object.prototype.toString.apply([]) === "[object Array]"
- [].constructor === Array
- [] instanceof Array === true
- Array.isArray([])
-
for-in for-of
-
for-in
- 循环对象&数组
- 循环只遍历可枚举属性
- 循环将遍历对象本身的所有可枚举属性,以及对象从其构造函数原型中继承的属性(更接近原型链中对象的属性覆盖原型属性)。
- 如果你只要考虑对象本身的属性,而不是它的原型,那么使用 getOwnPropertyNames() 或执行 hasOwnProperty() 来确定某属性是否是对象本身的属性(也能使用propertyIsEnumerable)
-
for-of
- 循环数组
- ES6新特性
- 不会循环对象的key,只会循环对象的value
- 遍历实现iterator接口
-
箭头函数
- 比函数表达书更简洁
- 没有this和arguments
-
复制对象
- for-in
-
object.assign()
- 浅拷贝
-
JSON.parse(JSON.stringify(obj))
- 方法不能用于复制用户定义的对象方法
- 不能用于复制循环引用对象。
-
展开操作符(…)
- 浅拷贝
- 自实现
-
类型判断
- Object.prototype.toString.call('')
-
事件阻止
-
阻止传播
-
event.Propagation()
- W3C
-
event.cancleBubble()
- IE
-
默认事件
-
event.preventDefault()
- W3C
-
return false
- 原生JS事件
- 阻止默认行为
- jQuery
- 阻止默认行为
- 阻止冒泡
- W3c
-
e.returnValue = false
- IE
-
iterator接口?
- 遍历器(Iterator)就是这样一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作(即依次处理该数据结构的所有成员)。
- 各种数据结构,提供一个统一的、简便的访问接口
- 数据结构的成员能够按某种次序排列
- 供for...of消费
-
编解码
-
escape
- 已从Web 标准中删除
- 对字符串进行编码,让计算机可以读取
-
编码集合
- 除
- ASCII 字母和数字
- ASCII 标点符号 - _ . ! ~ * ' ( )
-
encode
-
encodeURI
- 把字符串作为URI进行编码
- 目的是对 URI 进行完整的编码
- 编码集合
- 除
- 非转义字符
- 字母 数字 - _ . ! ~ * ' ( )
- 保留字符
- ; , / ? : @ & = + $
- 数字符号
- #
-
encodeURIComponent
- 编码集合
- 除
- 字母 数字 - _ . ! ~ * ' ( )
- ;/?:@&=+$,# 这些用于分隔 URI 组件的标点符号
- 十六进制的转义序列
-
decode
- docodeURI
- decodeURIComponent
-
类型化数组
- 通用的、固定长度的二进制数据缓冲区
-
JS开始执行时机
-
window.load
- 必须等待网页中所有内容加载完毕后才能执行
-
$(document).ready
- dom结构绘制完毕后开始执行
- 封装了ondomcontentready、ondomcontentloaded
-
HTTP
-
cookie和session
-
cookie
- 服务器在本地机器上存储的小段文本
- 只能保管ASCII字符串
- 受浏览器安全策略限制
- 而Cookie保管在客户端,不占用服务器资源
-
session
- 服务器端的机制
- 任何类型的数据
- Session存储在服务器上,对客户端是透明的,不存在敏感信息泄露的风险
- Session是保管在服务器端的,每个用户都会产生一个Session。假如并发访问的用户十分多,会产生十分多的Session,耗费大量的内存
-
基本概念
-
请求头
- request header
-
响应头
- response header
-
状态码
-
分类
- 1xx
- 信息响应类
- 2xx
- 处理成功响应类
- 3xx
- 重定向响应类
- 4xx
- 客户端错误类
- 400
- 客户端有语法错误,不能被服务器理解
- 401 未授权
- 403 拒绝提供服务
- 404
- 资源不存在
- 5xx
- 服务端错误
- 解决了什么问题
-
报文
-
是什么
- 承载多个请求参数的数据
- 报文格式
-
一次http完整的过程
- 输入网址
- 根据DNS,将域名解析为IP地址
-
建立TCP连接
- 三次握手
- 客户端发送报文
-
服务端应答
- 服务端返回状态码和请求体
- 关闭TCP连接
-
Accept - Encoding的作用,和性能有关系
- 对body部分进行编码,达到压缩的目的
-
编码类型
-
gzip
- 好处
- 节省空间
- 弊端
- JPEG这类文件用gzip压缩的不够好
- compress
-
deflate
- zlib
-
请求方式
-
get和post区别
-
同
- TCP链接
- 底层是TCP/IP
- GET和POST能做的事情是一样的
-
定义
- get
- Get是向服务器发索取数据的一种请求
- post
- Post是向服务器提交数据的一种请求
-
不同
- 长度
- get
- 无长度限制
- 但是浏览器会对URL厂区做出限制,2000多个字符
- post
- 无长度限制
- 大多数服务器最多处理64K大小的url
- 字符
- get
- ASCII字符
- post
- 没有限制
- 编码
- get
- application/x-www-form-urlencoded
- post
- POST支持多种编码方式
- 安全
- get
- GET参数直接暴露在URL上
- post
- POST参数在HTTP消息主体中
- 不会被保存在浏览器历史
- 缓存
- get
- 请求会被浏览器主动缓存
- post
- POST不会
- 浏览器
- GET请求参数会被完整保留在浏览器历史记录里
- 而POST中的参数不会被保留
- 建立过程?
- 产生一个TCP数据包
- 浏览器会把http header和data一并发送出去,服务器响应200(返回数据)
- 产生两个TCP数据包
- 浏览器先发送header,服务器响应100 continue
- 浏览器再发送data,服务器响应200 ok(返回数据)
- https://zhuanlan.zhihu.com/p/25028045
- https://www.zhihu.com/question/20552352
-
请求类型
- get
-
post
- 创建
-
put
- 更新
- delete
-
head
- 仅仅返回相应的头部,没有具体的响应体。它也不会对服务器造成其他影响
- TRACE
-
options
- OPTIONS允许客户端请求一个服务所支持的请求方法。它所对应的响应头是Allow,它非常简洁地列出了支持的方法。下面为服务端成功处理了OPTIONS请求后,响应的内容:
- Allow: HEAD,GET,PUT,DELETE,OPTIONS
- 发生时机?
- connect
- 用途?
- websocket
-
异步请求和同步请求的区别
-
异步请求
- 并行处理
- 不等待
-
同步请求
- 顺序处理
- 等待
-
TCP/IP
-
协议集
- 应用层
- 传输层
- 网络层
- 网络访问层
-
三次握手
-
1 客户端到服务器
- 等待确认
- 2 服务器告诉客户端,收到消息,进入等待状态
- 3 客户端收到消息,发送确认包
- 然后,再传递消息
- 断开连接时服务器和客户端均可以主动发起断开TCP连接的请求
-
四次分手
- 客户端提出分手请求
- 服务端收到请求,关闭连接
- 并提出反方向关闭请求
- 客户端对服务端请求确认,双方向的关闭结束
-
http2
-
多路复用
- 相同域名请求通过同一个TCP链接并发完成
- Hpack头压缩
-
二进制传输
- 1.x为文本格式
- 服务端推送
-
解决队头阻塞问题
- 帧
- 流
-
vs 1.x keep alive
- 1.x 串行传输
-
https?
- 证书颁发机构CA
-
https的信任基于预先安装在浏览器中的证书颁发机构
- 我信任证书颁发机构我应该信任的
- HTTPS报文中的任何东西都被加密,包括所有报头和荷载。
-
和http的差异
-
端口
- http
- 默认80端口
- https
- 默认443端口
-
加密
- 对称加密
- 非对称加密
- 中心化加密
- 去中心化加密
- https://github.com/Advanced-Frontend/Daily-Interview-Question/issues/74
-
优化
-
性能优化
-
原则
-
选择合适的衡量指标、测试用例、测试环境,找到瓶颈
- 度量
- 首次有效渲染
- 重要渲染时间
- 可交互时间
- 输入响应
- 不要过早优化
- 忌过度优化
- 性能优化是持久战
-
方向
-
语言本身
- css
- 嵌套
- 合理使用硬件加速
- 少用高消耗属性
- calc
- shadow
- js
- 语法
- 针对JIT的优化
- 隐藏类
- WebWorker
- 框架
-
网络
- 分类
- 缓存技术
- 负载均衡
- 压缩
- 优化协议(HTTP,HTTP2.TCP/IP)
- CDN
- 减少HTTP请求为何能优化速度
-
构建
- 压缩
- 分包
- tree shaking
- aot
- 并行处理
-
容器类优化
- 引擎优化
- Wasm
- 整体结构优化
- RN
- fluter
- 混合应用
- Hybrid
- 小程序
-
性能优化
-
页面加载链路优化
-
网络
- CDN
- HTTP请求数量
- 压缩
-
资源
- 分包
- 压缩
- 懒加载
- 缓存
- 热加载&离线包
-
首屏
- 首屏处理
- 外壳处理
- 拆分过程,并行处理
-
runtime优化
-
容器
- WKWebview
- V8
- 内联类
- wasm
- RN
- canvas
- webgl
- 硬件加速
-
语言层面
- CSS
- JS
- 框架层面
-
视觉
- 动画
-
交互
- 避免重排重绘
- fastclick
- 解决问题
- 300ms延迟
- 原因
- 移动浏览器存在双击缩放或双击放大操作
- 第一次点击之后,系统需要等待300ms,以判断用户是否再次点击了屏幕
- 事件发生顺序
- touchstart
- touchmove
- touchend
- click
- 解决方法
- 禁用缩放
- user-scalable=no
- 但同时也禁用了双指缩放操作
- 更累默认视口宽度
- <meta name="viewport" content="width=device-width"></code>
- 仍可进行双指缩放操作
- 指针事件
- pointerdown事件
- css touchaction: none
- 是否触摸操作会触发用户代理的默认行为
- zepto tap
- document
- touch事件
- 计算时间和位置差
- fastlick
- 监听touchend
- 发出自定义click事件
- 把原来的click事件阻止掉
-
方案
-
自适应方案
-
响应式布局
- 通过媒体查询
-
viewport缩放
- 简单、高效
-
rem布局
- 动态设置根元素font-size,等比缩放元素大小
-
lazyimage
- 图片先用占位图表示,属性放到data里面
- 页面加载完成后,监听窗口滚动,
- 当图片出现在视口内,再赋予真实的地址
-
安全
- DOS攻击
-
XSS攻击与防御
-
含义
- 跨站脚本攻击
-
方法
- 恶意将未经过滤的代码植入到页面中
-
分类
-
反射性
- URL到页面
-
持久型
- 数据库
-
避免
-
常见符号编码转换
- & < > " ' /
- 对诸如<script>、<img>、<a>等标签进行过滤
-
HttpOnly
- 避免cookie劫持
- HTML 属性、HTML 文字内容、HTML 注释、跳转链接、内联 JavaScript 字符串、内联 CSS 样式表等,所需要的转义规则不一致。 业务 RD 需要选取合适的转义库,并针对不同的上下文调用不同的转义规则。
-
CSRF攻击
-
跨站请求伪造
- 攻击者盗用了用户的身份,以用户的名义发送恶意请求
- 在不同的domain下,攻击者却能为造出”用户本人发出的request“
-
避免
- 关键请求使用验证码或者token机制
- 验证码
- 在HTTP 头中自定义属性并验证
-
Cross Site
- 验证 HTTP Referer 字段
- 具体来说就是服务器每次返回客户端页面的时候,在页面中埋上一个token字段
- SameSite
-
参考
- https://blog.techbridge.cc/2017/02/25/csrf-introduction/
-
HTTP劫持与对策
- https
-
浏览器
-
渲染过程
-
JS触发reflow?
-
JS
- 影响到DOM变化
-
Style
- 根据css计算变化后的dom样式
-
layout
- 计算每个 DOM 元素最终在屏幕上显示的大小和位置
-
Paint
- 为每个dom填充像素
- 本质上就是填充像素
- 一个DOM的所有可是效果
- 这个绘制过程是在多个层上完成的。
-
Composite
- 渲染层合并
- 在每个层上完成绘制过程之后,浏览器会将所有层按照合理的顺序合并成一个图层,然后显示在屏幕上
- 完成绘制之后,浏览器会按照所有层顺序,合理的合并成一个图层,显示在屏幕上
- 某些特殊的渲染层会被认为是合成层(Compositing Layers),合成层拥有单独的 GraphicsLayer,
-
扩展
- 某些特殊的渲染层会被认为是合成层(Compositing Layers),合成层拥有单独的 GraphicsLayer,而其他不是合成层的渲染层,则和其第一个拥有 GraphicsLayer 父层公用一个。
- 每个 GraphicsLayer 都有一个 GraphicsContext,GraphicsContext 会负责输出该层的位图,位图是存储在共享内存中,作为纹理上传到 GPU 中,最后由 GPU 将多个位图进行合成,然后 draw 到屏幕上,此时,我们的页面也就展现到了屏幕上。
- http://taobaofed.org/blog/2016/04/25/performance-composite/
-
层压缩
-
原因
- 大量合成层来,而每个合成层都要消耗 CPU 和内存资源,岂不是严重影响页面性能
-
事件模型
-
DOM0级模型
- 事件不会传播,即没有事件流的概念
- btn.onclick = fun;
-
DOM2级模型
- W3C标准模型
-
三个阶段
- 捕获
- 目标
- 冒泡
- 兼容问题
- WebGL渲染的过程?
-
缓存策略
-
分类
- DNS缓存
- CDN缓存
-
浏览器缓存
- 强缓存
- cache-control
- no-cache
- max-age=<seconds>
- expires
- 协商缓存
- Last-Modify
- ETag
-
同源策略
-
定义
- 限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的重要安全机制
- 协议,端口(如果有指定)和域名
-
web语义化
- 使用恰当语义的html标签、class类名等内容,让页面具有良好的结构与含义,从而让人和机器都能快速理解网页内容。
-
线程
-
含义
- 程序执行中一个单一的顺序控制流程
-
为什么浏览器是单线程设计
- 如果JavaScript是多线程的方式来操作这些UI DOM,则可能出现UI操作的冲突
-
浏览器中的线程
-
界面渲染线程
- GUI 渲染线程 与 JavaScript引擎线程互斥
- javascript引擎线程
- Http请求线程
- 定时触发器线程
- 浏览器事件触发线程
-
进程
-
含义
-
代表CPU所能处理的单个任务
- 有单独的内存区域
-
和线程的关系
- 一个进程由一个或多个线程组成
- 线程是一个进程中代码的不同执行路线
- Chrome浏览器使用多个进程来隔离不同的网页
-
HTML加载过程?
- 输入地址,返回HTML
-
加载DOM
-
遇到body标签
- 加载并渲染DOM
- 浏览器遇到dom元素时,正常顺序加载,边加载边渲染
-
内联CSS
- 浏览器继续加载,但渲染被阻塞
- 生成新的CSS Rule Tree
- 生成后重新渲染界面
-
内联Javascript
- DOM的加载和渲染同时被阻塞
- 由于JavaScript有可能会更改DOM Tree和Render Tree,因此同时被阻塞
-
外联Javascript
- DOM的加载和渲染同时被阻塞
- render tree
- layout
-
文档碎片?
- 内存
- 合成一个DOM?
-
内存管理
-
概念
- 像C语言一般都有自己的内存管理接口,JS创建变量时分配内存,而不再使用时再释放内存。
-
方法
-
标记清除
- 从根部开始遍历,找出不再使用的变量
- 阶段
- 初始阶段
- 标记阶段
- JS会停止运行
- 清楚阶段
- V8
- 增量标记
-
引用计数
- 优势
- 算法简单
- 释放时间快
- 劣势
- 循环引用问题
- 对计数要求高
- 不能并行计算
-
堆内存
- 全局变量
- 对象的引用
- 事件
- 定时器
-
堆和栈的区别
-
堆
- 动态分配的内存,大小不定也不会自动释放
- JS中引用类型占据空间大、大小不固定,栈内存中存放地址指向堆内存中的对象。按引用访问
-
栈
- 自动分配的内存空间,由系统自动释放
- 基本类型占据空间小、大小固定,值保存在栈空间。按值来访问
- 内存泄漏实例?
-
内核
- KHTML
-
Webkit
- 是排版引擎
- 01年开始苹果
-
组件
- JS Core
- webcore
- Drosera
- 调试工具
-
组成
- 渲染引擎
- HTML解释器
- CSS解释器
- 布局
- JS引擎
- JS 引擎
- 源代码 –> 抽象语法树 –> 字节码(跨平台) –> JIT –> 本地代码
-
Blink
-
blink
- 13年,webkit的分支
- V8
-
框架
-
Angular
-
脏值检查
-
数据何时变化
- 用户输入
- 请求服务端数据
- 定时事件
-
监听变化
- 使用zone.js Monkey patch的方式,监听所有异步事件
-
变化检测
- 新旧数据对比
- angular改善的脏检查
- 组件树
- 每个组件都有自己的变化检测器
- 变化检测器树
- 数据流自上而下
- 高效
- 可预测
- 相比之下,AngularJS采用的是双向数据流,错综复杂的数据流使得它不得不多次检查,使得数据最终趋向稳定。理论上,数据可能永远不稳定。AngularJS给出的策略是,脏检查超过10次,就认为程序有问题,不再进行检查。这个10,我不知道它的给出依据是什么,也许是个经验值吧。
- 变化检测对象
- 定制变化检测
-
DI
-
目标
- 控制反转
- 好处
- 降低代码之间的耦合度
- 每个对象都需要获取与其合作的对象(也就是它所依赖的对象)的引用。如果这个获取过程要靠自身实
-
实现方式
- 依赖注入
- Injector会自动帮你将需要的依赖注入到类的构造器里,并返回这个类的实例
-
使用的三个技术
- reflect-metadata
- typescript
- Decorator
- 数组绑定
-
生命周期
- ngOnChanges
- ngOnInit
- ngDoCheck
-
ngAfterContentInit
- 在外来内容被投影到组件中之后/投影组件内容的变更检测之后调用
- ngAfterContentChecked
-
ngAfterViewInit
- 初始化完/检测变更完组件视图及其子视图之后调用。
- ngAfterViewChecked
- ngOnDestroy
-
Vue
-
数据绑定
-
实现原理
- 数据劫持的方式来做数据绑定
- 方法
- Object.defineProperty()
- getter
- setter
- notify
- 监听变化
- Watcher
- Observer
-
React
-
本质
- 规范
- 接口
-
数据绑定
-
数据变化
- setState()通知变化
-
数据更新
- virtual DOM
- 原理
- 本质上就是在 JS 和 DOM 之间做了一个缓存
- 会跟踪每一个组件的依赖关系
- 弊端
- 如果你的应用中,交互复杂,需要处理大量的UI变化,那么使用 Virtual DOM 是一个好主意。如果你更新元素并不频繁,那么 Virtual DOM 并不一定适用,性能很可能还不如直接操控 DOM。
- 好处
- diff
- 抽象
- diff算法
- react渲染机制、key的用途
-
生命周期
- shouldComponentUpdate
- componentWillUpdate
- componentDidUpdate
- componentWillMount
- componentDidMount
- componentWillReciveProps
- componentWillUnmout
- render
-
state和props
- state是做为状态管理
- 而props相当于api,由外界传入
- 问题
-
setState
-
this.updater
- 合并旧state
- 放进state队列,等待更新
- 集齐一批需要更新的组件然后一起更新
- updater
- react-dom
- render
- 它是异步的
- 没有脏值检查?
-
大三框架的比较
-
同
- 都以组件化为核心
- 都利用了MVVM设计模式
- 都可以完成各式的前端项目,只是方式和灵活度不同
-
不同
-
核心思想
- react
- 对view层的抽象定义,规范化、接口化
- vue
- 以组件化和MVVM为核心,小而轻
- angular
- 利用用先进的设计模式和思想,提供系统化的解决方案,大而全
-
适合工程
- react
- 最适合抽象和跨端项目
- 中小型项目vue更合适,只是vue生态不及react
- vue
- 中小型工程
- angular
- 中大型工程
-
独特的优势
- react
- 极度抽象,跨平台
- vue
- 渐进式增强,对小项目非常友好
- angular
- 系统化、优秀的设计模式和思想
- 内置的优化解决方案
- MVC
- 单例
- 观察者
- 数据流
- 依赖翻转
- typescript
- CLI
-
缺点
- react
- 过度自由
- 太过抽象
- vue
- 学习者的姿态
- angular
- 小项目收益低
- 学习曲线高、概念多、难以理解
-
MVVM和Virtual Dom比较
- 初始渲染:Virtual DOM > 脏检查 >= 依赖收集
- 小量数据更新:依赖收集 >> Virtual DOM + 优化 > 脏检查(无法优化) > Virtual DOM 无优化
- 大量数据更新:脏检查 + 优化 >= 依赖收集 + 优化 > Virtual DOM(无法/无需优化)>> MVVM 无优化
-
架构
-
三种软件架构
-
目标
- 面向GUI编程领域
-
分类
-
MvvM
- 软件架构模式
- 软件逻辑和数据逻辑分离开来
- 视图模型是暴露公共属性和命令的视图的抽象
- 包含
- 模型
- 代表真实状态的数据模型
- 视图
- 视图模型
- 暴露公共属性和命令的视图的抽象
- 绑定器
- 声明性数据和命令绑定
- 绑定器使开发人员免于被迫编写样板式逻辑来同步视图模型和视图
-
MVC
- 模型
- 控制器
- 视图
-
MVP
- 对MVC的变种
- Presenter 可以理解为松散的控制器,其中包含了视图的 UI 业务逻辑
-
实践
-
典型项目
-
项目
- 数据配置平台
-
身份
- 主导者
- 设计者
- 开发者
-
系统
- 数据配置
-
粒度划分
- 空间
- 项目
- 项目
- 回滚
- 权限
- 用户管理
- 日志
- 良好的交互
-
技术选型
- angular
- node.js
- mongodb、mysql
- php + mysql
-
遇到的问题
-
配置形式
- 配置的表达形式
- json
- 针对每个业务进行可视化开发
- 策略
- 解决方案
- json和可视化自动转换方案
- 操作
- 研发使用json进行数据编辑
- 业务方使用可视化进行编辑
- 原理
- 正向
- json string
- monaco编辑器
- 转成comment json
- 包含注释信息的json
- 解析comment json
- 取出数据和标题
- 转成angular form reactive表达形式
- 将form reactive转化为视图
- 针对每种数据类型做优化
- 数字
- 字符串
- 布尔型
-
php接口逻辑和压力
- 自动化测试脚本
- 压力测试
- 每天上亿的流量
-
如何解决问题
- 理解目标、找到瓶颈
- 监控和优化案例
-
工程化
-
WebPack打包原理
-
require
- 根据node的规范封装的模块化
-
名词
-
loader
- 模块转换器
-
plugin
- 自定义打包流程
-
过程
-
准备
- 加载所有插件
- 确定入口文件
-
编译
- 递归寻找模块依赖
- 调用loader对模块进行编译
-
资源输出
- 输出chunk文件
-
软
- 未来工作计划
- 为什么选择前端
- 平时关注新技术吗?哪些渠道
- 项目选型
- 缺点
- 跳
-
简单算法
-
数组去重
- Array.from(set)
- 排序后去重
- filter
- 双层循环
-
频率控制
-
防抖 debounce
-
含义
- 高频事件
- n秒内只执行一次
- 如果n秒内再次被触发,则重新触发时间
-
实现思路
- 每次事件触发后,都取消原来的延时处理方法
-
节流 throttle
-
含义
- 在n秒内忽略随后发出的源值
-
实现思路
- 每次触发事件时,都判断当前是否有延时函数
-
数组扁平化
- Array.from(new Set(arr.flat(Infinity))).sort((a,b)=>{ return a-b})
-
高级应用
-
状态管理
-
redux
- JavaScript 状态容器,提供可预测化的状态管理
-
动机
- state过多,来源复杂
- 服务器数据
- 缓存
- 路由
- 让state的变化可预测
-
好处
- 一个action对应了一个完整的应用状态
- 历史记录功能
- 易于测试
- reducer是纯函数
-
概念
- action
- 行为、指令
- store的唯一数据来源
- reducer
- 响应action,并发送到store
- store状态容器
- mobx
- rxjs
-
Pendding
-
HTML加载过程?
- http://fex.baidu.com/blog/2014/05/what-happen/