# 性能优化举措

一、思路

  1. 根据浏览器请求、渲染资源的逻辑来阐述。
  2. 根据用户的感知角度来阐述
  3. 根据我们目前最常见的开发 部署的模式来阐述
  4. 业界的性能优化规则:

ps : 浏览器加载页面的流程,请见:

二、网络层面

是否需要 距离 速度 总量 工具

实际上也有:TCP握手连接、HTTP请求报文、HTTP回复报文(理解资源加载的性能约束,包括:TCP连接限制、TCP慢启动)
后续再展开介绍。

2.1 不用传输

2.1.1 缓存
    dns缓存
    cdn缓存
    服务器缓存
        nginx缓存

    客户端缓存

<font color="#d35400">CDN缓存 why: </font>

CDN(Content Distribute Network,内存分发网络)的本质上仍然是一个缓存,而且将数据缓存在离用户最近的地方,是用户以最快速度获取数据,即所谓网络访问第一跳。CDN一般缓存的是静态资源,如图片,文件,CSS,Script脚本,静态网页等,但是这些文件访问频率很高,将其缓存在CDN可极大改善网页的打开速度

<font color="#d35400">nginx缓存 why: </font>

代理服务器也可以通过配置缓存功能加速Web请求,当用户第一次访问静态内容的时候,静态内容就被缓存在反向代理服务器上,这样当其他用户访问该静态内容的时候,就可以直接从反向代理服务器返回,加速Web请求响应速度,减轻服务器负载

<font color="#d35400">客户端缓存:why: </font>

CSS,JavaScript,Logo,图标等这些静态资源文件更新的频率都比较低,而这些文件又几乎是每次HTTP请求都需要的,如果将这些文件缓存在浏览器中,可以极好地改善性能。

<font color="#27ae60">客户端缓存:how to do</font>

设置HTTP头中Cache-Control和Expires属性,可设定浏览器缓存,缓存时间可以是数天甚至是几个月。有时候,静态资源文件变化需要及时应用到客户端浏览器,这种情况可以通过改变文件名实现,比如一般会在JavaScript后面加上一个版本号,使浏览器刷新修改的文件。

2.1.2 减少传输次数(有点偏内容层面了)
        1. 合并传输
            api 合并传输??
                怎么合并没懂
            css 合并 ;js合并,图片合并 css sprite等等。
             iconfont
        2. 按需加载(即暂且不用传输的先不传送)
            单页应用下的按照路由的需要加载 
            不再当前页的 不传送
        3. 使用http2.0  3.0  --可一个tcp,多个http传输

<font color="#d35400">why: </font>

HTTP协议是无状态的应用层协议,意味着每次HTTP请求都需要建立通信链路,进行数据传输,而在服务器端,每个HTTP都需要启动独立的线程去处理,这些通信和服务的开销都很昂贵,减少HTTP请求的数目可有效提高访问性能。

2.2 传输内容少

    见下方内容的部分

2.3 传输速度快

1. 带宽大
2. 服务器相关的性能好,相关反应速度也就快了。
3. ★★★prefetch(利用空闲时间),可用webpack 的 PreLoadWebpackPlugin插件

2.4 减少传输距离

使用cdn能帮你选择最优的服务器下载响应你的资源

2.5 工具能不能优化

http传输协议使用 3.0 2.0 更高的版本



总结如下:

1. 使用cdn 
2. 开启相关缓存
3. 增加带宽
4. http版本升级
5. refetch(利用空闲时间)






三、资源(内容)层面

3.1 有内容,不出错

即避免202
避免重定向

3.2 内容少

3.2.1 分批传输
        1. 大的内容,分拆一下。
        2 使用流,边看便下载
3.2.2 去除多余的大小
      1. 设计师设计的时候就不大面积使用背景图,
       2. api 请求的时候,去除多余的大小,不必要的返回
       3. 去除多余的依赖: 控件中的依赖 干掉;webpack 中的sourcemap
       2. 去除多余的代码和注释 分号 空格等等
       5. 技术选型恰当
       6. 首页,从单页面 改用多页。
       7. 资源按需加载。如hui控件的按需使用
       8. 其他: 代码压缩、
       9. 减少cookie大小: 
       10. 规范代码: 无用的东西,不需要的东西(css  js 图片等)删除掉。 
3.2.3 本身内容再少
    3.2.3.1 压缩一下
         1. 首页gzip
         2. 设计师自己压缩图片 视频资源
         3. 代码压缩: webpack 工具已经帮我们做好了
    3.2.3.2 内容再减少 
                1. 模块化,组件化,
                2.按需加载:
                     第三方库和工具的 按需加载
                    可用代码拆分(Code-splitting)只传送用户需要的代码。
                    滚动加载,部分加载 懒加载
                3. 业务梳理的时候,首屏设计好。避免大面积图片
                4. 使用更小的第三方库
                5. 使用新一代图片格式,清晰且体积小
                6. 初次使用模糊的 小图,后续再用高清
                 

<font color="#27ae60">减少cookie大小:how to do</font>

可以考虑静态资源使用独立域名访问,避免请求静态资源时发送Cookie,减少Cookie传输的次数。

3.3 内容的执行过程(页面得渲染过程)

避免重排 ,少重绘
    减少dom操作---缓存dom,虚拟dom
js css 执行不阻塞
    文件的位置的重要性。
        代码编写的逻辑性

3.4 减少IO操作

    1.减少全局变量;
    2.减少全局组件;
    3.减少dom操作---缓存dom,虚拟dom

3.5代码上的优化

css
    避免在HTML中书写style
    避免CSS表达式:CSS表达式的执行需跳出CSS树的渲染
    移除CSS空规则:CSS空规则增加了css文件的大小,影响CSS树的执行
    正确使用display:display会影响页面的渲染
    不滥用float:float在渲染时计算量比较大,尽量减少使用
    不滥用Web字体:Web字体需要下载、解析、重绘当前页面,尽量减少使用
    不声明过多的font-size:过多的font-size影响CSS树的效率
    值为0时不需要任何单位:为了浏览器的兼容性和性能,值为0时不要带单位
    标准化各种浏览器前缀
    避免让选择符看起来像正则表达式:高级选择符执行耗时长且不易读懂,避免使用
js
    减少重绘和回流
    变量的缓存
        缓存DOM选择与计算:每次DOM选择都要计算和缓存
        缓存.length的值:每次.length计算用一个变量保存值
    尽量使用事件代理:避免批量绑定事件
    尽量使用id选择器:id选择器选择元素是最快的
    touch事件优化:使用tap(touchstart和touchend)代替click(注意touch响应过快,易引发误操作)

四、 渲染层面

深入理解浏览器的render过程,详情请见()

4.1 渲染工具的优化

推荐用户使用chrome浏览器
GPU加速
        用某些HTML5标签和CSS3属性会触发GPU渲染: 
            HTML标签:video、canvas、webgl
            CSS属性:opacity、transform、transition
    减少DOM节点:DOM节点太多影响页面的渲染,尽量减少DOM节点
    设置viewport:HTML的viewport可加速页面的渲染

4.2 不阻塞

页面渲染 不频繁切换渲染引擎和js引擎。
    css 头 ,js尾
    css 种少正则 少表达式;能css处理的不js

4.3 优化高频事件: scroll、touchmove等事件可导致多次渲染

函数节流
函数防抖
使用requestAnimationFrame监听帧变化:使得在正确的时间进行渲染
增加响应变化的时间间隔:减少重绘次数

4.4 优化动画

尽量使用CSS3动画
合理使用requestAnimationFrame动画代替setTimeout
适当使用Canvas动画:5个元素以内使用CSS动画,5个元素以上使用Canvas动画,iOS8+可使用WebGL动画

避免滥用框架、库

4.5 避免重排 ,少重绘

避免不必要的DOM操作
避免使用document.write
减少drawImage
缓存dom,虚拟dom

五、用户层面:

  1. 预加载:preload(在主渲染前进行预加载) 和,可

首屏的渲染时间

根据2 -5 - 8原则,最好能让用户在2秒内看到整个页面,可操作页面。

举措:

首屏加载同时请求不操作4个 
按需加载
    懒加载
    滚动加载
    不使用spa 模式--或者把首页单独拿出来
延迟加载
    比较大的资源如 图片 延迟加载
增加loading  或者时间提示   或者好看的动画
其他性能优化的点 均使用

<font color="#2980d9">ps: 2-5-8原则</font>

用户在2秒内得到响应,会感觉页面的响应速度很快 Fast
用户在2~5秒间得到响应,会感觉页面的响应速度还行 Medium
用户在5~8秒间得到响应,会感觉页面的响应速度很慢,但还可以接受 Slow
用户在8秒后仍然无法得到响应,会感觉页面的响应速度垃圾死了(此时会有以下四种可能)
    难道是网速不好,发起第二次请求 => 刷新页面
    什么垃圾页面呀,怎么还不打开 => 离开页面,有可能转投竞争对手的网站
    垃圾程序猿,做的是什么页面啊 => 咒骂开发此页面的程序猿
    断网了 => 网线断了?Wi-Fi断了?信号不好?话费用完了?


六、基于webpack的性能优化:


  1. 遇到webpack打包性能问题,先去npm run build --report,然后根据分析结果来做相应的优化,谁占体积大就干谁<br/>
  2. webpack提供的externals可以配合外部资源CDN轻松大幅度减少打包体积,尤其对于echarts、jQuery、lodash这种库来说<br/>
  3. 代码拆分

JS 层面细细展开<br/>
只传送用户需要的代码。可用代码拆分(Code-splitting)。<br/>
优化压缩代码(ES5的Uglify,ES2015的babel-minify或者uglify-es)<br/>
高度压缩(用Brotli~q11,Zopfli或gzip)。Brotli的压缩比优于gzip。它可以帮CertSimple节省17%的压缩JS的字节大小,以及帮LinkedIn减少2%的加载时间。<br/>
移除无用的代码。用 Chrome DevTools代码覆盖率功能来查找未使用的JS代码。对于精简代码,可参阅tree-shaking, Closure Compiler的高端模式(advanced optimizations)和类似于 lodash-babel-plugin的微调库插件,或者像Moment.js这类库的Webpack的<br/>ContextReplacementPlugin。用babel-preset-env & browserlist来避免现代浏览器中已有的转译(transpiling)功能。高级开发人员可能会发现仔细分析Webpack打包(bundle)有助于他们识别和调整不必要的依赖关系。<br/>
缓存HTTP代码 来减少网络传输量。确定脚本最佳的缓存时间(例如:max-age)和提供验证令牌(Etag)来避免传送无变化的字节。用Service Worker缓存一方面可以让应用程序网络更加灵活,另一方面也可以让你能够快速访问像V8代码缓存这样的功能。长期缓存可以去了解下Webpack带哈希值文件名(filename hashing)。<br/>

## 七 比较影响性能的点

图片的性能优化

cssspite 
不在HTML中缩放图片
使用小体积可缓存的favicon
优化图片
    使用最新的图片格式,或者较好的图片格式png等
    图片压缩一下
base64的使用。
预加载
懒加载
避免图片空连接 或者错误的链接

缓存的使用

更新时间 2021.03.05

JavaScript的成本


katara1109
468 声望22 粉丝

天助自助者