前端性能优化点,涉及的功能 1)网络层面。2)构建层面。3)服务端层面。4)浏览器渲染层面。 资源的合并与压缩,图片编解码原理和类型选择,浏览器渲染机制。 掌握前端性能优化的原理,这些优化点如何与业务相互结合,业务优化点有哪些可以优化的点。 了解当前大公司在性能优化上所做的实践,学会分析自身业务,选择合适的性能优化方式。
资源的合并与压缩
掌握知识要点:
理解减少http请求数量和减少请求资源大小两个优化要点;
掌握压缩与合并的原理;
掌握通过在线网站和fis3两种实现压缩与合并的方法。
CS架构:
BS架构:开发人员将前端代码发
布到远程服务器webserver以及远程CDN上,用户打开浏览器输入相应网址,这是浏览器向远程服务器发送请求,动态增量式的去加载静态资源,因次web前端去访问过程是一个动态增量地加载静态资源过程,通过http请求,通过浏览器发出到server并且返回,最终拿到资源,这个过程中我们拿到资源接口返回数据更快,那么对我们web前端来讲体验会更好。
浏览器的一个请求从发送到返回都经历了什么?
![](https://images2018.cnblogs.com/blog/1018462/201712/1018462-20171203112645038-1639110134.png)
请求过程中一些潜在的性能优化点:
- dns是否可以通过缓存减少dns查询时间?
- 网络请求的过程走最近的网络环境?
- 相同的静态资源是否可以缓存?
- 能否减少请求http请求大小?
- 减少http请求
- 服务端渲染
深入理解http请求的过程是前端性能优化的核心,基于对业务更深入的理解,及对业务技术栈更深入的理解。
资源的合并与压缩包含哪两种知识点?
减少http请求数量合并;减少请求资源的大小(压缩);
html压缩:
html代码压缩就是压缩这些在文本文件中有意义,但是在html中不显示的字符,包括空格,制表符,换行符等,还有一些其他有意义的字符,如html注释也可以被压缩。
如何进行html压缩:
1)使用在线网站进行压缩(现在很少使用这种方式进行,大多数公司使用webpack构建工具进行压缩);
2)nodejs提供了html-minifier工具;
3)后端模板引擎渲染压缩;
css压缩:
无效代码删除;css语义合并;
如何进行css压缩:
1)使用在线网站进行压缩;
2)使用html-minifier对html中的css进行压缩;
3)使用clean-css对css进行压缩;
js压缩与混乱:
无效字符的删除,剔除注释,代码语义的缩减和优化;代码保护层面 ;
如何进行js压缩和混乱:
1)使用在线网站进行压缩;
2)使用html-minifier对html中的js进行压缩;
3)使用uglifyjs2对js进行压缩;
文件合并存在的问题:
1)首屏渲染问题(React、Vue );2)缓存失效问题;
针对上面2个问题如何解决?
1)公共库合并;在真实的业务场景中,将公共库打包成一个文件,将业务代码(频繁改变)打包成一个文件,就算我们改动业务代码的时候,也不会影响到业务层代码的情况
2)不同页面的合并;针对经常单页应用,单页面应用在渲染的时候会请求当前页面对应的js,而不是把所有js都打成一个包,请求回来是不合理的。在真实的业务场景中,我们期望的是单页面中某一个页面被路由到的时候,才去加载那个页面的组件,请求那个页面的js。把不同页面的js分别打包,当前端路由路由到哪个页面的时候才去加载那个页面的组件(对应js文件)。这种方式在webpack中是可以实现,异步加载组件结合现在的框架。
3)见机行事,随机应变;
如何进行文件合并:
使用在线网站进行文件合并;使用nodejs实现文件合并;
进行文件合并有些情况下还有一个原因就是:受限于我们浏览器所支持一个域名的并发情况。比如说
浏览器可以并行加载100个js文件,其实它会发100个请求,是实际上浏览器本身因为受限它起的线程数量,所以浏览器针对每一个域名并发请求js的数量(静态资源数量)是有限的,比如。。100个js通过<script>标签引入的话,其实并不能对它同时发起请求。浏览器支持对同一个域名下并发请求数量是有限的,具体数据每个浏览器是不一样的。
web前端的核心概念和web前端性能优化的意义所在;
http请求的过程及其中潜在的性能优化点;
压缩与合并的理念和使用;
图片相关的优化
需要掌握:理解图片相关的优化的核心概念;结合大厂网站案例分析;掌握通过在线网站和fis3两种实现图片相关的一些优化。
png8/png24/png32之间的区别:
png8--256色+支持透明;png24——2的24方色+不支持透明;png32——2的24方色+ 支持透明;文件大小,色彩富丰程度。
每种图片格式都有自己的特点,针对不同的业务场景选择不同的图片格式很重要。
不同格式图片常用的业务场景(及特点):
1)jpg有损压缩,压缩率高,不支持透明;——大部分不需要透明的业务场景
2)png支持透明,浏览器兼容好;——大部分需要透明图片的业务场景
3)webp压缩程度更好,在ios webviews有兼容性问题(ios支持不是很好);——安卓全部
4)svg矢量图,代码内嵌,相对较小,图片样式相对简单的场景;——图片样式相对简单的业务场景
图片压缩:针对真是图片情况,舍弃一些相对无关紧要的色彩信息。
CSS雪碧图:把网站上用到的一些图片整合到一张单独的图片中
优点:减少你的网站的http请求数量;缺点:整合图片比较大时,一次加载比较慢。
Image inline: 在构建阶段将图片内嵌到html上,与html同时存在的情况,不是发送http请求去获得一张图片,而是以base64格式将它文件的信息都inline到,减少网站http请求的数量。
使用矢量图:使用SVG进行矢量图的绘制,使用iconfont解决icon问题。
在安卓下使用webp:Webp的优势体现在它具有更优的图像数据压缩算法,能带来更小的图片体积,而且拥有肉眼识别无差异的图像质量;同时具备了无损和有损的压缩模式、Alpha透明以及动画的特性,在JQED和png上的转化效果都非常优秀、稳定和统一。
图片压缩常用网站:https://tinypng.com
png压缩webp的两种方式:1)在线网站2)fis3压缩。
image-inline:需要根据具体业务场景来确实是否使用,会导致图片变大,整体资源所需要size变大,但会减少http请求,寻找合适的业务场景。小的icon本身只有1kb那么变大也就1.几kb,这样在size变化不大。但是减少一次http请求,更多减少10次http请求对于我们网络上传输损耗是优化是非常大的。
在业务场景中会有一个标准,小于4kb或者小于8kb的图片,都会使用构建工具inline进来。
css和js的加载与执行
最先拿到html从上到下解析,浏览器在解析的过程会发现它会使用其它外部资源,进一步请求外部资源,再对这些外部资源进行解析,从而进行页面最终的渲染,这是html页面加载渲染的过程。
css加载生成css树最终和DOM树整合成为RenderTree之后才会进行页面渲染,带有样式。
HTML渲染过程的一些特点:
1)顺序执行,并发加载;
从上倒下词法分析html标签情况进行加载,html中引入cssjs外部资源是并发加载的,这个并发度是受浏览器限制的。
2)是否阻塞;
css加载是否阻塞js的加载?css加载是否会阻塞js的执行?css加载是否会阻塞页面渲染?
3)依赖关系;
4)引入方式;
CSS阻塞(重要)
1)css head中阻塞页面的渲染;css如果在head中通过link的方式引入,会阻塞页面渲染。
2)css阻塞js的执行;
3)css不阻塞外部脚本的加载;
js阻塞
1)直接引入的js阻塞页面的渲染;
2)js不阻塞资源的加载;
3)js顺序执行,阻塞后续js逻辑的执行;
懒加载与预加载
预加载:
重绘与回流
css性能让javascript变慢?
频繁触发重绘与回流,会导致UI频繁渲染,最终导致js变慢。
css的核心会影响页面的样式展示,渲染流程频繁触发,重绘与回流机制频繁触发的话,实际上那么ui线程会比较频繁的进行页面相关的渲染。这个时候再进行渲染的时候,由于阻塞了JavaScript线程,所以JavaScript脚本代码没办法执行,那么css会让页面一些JavaScript代码执行变慢。
尝试优化css写法和一些性能,从而让我们页面ui线程渲染次数和渲染难度降低,从而加快渲染速度,性能提升。
回流
1)当render tree中的一部分(或全部)因为元素的规模尺寸,布局,隐藏等改变而需要重新构建。这就成为回流。
2)当页面布局和几何属性改变时就需要回流。
重绘
1)当render tree中的一些元素需要更新属性,而这些属性只是影响元素的外观,风格,而不会影响布局的,比如backgroud-color。则就叫重绘。
回流必将引起重绘,而重绘不一定会引起回流。
触发页面重布局的属性--触发重绘
![](https://images2018.cnblogs.com/blog/1018462/201712/1018462-20171203113438163-1404794159.png)
只触发重绘的属性,不会触发回流
![](https://images2018.cnblogs.com/blog/1018462/201712/1018462-20171203113520788-1149437083.png)
浏览器存储
多种浏览器存储方式并存,如何选择?
Cookie
![](https://images2018.cnblogs.com/blog/1018462/201712/1018462-20171203113608851-1604747351.png)
因为HTTP请求是无状态,所以需要cookie去维持客户端状态。
cookie的生成方式:
1)http response header 中的set-cookie。
2)js中可以通过document.cookie可以通过读写cookie
由服务端生成的,由客户端存储和维护的。每次请求客户端都携带cookie这个标示到服务端的。
cookie作用:
1)用于浏览器端和服务器的交互。
2)客户端自身数据的存储。
过期时间expire。
cookie存储的限制:
1)作为浏览器存储,大小4kb左右。
2)需要设置过期时间expire。
httponly:当前这个cookie不支持js读写的,如果这个cookie支持读写,可能会有安全隐患。
![](https://images2018.cnblogs.com/blog/1018462/201712/1018462-20171203113710913-682949745.png)
cookie中在相关域名(Domain)下面-cdn的流量损耗。域名维度下面的概念,只要这个域名下所有请求都会携带cookie,并不是这个域名下所有请求都需要用cookie。在http-request-header中携带cookie。
优化方案:cdn的域名(不携带cookie)和主站的域名要分开。cdn域名下存放css、js请求不需要携带cookie的,减少流量的损耗。
LocalStorage
1)html5设计出来专门用于浏览器存储的
2)大小为5m左右
3)尽在客户端使用,不和服务端进行通信
4)接口封装较好
5)浏览器本地缓存方案
SessionStorage(会话维度)
1)回话级别的浏览器存储。——浏览器的type就是一个回话,chrome标签关闭后,存储的数据清空。
2)大小为5m左右。
3)仅在客户端使用,不和服务端进行通信。
4)接口封装较好。
5)对于表单信息的维护。
对SessionStorage方面的优化:
(1)对于想注册相关页面,用户会填写相关信息,当刷新页面后信息会丢失,可以用sessionStorage实时存储用户输入的信息即使用户刷新页面数据还在,只有在用户关闭标签之后信息才会消失,提升用户交互体验。
(2)另外一种情况就是用户填写信息是以分页形式展示,点击下一页填写信息,也可以使用这个方式去存储相关信息。sessionStorage去维护一个表单在进行多页切换的时候数据传递可以存储。
IndexedDB(浏览器端数据库)
1)IndexedDB是一种低级api,用于客户端存储大量结构化数据。该api使用索引来实现对该数据的高性能搜索。虽然web Storage对于存储较少量的数据很有用,但是对于存储大量的结构化数据来说,中方方式不太有用。IndexedDB提供了一个解决方案。
2)为应用创建离线版本。
相关性能优化的案例:
1)localStorage作为缓存优化的应用场景:百度是将BMap这个库js全都存到了localStorage中,包括了css文件,这些文件请求一次就不会改变了。如果仅仅通过服务端缓存机制设置过期时间,终究会有资源浪费。但是存到localstorage中设置不会过期的话,那么就非常方便。
2)手淘将很多小icon存到localstorage中,或商铺相关信息等。
缓存
httpheader(Response、Request)
Cache-Control
1)max-age:指定缓存最大有效时间
![](https://images2018.cnblogs.com/blog/1018462/201712/1018462-20171203113932601-525449639.png)
从请求这个资源到max-age这段时间内,浏览器再次请求这个资源的时候不会向服务端发起请求的。max-age会让浏览器在请求资源的时候不向服务端发起请求。服务端会告诉浏览器在这段时间内,这个资源是有效的不会过期的,浏览器会从缓存中直接读取。
2)s-maxage(返回304)
![](https://images2018.cnblogs.com/blog/1018462/201712/1018462-20171203114051413-689920066.png)
指定一个缓存的有效时间,只能设置对于public设备(cdn)的缓存,cdn公共缓存区域。
优先级高于max-age,只能去public缓存区域读取相关信息,不是从浏览器拿资源而是去cdn上读取,返回304状态及资源。s-maxage的意义是对于cdn公共的区域在s-maxage设置的过期时间之内缓存是不会过期的,超过这个时间才回去原服务器(cdn)更新资源。
3)private:私人缓存设备,当前用户自己访问的缓存,用户在浏览器缓存的信息,只有当前用户使用。
4)public:
比如cdn缓存设备,能被很多用户访问读取信息的。
5)no-cache:
![](https://images2018.cnblogs.com/blog/1018462/201712/1018462-20171203114123272-536291161.png)
搭配max-age=0使用,当前文件都会向浏览器发起请求询问当前文件是否在缓存策略中过期,不会不发请求直接向浏览器缓存读。先发请求到服务端根据返回信息判断浏览器端缓存是否过期。
6)no-store:
不适用缓存策略。
Expires
1)缓存过期时间,用来指定资源到期的时间,是服务器端的具体的时间点。
2)告诉浏览器在过期时间前浏览器可以直接从浏览器存取数据,而无需再次请求。
![](https://images2018.cnblogs.com/blog/1018462/201712/1018462-20171203114203569-1849982742.png)
max-age优先级高于expires的,强的浏览器端缓存,属性生效不会触发向服务端发起请求的过程,直接在浏览器中读取相应缓存数据,在浏览器层面控制。那么服务端某资源发生变化,浏览器端是无法感知的,因为浏览器直接从浏览器端缓存中读取资源。
Last-Modified/IF-Modified-Since
1)基于客户端和服务端协商的缓存机制。
2)last-modified---response header。
3)if-modified-since---request header。
4)需要与cache-control共同使用。
当从客户端发起请求到服务端,服务端会在response-header中带Last-Modified,客户端会将资源存到缓存区域当中,Last-Modified作为一个标识。那么每次客户端在请求这个资源时,会在Request-Headers中带if-modified-since这个字段,告诉服务端这个时间点。那么客户端在这个时间点过期之后,如果这个资源没有更新返回304状态以及Last-Modified状况;如果有更新,则返回最新Last-Modified的时间点及200状态码。
但last-modified有什么缺点?
1.某些服务器不能获取精确的修改时间
2.文件修改时间改了,但文件内容却没有变。
Etag/If-None-Match
1)文件内容的hash值
2)etag-response header
3)if-none-match-request header
4)需要与cache-control共同使用
![](https://images2018.cnblogs.com/blog/1018462/201712/1018462-20171203114235569-1209190162.png)
当文件内容改变,这个哈希值会改变,更加精确。
![](https://images2018.cnblogs.com/blog/1018462/201712/1018462-20171203114318601-911617008.png)