汇总
项目结构 js-node-java ng
移动端适配 IP6 750 rem
设备像素
屏幕物理像素 任何设备屏幕的物理像素的数量都是固定不变的,单位是ptjavascript
css像素 px
https://github.com/riskers/blog/issues/17
https://github.com/riskers/blog/issues/18php
延伸 「像素」「渲染像素」以及「物理像素」
display 布局展示
1. none; block;
2. inline <span>
3. inline-block <input>
4. list-item <li>
5. table <table>
6. inline-table
7. table-row-group <tbody>
8. table-header-group <thead>
9. table-footer-group <tfoot>
10. table-row <tr>
11. table-column-group <colgroup>
12. table-column <col>
13. table-cell <td> <th>
14. table-caption <caption>
15. run-in:
16. 旧版本 flexbox 的使用 safari浏览器
box: 块伸缩容器
inline-box: 内联级伸缩容器
17. 混合版本flexbox模型 IE10浏览器 “-ms-”
flexbox:
inline-flexbox:
18. 新版本flexbox模型
flex:
inline-flex:
position static
1. static 文档的常规位置 不会从新定位
2. relative
3. absolute
4. fixed
1-10000的随机数 获得1-10
1-10000 取特定数 取几回 2进制
hybrid 原理。桥 协议 js注入webview
es6多了什么新特性
添加了块级做用域,
一个{}表明一个块级做用,做用域嵌套时外层代码块不受内层代码块的影响,
使得当即执行匿名函数(IIFE)不在必要; IIFE本来的做用是为了造成局部做用域,防止变量污染;
函数自己的做用域,在其所在的块级做用域以内。 es5 存在函数提高,无论函数在何处声明,函数声明都会提高到当前做用域的顶部,获得执行.而es6支持块级做用域,其内部声明的函数皆不会影响到做用域的外部。
增长了语法糖
let命令 所声明的变量,只在let命令所在代码块内有效
- 不会像var同样声明提早,只能在定义以后使用
- 只要做用域内有let声明的变量,这个变量就会被绑定,不受原来变量声明规则的影响。es明确规定,若是区块中存在let和const命令,这个区块对这些命令声明的变量,从一开始就造成了封闭做用域。凡是在声明以前就使用这些命令,就会报错ReferenceError。 这在语法上,称为“暂时性死区”。
- 函数的做用域是其声明时所在的做用域
- 不容许在相同做用域内,重复声明同一个变量。所以不能在函数内部从新声明参数。
const命令 用来声明常量, 一旦声明, 常量的值就不能改变
- 对常量从新赋值不会报错,只会默默地失败
- 只在声明所在的块级做用域内有效
- 不存在提高,只能在声明的后面使用,提早使用会抛出ReferenceError
- 不可重复声明
只是指向变量所在的地址; 若是将const常量赋值为一个对象,则此常量储存的是一个地址,不可变的只是这个地址,但对象自己是可变的,依然能够为其添加新属性。css
全局对象的属性
全局对象是最顶层的对象,在浏览器环境指的是window对象, 在Node.js指的是global对象。ES5规定,全部全局变量都是全局对象的属性;ES6规定,var命令和function命令声明的全局变量,属于全局对象的属性; let命令、const命令、class命令声明的全局变量,不属于全局对象的属性。html
变量的解构赋值
- 按照必定模式,从数组和对象中提取值,对变量进行赋值,这被称之为解构(Destructing)。解构只能用于数组或对象。其余原始类型的值都是能够转为相应的对象,除了undefined 和null
- 对数组的解构赋值,容许指定默认值。(只要某种数据结构具备Iterator接口,均可以采用数组形式的解构赋值,set结构也可用)
- 对象的解构,属性没有次序,变量必须与属性同名。 能够很方便地将现有对象的方法,赋值到某个变量。对象的解构一样能够指定默认值,而且能够与函数参数的默认值一块儿使用。
增长了字符串处理、
字符串处理的加强,字符以utf-16格式储,每一个字符固定2个字节。对于那些须要4个字符,js 会认为是两个字符。 es6 加强了对码点大于0xFFFF的字符的总体处理和正则匹配。
- codePointAt() 正确返回四字节的UTF-16字符的 对于常规字符返回结果与 charCodeAt 方法相同
- String.fromCodePoint() 正确返回编号大约0xFFFF码点对应的字符 弥补String.fromCharCode 方法的不足
- at() 返回字符串给定位置的字符,若是该字符的Unicode 编号大于 0xFFFF,能够返回正确的字符。 chatAt()只能返回UTF-16编码的第一个字节,不能正确返回
- 字符的Unicode表示法: "\u{20BB7}"的形式能够正确表示超出\uFFFF的双字节字符
- normalize() String.prototype.normalize()方法。。。
- includes() 返回布尔值,是否找到参数字符串,支持第二个参数,表示开始搜索的位置
- startsWith() 返回布尔值,表示参数字符串是否在源字符串的头部,支持第二个参数,表示开始搜索的位置
- endsWith() 返回布尔值,表示参数字符串是否存在源文件的尾部。支持第二个参数,表示对前N个字符进行搜索
- repeat() 返回一个新字符串,表示将原字符串重复n次
模板字符串
- 加强字符串,用反引号(')标识,普通字符串 多行字符串 字符串中嵌入变量
- 在模板字符串中嵌入变量,须要将变量名写在$()之中
- 反引号 斜杠转义
- 大括号内部能够进行运算, 以及引用对象属性,其中还能调用函数。
- 模板字符串能够紧跟一个函数名后面,该函数将被调用来处理这个模板字符串。函数的参数为模板字符串中没有变量替换的部分组成的数组,第一个参数以后的参数,都是模板字符串各个变量依次被替换后的值, 拥有一个raw属性
数值的扩展
- 二进制和八进制表示法 ??? 0b 0o
- 扩展函数
Number.isFinite()用来检查一个数值是否非无穷(infinity);
Number.isNaN() 用来检查一个值是否为NaN
区别在于传统方法先调用Number(),将非数值的值转为数值,再进行判断,而这两个新方法只对数值有效,非数值一概返回false
Number.parseInt()与Number.parseFloat() 将全局方法,移植到Number对象上面,行为彻底保持不变
Number.isInteger() 用来判断一个值是否为整数。 在javascript内部,整数和浮点数是一样的储存方法,3和3.0被视为同一个值
Number.isSafeInteger() 则是用来判断一个整数是否落在Number.MAX_SAFE_INTEGER 和Number.MIN_SAFE_INTEGER 这两个常量表示的上下限范围内
Math对象上提供了许多新的数学方法
数组的扩展
- 数组推导:直接经过现有数组生成新数组的一种简化写法, 经过 for...of结构,容许多重循环。 注:新数组会当即在内存中生成,这时若是原数组是一个很大的数组,将会很是耗费内存。
- 数组处理的扩展方法:
- Array.from():用于将两类对象转为真正的数组。相似数组的对象(array-like object)和可遍历(iterable)的对象,其中包括ES6新增的Set和Map结构。 Array.from() 还能够接受第二个参数,做用相似于数组的map方法,用来对每一个元素进行处理
- Array.of() 用于将一组值,转换为数组。弥补数组构造函数Array()的不足。
- 数组实例的find()用于找出第一个符合条件的数组元素
- 数组实例的findIndex() 用于返回第一个符合条件的数组元素的位置。 这两个方法均可以发现NaN
- 数组实例的fill() 使用给定值 填充一个数组
- 数组实例的entries() 键值对的遍历 ,keys() 针对键名的遍历 和values() 针对键值的遍历, 用于遍历数组,它们都返回一个遍历
对象的扩展
加强的对象写法 容许直接写入变量和函数,做为对象的属性和方法
容许字面量定义对象时,用表达式做为对象的属性名,即把表达式放在方括号内,容许变量渗入key中前端
- Object.is() 用来比较两个值是否严格相等。与严格比较浮的不一样之处 ,+0不等于-0, NaN等于自身
- Object.assign() 用来将源对象(source)的全部可枚举属性,复制到目标对象(target)。它至少须要两个对象做为参数,第一个是目标对象,后面的参数都是源对象。 同名属性,后面覆盖前面。
- proto属性
用来读取或设置当前对象的prototype对象
- Object.setPrototypeOf()方法的做用与proto相同,用来设置一个对象的prototype对象,是es6正式推荐的设置原型对象的方法
- Object.getPrototypeOf()方法用于读取一个对象的prototype对象
- Symbol原始数据类型,表示独一无二的ID,经过Symbol函数生成。凡是属性名属于Symbol类型,就都是独一无二的,能够保证不会与其余属性名产生冲突。Symbol函数能够接受一个字符串做为参数,表示Symbol实例的名称。
- Proxy
用于修改某些操做的默认行为,等于在目标对象以前,架设一层“拦截”,外界对该对象的访问,都必须经过这层拦截,所以提供了一种机制,能够对外界的访问进行过滤和改写。而 Proxy.revocable()方法则返回一个可取消的Proxy实例。
- Object.observe() Object.unobserve()
Object.observe()方法用来监听对象(以及数组)的变化。一旦监听对象发生变化,就会触发回调函数。
Object.unobserve()方法用来取消监听。
- add 添加属性
- update 属性值的变化
- delete 删除属性
- setPrototype设置原型
- reconfigure 属性的attributes 对象发生变化
- preventExtensions 对象被禁止扩展
函数的扩展
- 函数参数默认值 使用=形式
- 指定了默认值以后,函数的length属性,将返回没有指定默认值的参数个数
- 参数默认值所处做用域 是函数做用域 而非全局做用域
- 双重默认值
- rest运算符
- ...变量名:将多余的参数放入一个数组中,rest参数必须为最后一个, 函数的length属性,不包括rest参数
- ... 数组: 将数组转为用逗号分割的参数序列
- 箭头函数
- 函数体内this对象,绑定定义时所在的对象,而不是使用时所在的对象
- 不能够当作构造函数,不可使用new命令,不然抛出一个错误
- 不可使用arguments对象,该对象在函数体内不存在
尾调用优化:java
Set Map数据结构
遍历器(Iterator)
- 一种接口规格; 一是为各类数据结构提供一个统一的 简便的接口,二是使得数据结构的成员可以按某种次序排列
- 调用这个接口,返回一个遍历器对象。 该对象具有next方法,每次调用该方法,会返回一个具备value 和done 两个属性的新对象,指向部署了 Iterator接口的数据结构的一个成员
- for...of 数组 类数组对象 Set Map结构
默认的Iteratorj接口部署在数据结构的Symbol.iterator属性,也就是说调用Symbol.iterator方法,就会获得当前数据结构的默认遍历器
- 调用默认iterator接口的场合:
进行如下操做时,会自动去调用默认iterator接口:
首先是上面介绍的for...of结构;
对数组和Set结构进行解构赋值时,会默认调用iterator接口;
扩展运算符(...)也会调用默认的iterator接口;
yield*
Array.from()
Map(), Set(), WeakMap(), WeakSet()
Promise.all(), Promise.race()
引入generator函数控制函数的内部状态的变化
generator 普通函数
两个特征:node
- function命令与函数名之间有一个星号
- 函数体内部使用 yield 语句,定义遍历器的每一个成员
- 一个函数的内部状态的遍历器,每调用一次,函数的内部状态发生一次改变
next方法的参数
- yield语句自己没有返回值,或者说老是返回undefined。next方法能够带一个参数,该参数会被看成上一个yield语句的返回值。这个功能有很重要的语法意义,Generator函数从暂停状态到恢复运行,它的上下文状态(context)是不变的。经过next方法的参数,就有办法在Generator函数开始运行以后,继续向函数体内部注入值。
yield* 语句
- 若是yield 后面跟的是一个遍历器,须要在yield命令后面加上星号。表示返回的是一个遍历器,则遍历有地柜效果 ,若是后面跟的是数组,表示该数组会返回一个遍历器,所以就会遍历数组成员
- 二叉树
Generator函数的应用
- 异步操做同步化
- 控制流管理:yield语句是同步运行,因此多层回调函数能够改写为直线执行的形式。
- 任意对象上部署 iterator 接口
原生提供了Promise对象
- 任务三种状态: 默认(pending) 完成(fulfilled) 失败(rejected)
- 默认状态能够单向转移到完成状态,这个过程叫resolve
- 默认状态能够单向转移到失败装填,这个过程叫reject
- deferred.notify(update)宣告任务执行信息,执行进度; 状态转移是一次性的,一旦任务由初始的pending 转为其余状态,就会进入到下一个任务的执行过程当中。
- 是一个构造函数,用来生成Promise实例。 接受函数做参数,resolve()成功 reject()失败
- 实例生成后 用then方法指定resolve方法 reject方法的回调函数; then方法 返回的是新的Promise对象,能够采用链式写法。多个then执行时前一个回调函数完成之后,会将返回结果做为参数,传入后一个回调函数。若是前一个回调函数返回的是Promise对象,这时后一个回调函数就会等待该Promise对象有了运行结果,才会进一步调用。
- Promise.prototype.catch方法是Promise.prototype.then(null, rejection)的别名,用于指定发生错误时的回调函数。
Promise.all() 将多个Promise实例,包装成一个新的Promise实例。
var p = Promise.all([p1,p2,p3]); 只有p一、p二、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p一、p二、p3的返回值组成一个数组,传递给p的回调函数。 只要p一、p二、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。 Promise.race():与Promise.all()形式相似,不一样的是只要p一、p二、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的Promise实例的返回值,就传递给p的返回值。
git
引入了Class(类)的概念,并在语言规格的层面上实现了模块功能
Class “类”, constructor方法表示构造方法,this关键字表明实例对象。
- prototype 在ES6继续存在,除了constructor方法外,类的方法都定义在类的prototype属性上面
- extends关键字,实现继承
- 子类必须在constructor方法中调用super方法,不然新建实例时会报错。
- 若是子类没有定义constructor方法,这个方法会被默认添加
- 在子类的构造函数中,只有调用super以后,才可使用this关键字,不然会报错。
- Class做为构造函数的语法糖,同时有prototype属性和proto属性:
- 子类的proto属性,表示构造函数的继承,老是指向父类。
- 子类prototype属性的proto属性,表示方法的继承,老是指向父类的prototype属性。
- 特殊状况:
- ES6模块经过export命令显式指定输出的代码,输入时也采用静态命令的形式。
- 取代import语句,总体输入模块做用
- export default 定义模块的默认方法
export * from circle "export *“ 输出circle模块的全部属性和方法 即继承github
- ES6 模块转码
- module transpiler CommonJS模块 AMD模块写法
- SystemJS 能够在浏览器内加载ES6模块 AMD模块 CommonJS模块 将其转为ES5格式
http://imweb.io/topic/55e330d6771670e207a16bbb
https://imququ.com/post/set-map-weakmap-in-es6.html
es6中新增的几种集合类型 Set、Map和WeakMap的区别
set
类数组,成员值惟一 没有重复值
不会发生类型转换,5“5” 内部判断两个值是否不一样,相似于精确相等运算(===),例外NaN等于自身
* 属性
Set.prototype.constructor 构造函数 默认是Set函数
Set.prototype.size 返回Set的成员总数
* 方法
add(value) 添加某个值 返回Set结构自己
delete(value) 删除某个值,返回一个布尔值,表示删除是否成功
has(value) 布尔值,是否为Set成员
clear() 清除全部成员,没有返回值
values 返回一个遍历器,set结构的默认遍历器就是它的value方法 能够直接用for...of 循环进行遍历
WeakSet 不重复值结合
与Set区别
* 成员只能是对象; 具备 iterable 接口的对象 eg 数组或者类数组对象
* 对象都是弱引用,即垃圾回收机制不考虑WeakSet对该对象的引用,若是其余对象不在引用该对象,那么垃圾回收机制会自动回收该对象所占用的内存,不考虑该对象还存在于WeakSet之中。 用途:储存DOM借点,不用担忧这些节点从文档移除时,会引起内存泄漏。
Map结构
类对象 键值对集合, 各类类型的值(包括对象)均可以看成键
Map的键 跟内存地址绑定,内存地址不同 视为两个键。同名属性碰撞(clash)的问题。
只有对同一个对象的引用,Map结构才将其视为同一个键
* 属性方法
size 返回成员总数
set(key,value) 设置一个键值对
get(key) 读取一个键
has(key) 返回布尔值,键是否在Map数据结构中
delete(key) 删除某个键
clear() 清除全部成员
keys() 键名的遍历器
values() 键值的遍历器
entries() 成员
for...of 遍历 firefox zhichia
WeakMap
只接受对象做为键名(null除外),不接受原始类型的值做为键名,并且键名所指向的对象,不计入垃圾回收机制,有助于防止内存泄漏
[https://imququ.com/post/set-map-weakmap-in-es6.html]
es6 promise VS es7 aysnc await
promise
循环执行 callback地狱 then
并发执行 并发执行多个任务时,能够有一个地方回收结果 Promise.all([,]).then(success); count
错误处理 统一用catch处理 promise chain里面出现的错误 callback里面没法用一个try接到深层的error
getUser().then(getArticle).then(success).catch(error);
array reduce 返回 最后一次调用回调函数得到的累积结果。
```
var p = Promise.resolve();
tasks.reduce(function(p, fn) {
return p = p.then(fn);
}, p).then(success);
```
async await 基本上這個語法的目的就是讓程式能再某些想卡住的地方能卡住,可是不是真的卡住,只是種語法糖。
在async function内, 能够用await语法去呼叫另外一个async function。
async function里 非同步事件由 promise or generator发起。
另外貼心的一點是 async function 預設會回傳一個 promise,就像 promise api 裡面 then 會幫你作的事一樣,只是搭配 await 以後其實就能够在非同步工做中用 await 語法取代掉 then 讓語法更簡潔。
http https 证书的做用
http
http 缺点 通信是用明文(不加密),内容可能会被窃听
不验证通讯方身份,一次有可能遭遇假装
没法真名报文的完整性,有可能已经被篡改
https
http+ 加密+认证+完整性保护 = https
- 身披SSL协议的这层外壳的HTTP
- 在采用SSL后, HTTP就拥有了HTTPS的加密, 证书和完整性的保护这些功能.
- SSL是独立于HTTP的协议, 全部不光是HTTP协议, 其余运行在应用层的SMTP(邮件协议)和Telnet等协议都可配合SSL协议使用. 能够说SSL是当今世界上应用最普遍的网络安全技术.
- SSL采用公开密钥加密 加密算法公开,密钥是保密的,安全性
对称密钥加密/ 共享密钥加密: 加密和解密同用一个密钥的方式
- 将密钥--对方 在互联网转发密钥时,通讯被监听 ? 安全转交? 使用两把密钥公开密钥加密
- 非对称密钥 : 一把私有密钥 一把公开密钥; 使用公开密钥加密方式, 发送密文的一方使用对方的公开密钥进行加密处理, 对方收到被加密的信息后, 在使用本身的私有密钥进行解密. 利用这种方式, 不须要发送用来解密的私有密钥, 也不用担忧密钥被攻击者窃听而盗走.
https混合加密机制,公开密钥加密和共享密钥加密并用的混合加密机制。公开密钥加密和共享密钥加密相比, 其处理速度要慢. 在交换密钥环节适用公开密钥加密方式, 以后的创建通讯交换报文阶段则使用共享密钥加密方式.
证实公开密钥的正确性的证书
数字证书认证机构和其余相关机关颁发的公开密钥证书;
- 服务器把本身的公开密钥登陆至数字证书认证机构
- 数字证书认证机构用本身的私有密钥向服务器的公开密钥署数字签名并颁发公钥证书
- 客户端拿到服务器的公钥证书后, 使用数字证书认证机构的公开密钥, 向数字证书认证机构验证公钥证书上的数字签名, 以确认服务器的公开密钥的真实性
- 使用服务器的公开密钥对报文加密后发送
- 服务器用私有密钥对报文解
跨站请求伪造。
伪造用户的正常操做,最好的方法是经过 XSS 或连接欺骗等途径,让用户在本机(即拥有身份 cookie 的浏览器端)发起用户所不知道的请求。
xss XCSRF
- 非get请求
发布帖子这一类建立资源的操做,应该只接受 POST 请求,而 GET 请求应该只浏览而不改变服务器端资源。
- 请求令牌
- “请求令牌”和“同步令牌”原理是同样的,只不过目的不一样,后者是为了解决 POST 请求重复提交问题,前者是为了保证收到的请求必定来自预期的页面。实现方法很是简单,首先服务器端要以某种策略生成随机字符串,做为令牌(token),保存在 Session 里。而后在发出请求的页面,把该令牌以隐藏域一类的形式,与其余信息一并发出。在接收请求的页面,把接收到的信息中的令牌与 Session 中的令牌比较,只有一致的时候才处理请求,不然返回 HTTP 403 拒绝请求或者要求用户从新登陆验证身份。
- 虽然请求令牌原理和验证码有类似之处,但不该该像验证码同样,全局使用一个 Session Key。由于请求令牌的方法在理论上是可破解的,破解方式是解析来源页面的文本,获取令牌内容。若是全局使用一个 Session Key,那么危险系数会上升。原则上来讲,每一个页面的请求令牌都应该放在独立的 Session Key 中。咱们在设计服务器端的时候,能够稍加封装,编写一个令牌工具包,将页面的标识做为 Session 中保存令牌的键。
- 在 ajax 技术应用较多的场合,由于颇有请求是 JavaScript 发起的,使用静态的模版输出令牌值或多或少有些不方便。但不管如何,请不要提供直接获取令牌值的 API。这么作无疑是锁上了大门,却又把钥匙放在门口,让咱们的请求令牌退化为同步令牌。
- 第一点说了请求令牌理论上是可破解的,因此很是重要的场合,应该考虑使用验证码(令牌的一种升级,目前来看破解难度极大),或者要求用户再次输入密码(亚马逊、淘宝的作法)。但这两种方式用户体验都很差,因此须要产品开发者权衡。
不管是普通的请求令牌仍是验证码,服务器端验证过必定记得销毁。忘记销毁用过的令牌是个很低级可是杀伤力很大的错误。咱们学校的选课系统就有这个问题,验证码用完并未销毁,故只要获取一次验证码图片,其中的验证码能够在屡次请求中使用(只要再也不次刷新验证码图片),一直用到 Session 超时。这也是为什么选课系统加了验证码,外挂软件升级一次以后仍然畅通无阻。
webkit渲染原理/渲染树css样式与dom结合/页面优化cdn css放前面js放后面
关键渲染路径
- 建立DOM树
html能够部分执行并显示
- 建立CSSOM树(对附在DOM结构上的样式的一种表示方式)
css是一种渲染阻塞资源, 彻底被解析以后才能进入生成渲染树环节
css继承属性,解析完成; css文件适用于当前设备时才能形成阻塞,eg:设备属性
eg
- 执行脚本
JavaScript是一种解析阻塞资源(parser blocking resource),它能阻塞HTML页面的解析。
当页面解析到<script>标签,无论脚本是內联的仍是外联,页面解析都会暂停,转而加载JavaScript文件(外联的话)而且执行JavaScript。这也是为何若是JavaScript文件有引用HTML文档中的元素,JavaScript文件必须放在那个元素的后面。
为了不JavaScript文件阻塞页面的解析,咱们能够在<script>标签上添加async属性,使得JavaScript文件异步加载。
- 生成渲染树
渲染树是DOM和CSSOM的结合,是最终能渲染到页面的元素的树形结构表示。也就是说,它包含能在页面中最终呈现的元素,而不包含那些用CSS样式隐藏的元素,好比带有display: none;属性的元素。
- 生成布局
布局决定浏览器视窗大小, 提供上下文依赖的css 样式 eg 百分比或窗口的单位
视口大小由<meta name="viewport" content=“决定”>
若是缺乏这个标签 一般默认为 980
- 绘制
页面上可见内容转化为屏幕上的像素点
绘制过程所需花费的时间取决于DOM的大小以及元素的css 样式。。
耗时样式eg: 复杂的渐变背景色 比简单的单色背景 渲染耗时
输入一个url后,会发生什么,一个页面输入后缓存会请求吗? last
页面的请求过程
- 浏览器的URL请求
- 递归寻找DNS服务器
- 接目标IP并创建TCP链接
- 向目标服务器发送http请求
- web服务器接收请求后处理
- web服务器返回相应的结果【无效、重定向、正确页面等】
- 浏览器接收返回的http内容
- 解析html文件,自上而下 先头部 后body
- 解析到头部的css外部连接时,同步去下载, 遇到外部js连接也是下载 【js 顶部 首屏加载时间】
- 解析body 边开始生辰该对应的DOM树 同时等待css 文件下载
- css文件下载完毕,DOM树+CSSOM --》 renderTree
- 渲染树一旦有告终构模型,同步去计算渲染树节点的布局位置
- 一旦计算出来渲染坐标后,同步开始渲染
- 10-13 若是遇到图片则跳过去渲染下面内容,等待图片下载成功后 会返回来在渲染原来图片的位置
- 同14步,若是渲染过程当中出现JS代码调整DOM树结构的状况,也会再次从新来过,从修改DOM开始
- 最终全部节点和资源都会渲染完成
- 渲染完成后开始page的onload时间
- 整个页面load完成
整个过程当中会有不少的分别请求,因此TCP链接会不少,而且每个用完都会本身关了,除非是keep-live类型的能够请求屡次才关闭。
https://yq.aliyun.com/articles/20667
web前端优化规则
减小 http 请求
合并脚本跟样式文件,如能够把多个css文件合成一个,把多个JS文件合成一个。
CSS Sprites利用css background相关元素进行背景图的绝对定位,把多个图片合成一个图片
使用浏览器缓存
在用户浏览网站的不一样页面时,不少内容是重复的,好比相同的JS、CSS、图片等。 强制浏览器在本地缓存这些文件,将大大下降页面产生的流量,从而下降页面载入时间。
根据服务器端的响应header,一个文件对浏览器而言,有几级不一样的缓存状态。
- 服务器端告诉浏览器不要缓存此文件,每次都到服务器上更新文件
- 服务器端没有给浏览器任何指示
- 在上次传输中,服务器给浏览器发送了Last-Modified或Etag数据,再次浏览时浏览器将提交这些数据到服务器,验证本地版本是否最新的,若是为最新的则服务器返回304代码,告诉浏览直接使用本地版本,不然下载新版本。通常来讲有且只有静态文件,服务器端才会给出这些数据。
服务器强制要求浏览器缓存文件,并设置了过时时间。在缓存未到期以前,浏览器将直接使用本地缓存文件,不会与服务器端产生任何通讯。
尽可能强制浏览器到第四种状态,特别是对于 JS、CSS、图片等变更较少的文件。
使用压缩组件
IE和Firefox浏览器都支持客户端GZIP,传输以前,先使用GZIP压缩再传输给客户端,客户端接收以后由浏览器解压,这样虽然稍微占用了一些服务器和客户端的CPU,可是换来的是更高的带宽利用率。对于纯文原本讲,压缩率是至关可观的。若是每一个用户节约50%的带宽,那么租用来的那点带宽就能够服务多一倍的客户,而且缩短了数据的传输时间。
图片、JS的预载入
JS中实例化一个新的Image(),
将脚本放在底部
脚本放在顶部带来的问题:
- 使用脚本时,对于位于脚本如下的内容,逐步呈现将被阻塞
在下载脚本时会阻塞并行下载
将样式文件放在页面顶部
- 白屏
无样式内容闪烁
使用外部的JS和CSS
将内联的作成外部的 减小重复下载内联的JS 和CSS
切分组件到多个域
主要的目的是提升页面组件并行下载能力. 但不要跨太多域名,建议采用2个域名。 img1.qunar。com img2.qunar.com
精简JS
- 精简:从代码中移除没必要要的字符以减小其大小
混淆:在精简的同时,还会改写代码、函数、变量名被转换成更短的字符串
可使用ShrinkSafe来精简JS http://shrinksafe.dojotoolkit.org/
精简CSS
从代码中移除没必要要的字符以减小其大小
可使用CSS Compressor http://www.cssdrive.com/index.php/main/csscompressor /
精简图片、Flash
对大图片、Flash,要在效果和大小以前作出平衡
ydoc
node 进程 集群