1. 对于静态资源文件采用“强缓存”和“协商缓存”,目的:让页面第二次及以后加载更快
扩展:描述强缓存和协商缓存(请求头和响应头字段);
如何保证服务器资源更新后,客户端可以抛开本地缓存,从服务器获取最新的信息;
2. 在直接操作DOM的时候,要减少DOM的重排(或回流),目的:提高页面重新渲染的性能
+ 尽可能使用vue/react等框架,避免直接操作DOM
+ 读写分离 「扩展:浏览器的渲染队列机制」
+ 样式集中修改
+ 批量新增元素,基于文档碎片或者字符串拼接等方式,统一插入到页面中
+ 尽可能使用transform修改样式「开启了硬件加速,不会引发回流」
+ 要操作的元素尽可能处于单独的文档流(平面)中
+ ...
3. 减少HTTP请求的次数和大小,目的:加快页面第一次渲染的速度,减少页面白屏等待时间
原因:同源下允许并发的HTTP数量是有限的(大概:5~7个),如果HTTP请求数过多,剩下的需要排队等待加载,而且因为请求数量过多,也可能会导致网络通道堵塞!
+ CSS/JS资源进行合并压缩「基于webpack」
+ CSS SPRITE 雪碧图技术
+ 图片懒加载
+ 数据的懒加载(异步加载):开始只发送首屏的数据请求,当页面渲染完,再去发送其他屏幕的数据请求 && 分页或者下拉加载等操作...
+ 服务器端开启GZIP压缩,可以使传输的内容压缩40%~60%左右
+ ...
4. 骨架屏技术方案,目的:加快页面第一次渲染的速度
「服务器骨架屏」
首屏信息基于服务器渲染(服务器返回结构/样式/数据,前提是服务器抗压能力和处理速度强),其余屏幕信息还是交给客户端渲染!!
「客户端骨架屏」
最开始加载页面的时候,只是用一些框框占位而已(变相的loading效果)
5. 基于事件委托来优化事件绑定
原因:减少了堆栈内存的开辟,性能比一个个的做事件绑定提高40%以上;可以给动态绑定的元素做事件绑定;
6. DNS优化,目的:加快页面第一次渲染速度
原则上我们应该减少DNS解析次数「具体做法:所有资源放在同一个域名下(相同的服务器上),第一次解析完会有缓存,后续再去获取其他资源,直接从本地缓存记录中获取DNS解析信息即可」
但是实际开发中,我们会根据资源类型不同,把他们放在不同的服务器上(不同的域名下)「目的:服务器资源的合理利用,减轻服务器的压力」,这样就增加了DNS解析的次数...
在增加解析次数的基础上,我们可以基于 DNS Prefetch(DNS预解析) 来进行优化「原理:利用link标签的异步性,在DNS解析的同时,GUI还可以继续渲染...」
7. 关于页面中的动画处理原则:能用CSS3搞定的不用JS;即使使用JS实现动画,能用requestAnimationFrame实现的也不用定时器;如果JS都搞不定的动画,直接让产品换需求...
8. 关于CSS选择器的优化 目的:也可以加快页面第一次渲染
+ 减少嵌套的“前缀”
+ 减少复杂性
+ 语义化
9. 导入JS资源的优化 目的:也可以加快页面第一次渲染
+ 放在页面的最底部「避免阻碍GUI的渲染」
+ 或者设置async或者defer
10. 导入CSS资源的优化 目的:也可以加快页面第一次渲染
+ 优先使用内嵌式「可以减少HTTP请求」
+ 代码过多的情况下,使用外链式
+ 坚决不用导入式,因为它会阻碍GUI的渲染
11. 使用HTTP2.0 目的:也可以加快页面第一次渲染
HTTP2.0相对于HTTP1.1的优势
+ 传输的内容是基于二进制来构建的,这样更加健壮
+ 请求头/响应头信息的压缩{客户端和服务器端对头的信息各自缓存一份,每次发送请求,没必要再传递那么多头信息,减少HTTP传输内容大小}
+ 服务端主动推送「发送一次请求,服务器端不仅把这次请求的内容返回,而且还可以把与其相关的内容都返回」
+ 多路复用「HTTP1.1中,基于TCP三次握手开辟的网络通道,每一次只允许一个请求通过(其余请求排队等待,而且容易导致“线头阻塞”),而HTTP2.0中一个通道可以允许多个请求同时进行...」
12. 减少HTML的层级嵌套,而且使用语义化标签,以此来加快DOM TREE的生成
13. 减少页面中的冗余代码,提高代码的重复使用率「低耦合高内聚」:函数的封装 -> 函数式编程和命令式编程
14. 对不经常更新的数据做缓存,减少非必要的请求「localStorage、sessionStorage、vuex/redux」
15. 函数的防抖和节流
16. 避免使用iframe实现页面嵌套,基于vue-router或者react-router-dom实现前端路由
17. 尽可能是用flex布局,减少float的使用
18. 对于数据的实时通信,避免基于定时器的ajax轮询,采用更好的scoket.io通信机制
19. 合理使用闭包,对于不用的堆内存及时释放...以此优化内存空间
20. 少使用cookie,因为每次向服务器发送请求,浏览器都会把本地cookie传递给服务器(哪怕这个事情是没用的)
21. 避免死递归和死循环,因为他们都会阻碍JS线程的渲染
22. 避免内存泄漏
23. 用字体图标(或者矢量图)代替位图
24. vue中为了减少DOM-DIFF计算,需要对超长列表进行优化
25. 音视频数据一定要延迟加载,否则会让页面首次渲染变慢
26. 不要使用CSS表达式
27. JS中减少对eval的使用,对于with坚决不用
28. JS循环的性能:for/while -> Array.prototype.forEach -> for of -> for in(性能最差)
29. 减少使用table布局
30. 图片使用BASE64
正常图片渲染的步骤:获取图片资源 -> 编码 -> 渲染
如果使用BASE64:渲染
虽然让图片渲染更快,但是导致页面中的代码“超恶(e)”,不方便维护,所以合理应用BASE64
+ 后期在webpack中,我们直接会把小图都base64了
+ 对于一些不能延迟加载的大图(图片中的信息很重要),我们可以基于BASE64来处理
终极方案: 如果公司有钱,以上优化都可以不做,直接把资源部署到CDN上