一、概念
1.优化地方:首屏时间,资源加载,交互响应,渲染,滚动,图片,动画
2.页面速度因素:网络宽带速度 设备性能(CPU,GPU,浏览器) 页面本身(js,css等)
3.法则:减少请求,合并,压缩,样式,css雪碧图,外联内联,DNS,图片压缩,渲染优化等
4.RTT:(Round-Trip Time)往返时间 简单来说就是发送方从发送数据开始,到收到来自接受方的确认信息所经历的时间。
5.14KB原则: 控制页面资源包在14KB内来减弱慢启动的影响
6.缓存:
协议缓存:Cache-Control(或Expires) Last-Modified(或Etag)
离线缓存:Cache Manifest
本地存储:localStorage sessionStorage
indexDB
7.requestAnimationFrame计算FPS(每秒钟画面更新次数) 1000ms/60=16.67
8.网络耗时的测定:window.performance
9.GPU渲染:transform,opacity,filter,video
使用GPU可以优化动画效果 GPU渲染会达到60fps 使用对GPU友好的css属性
触发硬件加速的css(浏览器通过某些样式创建了一个独立图层,图层中的动画由GPU进行预处理并且触发了硬件加速)
二、优化场景
方法:减少http请求,压缩,懒加载,css Sprite,异步加载,cdn,缩小cookie,避免重定向
压缩图片,脚本执行优化,touch事件优化,减少dom节点,canvas, 动画优化,GPU加速,缓存,首屏,无阻塞,离线包
2.1 图片
图片格式选择
图片压缩工具: gifsicle:创建和优化GIF图片 jpegtran:优化jpeg图片 optipng:无损png优化 pngquant :有损png优化
依靠css3绘制图片:体积小,减少请求,矢量
使用iconfont代替图片:加载性能好,支持css样式,兼容性好,矢量 ,缺点:只支持单色图标
Data URL弊端:在做加载优化时,需要综合考虑是否采用
Base64编码的数据体积通常是原数据的体积的4/3
消耗更多CPU和内存资源
为了使其可缓存,写在CSS中导致CSS文件大了
适用于图片小,页面上引用图片总数不多的场景
2.2 加载/滚动
加载优化
预加载:显性加载 隐性加载
按需加载:懒加载,响应式加载(使用srcset+sizes属性与w标识符)
2.3 ajax
数据埋点,统计等场景,不用ajax,用img 设置src
优点:不存在跨域;并行加载,不影响页面加载;更简单
2.4 js和css
1.localStorage/indexDB:Localstorage不支持大文件,频繁读写,会溢出;indexDB类似数据库
2.webwoker:
运行在后台、独立于其他脚本、不会影响页面的性能
除了DOM操作之外、理论上任何JS脚本任务都可放入worker中执行
用户体验上来看、提升了性能
3.timeline工具
4.渲染优化
- 避免在document上直接进行频繁的DOM操作
- 使用classname代替内联修改样式
- 缓存Layout属性值
- 设置元素的position为absolute或fixed
- 读写分离,批量操作
- 不要在css里面写expression
- 不要在16ms内发生多次渲染行为
5.滚动渲染:重绘是一个阻塞操作,滚动时减少绘制
6.策略:
- requestAnimationFrame
- 绝对定位
- 开启GPU加速: -webkit-transform :translateZ(0)
- Canvas
- 禁止图像缩放(使用实际大小的图片非常重要)
- 根据实际页面情况慎用耗性能的CSS属性
7.构建工具支持:文件体积的减小
Webpack: Tree-shaking –删除无用代码
Webpack: CommonsChunk --提取公共代码
三、首屏优化
- 资源内联
- 压缩直出内容:直出数据,不直出dom,dom通过模板数据生成
- 首屏数据预拉取:加载js文件,发送请求拉取数据
- 非首屏预拉取首屏数据:话题详情中点击,预先取首屏的数据
- 静态资源存储到localStorage:资源包减小,流量节省
- 网络环境差异化加载资源:webview提供接口,2G网络加载低质量图片,Wi-Fi环境中预加载资源
- 数据复用:个人中心(用户信息)
if (/MicroMessenger/ig.test(navigator.userAgent)){ // 微信环境加载js api resourcesToLoad.push('http://res.wx.qq.com/open/js/jweixin-1.0.0.js'); } wx.getNetworkType({ success: function (res) { var networkType = res.networkType; // 返回网络类型2g,3g,4g,wifi if ( networkType == 'wifi' ) { //如果是wifi环境,预加载所有的图片文件 //预加载的资源代码 var resouresToPreLoad = [xxxxxx, xxxxxxxx]; //此处省略一堆资源代码 for (var i = resouresToPreLoad.length - 1; i >= 0; i--) { new Image().src = resouresToPreLoad[i]; } } } });
四、前端优化是双刃剑
- 按需加载提升速度,但可能导致大量重绘
- Touch响应快,但很多场景不适合
- GPU加速效率高,但内存开销大等等
- Loading会让整体体验流畅,但容易造成用户流失
- 图片压缩让带宽成本降低,但可能会导致视觉效果变差