前端性能优化
一、请求响应优化
- 减少DNS查找:每次主机名的解析都需要一次网络往返,从而增加了请求的延迟时间同时还会阻塞后续的请求。
- 重用TCP连接:尽可能的使用持久连接,以消除因TCP握手和慢启动导致的延迟。
- 减少HTTP重定向:HTTP冲定向需要额外的DNS查询、TCP握手等非常耗时,最佳的重定向次数为0。
- 压缩传输的资源:比如Gzip、图片压缩。
- 便用缓存:比如HTTP 缓存、CDN缓存、Service Worker 缓存。
- 使用 CDN(内容分发网络):把数据放在离用户地理位置更近的地方,可以明显减少每次TCP连接的网络延迟,增大吞吐量。
- 删除没有必要请求的资源。
- 在客户端缓存资源:缓存必要的应用资源,避免每次都重复请求相同的内容,例如多图片下载可以考虑使用缓存。
- 内容在传输前先压缩:传输数据之前应该先压缩应用资源,把要传输的字节减少到最小在压缩的时候确保对每种不同的资源采用最好的压缩手段。
- 消除不必要的请求开销:减少请求的HTTP首部数据(比如 HTTP COokie)
- 并行处理请求和响应:请求和响应的排队都会导致延迟,可以尝试并行的处理请求和响应(利用多个HTTP11连接实现并行下载,在可能的情况下使用HTTP管道计数)。12针对协议版本采取优化措施。升级到HTTP2.0。
- 根据需要采用服务端渲染方式。这种方式可以解决SPA应用首屏渲染慢的问题。
- 采用预渲染的方式快速加载静态页面。页面渲染的极致性能,比较适合静态页面。
1、DNS优化
- 减少DNS的请求次数
- 进行DNS预获取:DNS Prefetch
2、HTTP压缩传输的数据源
- 响应数据:使用Gzip压缩文本
- 请求数据:
请求体:HTTP协议中的Accept-Encoding/Content-Encoding机制。这套机制可以很好地用于文本类响应正文的压缩
请求头:HTTP/2 引入了头信息压缩机制(header compression)
3、强缓存和协商缓存
- 强缓存
- 协商缓存
4、CDN缓存
- 避免对静态资源的请求携带不必要的Cookie信息
- 考虑浏览器对同一域名下并发请求的限制。
二、渲染优化
- JavaScript处理:前端项目中经常会需要响应用户操作,通过JavaScript对数据集进行计算、操作DOM元素,并展示动画等视觉效果。当然对于动画的实现,除了 JavaScript,也可以考虑使用如CSSAnimations、Transitions等技术。
- 计算样式:在解析CSS文件后,浏览器需要根据各种选择器去匹配所要应用CSS规则的元素节点,然后计算出每个元素的最终样式。
- 页面布局:指的是浏览器在计算完成样式后,会对每个元素尺寸大小和屏幕位置进行计算。由于每个元素都可能会受到其他元素的影响,并且位于DOM树形结构中的子节点元素,总会受到父级元素修改的影响,所以页面布局的计算会经常发生。
- 绘制:在页面布局确定后,接下来便可以绘制元素的可视内容,包括颜色、边框、阴影及文本和图像。
- 合成:通常由于页面中的不同部分可能被绘制在多个图层上,所以在绘制完成后需要将多个图层按照正确的顺序在屏幕上合成,以便最终正确地渲染出来。
1、 优化DOM
HTML文件的尺寸应该尽可能的小,目的是为了让客户端尽可能早的接收到完整的 HTML。总结起来有三种方式可以优化HTML:
- 缩小文件的尺寸(Minify)
- 使用gzip压缩 Tiar (Compress)
- 使用缓存(HTTP Cache)。
2、 优化CSSOM
- 让这些非关键的 CSS 资源不阻塞渲染。
<!--阻塞渲染-->
<link href="style.css" rel="stylesheet">
<!-- 非阻塞的加载Css--->
<link href="print.css" rel="stylesheet" media="print">
<!-- 拆分媒体查询相关CSS 资源:可变阻塞加载 -->
<link href="other.css" rel="stylesheet" media="(min-width: 40em)">
<!-- 具有动态媒体查询,将在网页加载时计算 -->
<link href="portrait.css" rel="stylesheet" media="orientation:portrait">
- 将关键CSS直接内联到HTML文档内。
- 避免在CSS中使用@import
3、 优化 JavaScript的使用
- 异步加载JavaScript,避免同步请求;延迟解析JavaScript;避免运行时间长的JavaScript:使用differ延迟加载
- 使用CSS实现动画效果
- 恰当使用WebWorker
可将一些纯计算的工作迁移到WebWorker上处理,它为JavaScript的执行提供了多线程环境,主线程通过创建出Worker子线程,可以分担一部分自己的任务执行压力。在 Worker子线程上执行的任务不会干扰主线程,待其上的任务执行完成后,会把结果返回给主线程,这样的好处是让主线程可以更专注地处理UI交互,保证页面的使用体验流程。
- 函数防抖和节流
4、 计算样式优化
- 减少要计算样式的元素数量:使用类选择器代替标签选择器、避免使用通配符做选择器
- 降低选择器的复杂性
- 使用BEM规范:.block__element--modifier
5、 避免触发页面布局与重绘
- 避免样式频繁改动
- 使用类名对样式进行修改
- 缓存对敏感属性值的计算
- 使用requestAnimationFrame方法控制渲染帧
JS性能优化
目的
- 首屏时间
- 首次交互时间
- 首次有意义内容渲染时间
页面性能检测
- https://developers.googLe.com/speed/pagespeed/insights/
方法
- 只请求当前需要的资源:
- 异步加载
- 懒加载
- 按需加载:优化polyfill(针对低版本浏览器的转义)https://polyfill.io/v3/url-builder/
- 缩减资源体积:
- 打包压缩(webpack4已内置、gzip)
- 图片格式优化:(https://tinypng.com/)、根据屏幕动态适配图片分辨率、webp无损压缩
- 控制cookie大小(request header),同域名请求携会带所有cookie
- 时序优化:
- promise.all
- ssr (而且还方便seo)
- prerender prefetch preload
<!-- 让文件会立马解析DNS(DNS预解析) -->
<link rel="dns-prefetch" href=''>
<!-- 预加载 -->
<link rel="dns-preload" as="image" href=''>
<!-- 预链接 -->
<link rel="dns-preconnect" href=''>
- 合理利用缓存:
- cdn预热和刷新
通过刷新功能,您可以强制CDN节点回源并获取最新文件;通过预热功能您可以在业务高峰期预热热门资源,提高资源访问效率。