【前端优化】前端常见性能优化
前言:
web前端本质上是一种GUI软件(图形用户界面—采用图形方式显示的计算机操作用戶介面)
性能time=下载资源time+服务响应time(api+浏览器渲染time 网络静态资源占用了大概50%的时间 - http请求的过程是前端性能优化的核心 前端优化性能指标:首屏性能-首屏渲染时间要在 1s之内
优化点1:资源请求
浏览器的一个请求从发送到返回都经历了什么
http://www.zyy1217.com/2017/0...
简述:
浏览器根据请求的URL交给DNS域名解析,找到真实IP,向服务器发起请求; 服务器交给后台处理完成后返回数据,浏览器接收文件(HTML、JS、CSS、图象等) 浏览器对加载到的资源(HTML、JS、CSS等)进行语法解析,建立相应的内部数据结构(如HTML的DOM)载入解析到的资源文件,渲染页面,完成
请求图示
dns缓存
什么是Dns
将网址转化为计算机理解的IP地址
是否可以通过缓存减少dns查询时间?
dns缓存/浏览器缓存查询/本地host查询/服务来查询 DNS查找过程------20ms 通过缓存,来减少这种查找功能
cdn服务(内容分发网络)
网络请求的过程走最近的网络环境 解决网络拥堵---需要添加服务器--靠money解决
相同的静态资源缓存
前端:本地 — 添加Expire/Cache-Control头
后端:使用特殊的字符串---来标识某个请求资源版本
请求资源---浏览器tag和服务器tag一样---返回304---信息没有被修改--可以直接使用本地缓存
配置etag可以减轻服务器的压力
优化点2:减少http请求大小(压缩/合并)
服务端:Gzip压缩
Gzip--思想:先把文件放在服务器上进行压缩,浏览器会自动的解压缩
这些文本文件都应被压缩:
服务端渲染SSR
前端:合并压缩常见html/css/js/图片
html压缩
1.实例:
goole点击查看网页源代码,可以看到压缩后的HTML
2.规则
在HTML中不显示的字符,包括空格,制表符,换行符等,还有一些其他意义的字符,如HTML注释也可以被压缩
3.意义
大厂有意义:google的流量,占到整个互联网的40% 预计2016年全球网络流量将会达到1.3ZB(1ZB = 10^9TB) 那么google在2016年的流量就是1.3ZB * 40% 如果google每1MB请求减少一个字节 每年可以节省流量近500TB
4.实现
Webapack — html-webpack-plugin可进行HTML的压缩
css压缩
1.规则:
无效代码删除+css语义合并(相同样式代码)
2.实现:
Webpack css-loader
JS压缩
1.规则
无效字符的删除 剔除注释 代码语义的缩减和优化 var a = 1, var a=2, var a=3
2.意义
为了安全性代码保护
3.使用
Webpack — UglifyJSPlugin
图片压缩
实现:
降低色彩点数 + 肉眼不可见
常见图片格式和使用场景
Png8/png24/png32 png8 —— 256色 + 支持透明 png24 —— 2^24色 + 不支持透明 png32 —— 2^24色 + 支持透明 不同图片使用不同的业务场景 — 手淘 jpg有损压缩,压缩率高,不支持透明大部分不需要透明图片的业务场景 Png支持透明,浏览器兼容好, 大部分需要透明图片的业务场景 webp压缩程度更好,在ios webview有兼容性问题,安卓全部/safari no/更优的图像数据压缩算法 svg矢量图代码内嵌相对较小,图片样式相对简单的场, 图片样式相对简单的业务场景
图片优化方案
1.Css雪碧图— backgroudPosition/图片大小很大 丢包 fb/需求页面 2.Image inline base64 webpack module: { loaders: [ { test: /\.(png|jpg)$/, loader: 'url-loader?limit=8192&name=images/[hash:8].[name].[ext]' } ] } 3. 矢量图svg内嵌标签(dom渲染,无请求)/iconfont(svg/png) svg标签 内置属性方法 只能花颜色单一,曲线不复杂 https://developer.mozilla.org/zh-CN/docs/Web/SVG/Tutorial/Basic_Shapes 4.tinypng.com压缩图片网站
文件合并
意义:
文件与文件之间有插入的上行请求,增加了N-1个网络延迟
文件合并弊端:
首屏渲染问题 合并文件太大,造成慢 缓存失效问题 标记 md5戳 只要有一个变动 则失效 a,b,c三个js合并
合并规则:
公共库合并 业务代码不合并 公共库合并 不同页面的各自合并 异步加载组件,不同页面单独打包,监听路由变化,自动下载
实现
Webpack — require.ensure([], callback) http://www.cnblogs.com/rubylouvre/p/4981929.html Webpack — 指定entry就是一个打包的入口 entry:{ index:["./src/index.js","./src/main.js"] }
优化点3:浏览器渲染
浏览器拿到资源后怎么工作?
http://taligarsiel.com/Projec... how bowser work
概述:
拿到是一个html文件— 里面内嵌了很多css.js.静态资源链接 Html渲染特点:顺序执行、并发加载(同一域名加载限制) 并发加载: result: 10 in IE 8, 6 in Firefox 3+ and Chrome 5+
浏览器会解析三个东西:
(1) HTML/SVG/XHTML,解析这三种文件会产生一个 DOM Tree。
(2) CSS,解析 CSS 会产生 CSS 规则树。
(3) Javascript脚本,v8引擎,主要是通过 DOM API 和 CSSOM API 来操作 DOM Tree 和 CSS Rule Tree.
载入后马上执行,执行时会阻塞页面后续的内容(包括页面的渲染、其它资源的下载 — 视浏览器内核为定)
Dom解析:
最先请求 字节 字符 词法分析 dom树 自上而下 边下载边渲染 不断重绘回流 DOM 树的构建过程是一个深度遍历过程:当前节点的所有子节点都构建好后才会去构建当前节点的下一个兄弟节点 解析完一部分内容就显示一部分内容,解析、渲染、http请求并行
css解析
#nav li 去找所有的li,然后再去确定它的父元素是不是#nav
渲染过程
Render tree结构不等同于dom树
网页中有哪些节点、各个节点的CSS定义以及他们的从属关系
Layout计算出每个节点在屏幕中的位置
绘制 遍历render树,并使用UI后端层绘制每个节点
Dom/Css渲染优化点
重绘/回流
名词解释:
两者关系
回流必将引起重绘而重绘不一定会引起回流
优化:减少reflow/repaint
Css/js的位置 为什么这么重要,链接放在那里无所谓吗?
css阻塞
Css — head — 阻塞页面渲染(首屏)— 白屏,闪屏 Css — 阻塞js执行/不阻塞js加载 - 边下边渲染
原因:
浏览器线程 — GUI渲染线程与javascript线程互斥 javascript执行依赖dom和css 动态修改
结论:
css一般放在头部
Js阻塞
直接引入js阻塞页面渲染 script js不阻塞资源加载, — 顺序执行 阻塞后续js执行 按文档结构
Webkit Html-preload-scanner 预加载
阻塞渲染,不阻塞加载,js执行时,扔预先下载一些资源,这是一个负责查找和加载子资源的对象。它通过扫描节点中的 "src" , "link"等属性,找到外部连接资源后,通过CachedResourceLoader进行预加载
解决方法
defer — IE独有 IE并行下载js文件、整个DOM装载完毕执行、多个defer的<script>在执行时也会按照其出现的顺序
js一般放在页面最尾部
补充:浏览器内核常驻线程
Q:
1.多个js的加载顺序
顺序执行
加载后立即执行并阻塞渲染
2.cache-control的参数
缓存请求指令:
Cache-Control: max-age=<seconds> Cache-Control: max-stale[=<seconds>] Cache-Control: min-fresh=<seconds> Cache-control: no-cache Cache-control: no-store Cache-control: no-transform Cache-control: only-if-cached
缓存响应指令
Cache-control: must-revalidate Cache-control: no-cache Cache-control: no-store Cache-control: no-transform Cache-control: public Cache-control: private Cache-control: proxy-revalidate Cache-Control: max-age=<seconds> Cache-control: s-maxage=<seconds>
3.chrome独有 Html-preload-scanner 预加载
在WebKit中,预加载扫描器指的是一个副解析器,当HTML主解析器被一个同步的script标签阻塞时,预加载扫描器就会启动.然后,它会马上找出接下来即将需要获取的资源(比如样式表,脚本,图片等资源)的URL,然后尽可能早的发起网络请求,而不用等到主解析器恢复运行,从而提高了整体的加载时间