前端性能优化之静态资源优化

静态资源优化

图片格式 和 应用场景介绍

JPEG

联合图像装甲小组是一种针对彩色照片而广泛使用的有损压缩图形格式

  • 介绍:栅格图形。常用文件扩展名为.jpg,也有.jpeg.jpeJPEG在互联网上常被应用于存储和传输照片
  • 不合适:线条图形和文字、图标图形,因为它的压缩算法不太这些类型的图形;并且不支持透明度
  • 非常合适:颜色丰富的照片、彩色图、大焦点图、通栏bnner图‘(一般是放在导航下面的一张大图)构不规则的图形

PNG

便携式网络图形是一种无损压缩的位图图形格式,支持索引、灰度、RGB三种颜色方案以及Alpha通道等特性。

  • 介绍:栅格图形。PNG最初是作为替代GIF来设计的,能够显示256色,文件比JPEG 或者GIF大,但是PNG非常好的保留了图像质量。支持Alpha通道的半透明和透明特性。 最高支持24位彩色图像(PNG-24 )和8位灰度图像(PNG-8 )。
  • 不适合:由于是无损存储,彩色图像体积太大,所以不太适合。
  • 非常适合:纯色、透明、线条绘图,图标;边缘清晰、有大块相同颜色区域二颜色数较少但需要半透明。

GIF

图像互换格式是一种位图图形文件格式,以8位色(即256种颜色)重现真彩色的
图像,采用LZW压缩算法进行编码。

  • 栅格图形。支持256色;仅支持完全透明和完全不透明;如果需要比较通用的动 画,GIF是唯一选择。
  • 不适合:每个像素只有8比特,不适合存储彩色图片。
  • 非常合适:动画、图标

Webp

Webp是一种现代图像格式,可为图像提供无损压缩和有损压缩,这使得它非常灵 活。由Google在购买On2 Technologies后发展出来,以BSD授权条款发布。

  • 介绍:优秀算法能同时保证一定程序上的图像质量和比较小的体积;可以插入多帧,实现动画效果;可以设置透明度;采用8位压缩算法。无损的Webp比PNG小26%,有损的Webp比JPEG小25-34%,比GIF有更好的动画。
  • 不合适:最多处理256色,不适合于彩色图片。
  • 非常合适:适用于图形和半透明图像。

用工具进行图片压缩

压缩 png
  • node-pngquant-native
  • 跨平台,压缩比高,压缩 png24非常好
  • 说明文档:https://www.npmjs.com/package/node-pngquant-native
  • 安装:npm install -g node-pngquant-native

压缩jpg

  • jpegtran
  • 跨平台,有LinuxMacWindows得解决方案
  • 官网:http://jpegclub.org/jpegtran.exe
  • 安装方法:npm install -g jpegtran
  • 使用方法:jpegtran -copy none -optimize -outfile out.jpg in.jpg
压缩gif
  • Gifsicle:通过改变每帧比例,减少GIF文件大小,同时可以使用透明来达到更小得文件大小,是目前公认得解决方案
  • 安装:http://www.lcdf.org/gifsicle/
  • 使用方法:
    • 优化级别设置为不小于 2 , 1 得话 基本不压缩 gifsicle --optimize=3 -o out.gif in .gif
    • 将透明部分截去 gifsicle --optimize=3 -crop-transparency -o out.gif in .gif

图片尺寸随网络环境变化

  • 不同网络环境 wifi / 4G / 3G,加载不同尺寸和像素的图片,通过在图片 URL后缀加不同参数改变

响应式图片

  • JavaScript绑定事件检测窗口大小

  • CSS媒体查询

  • @media screen and (max-width:640px){
    	image{
    		width:640px
    	}
    }
    
  • img 标签属性

  • img
    //x 描述符:表示图像得设备像素比
    

逐步加载图像

  • 使用统一占位符

  • 使用LQIP

    • 低质量图像占位符
    • 安装 : npm i lqip
    • 源码: http://www.github.com/zouhir/lqip-loader
  • 使用SQIP

    • 基于svg得图像占位符
    • 安装:npm i sqip
    • 源码:https://github.com/axe312ger/sqip
  • Web Font代替图片

  • 使用Data URL代替图片

  • 采用Image Spriting(雪碧图)

图片服务器自动优化解密

  • 名词解释
    • 图片服务器自动化优化是可以在图片URL链接上增加不同特殊参数,服务端自动化生成
    • 不同格式、大小、质量得图片
  • 处理方式
    • 图片裁剪:按长边、短边、填充、拉伸等缩放
    • 图片格式转换:支持JPGGIFWebP等,支持不同得图片压缩率
    • 图片处理:添加图片水印、高斯模糊、重心处理、裁剪边框等
    • AI能力:鉴黄以及智能抠图、智能排版、智能配色、智能合成等AI功能

精简HTML代码

  • 减少html得嵌套
  • 减少dom节点数
  • 减少无语义代码【比如:
    清除浮动】
  • 删除https 或者http,如果url得协议头和当前得协议头是一致得,或者此URL在多个协议头都是可用得,可以考虑删除协议头
  • 删除多余得空格、换行符、缩进和不必要得注释
  • 省略冗余标签和属性
  • 使用相对路径得URL

文件放在合适位置

  • css样式文件链接尽量放在页面头部
    • css加载不会阻塞DOM tree解析,但是会阻塞DOM Tree渲染,也会阻塞后面js执行。任何body元素之前,可确保在文档部分中解析了所有css样式(内联和外联),从而减少浏览器必须重排文档得次数。如果放置页面底部,就要等待最后一个css文件下载完成,此时会出现“白屏”,影响用户体验
  • JS引用放在HTML底部
    • 防止JS的加载、解析、执行对阻塞页面后续元素的正常渲染

增强用户体验

  • 设置favicon.ico

    • 网站如果不设置favicon.ico,控制台会报错,另外页面加载过程中也没有图标loading过程,同时也不利于记忆网站品牌,建议统一添加
  • 增加首屏必要的cssjs

    • 页面如果需要等待所依赖的jscss加载完成才显示,则在渲染过程中页面会一致显示空白,影响用户体验,建议增加首屏必要的cssjs,比如页面框架背景图片或者loading图标,内敛在html页面中。这样做,首屏能快速显示出来,相对减少用户对页面加载等待过程。

提升css渲染性能

  • 谨慎使用expensive属性

    • 如:nth-child伪类;position:fixed定位
  • 尽量减少样式层级数

    • div ul li span i {color:blue}
  • 尽量避免使用占用过多cpu 和内存的属性

  • text-indent:-999px text-indent 属性规定文本块中首行文本的缩进。

  • 尽量避免使用耗电量大的属性

    • css3 3D transforms 、 css3 transitions Opacity
    • transforms 会开启硬件加速

    Tips:为什么CSS选择器是从右向左匹配的?

    CSS中更多的选择器是不会匹配的,所以在考虑性能问题时,需要考虑的是如何在选择器不匹配时提升效率。从右向左匹配就是为了达成这一目的的,通过这一策略能够使得CSS选择器在不匹配的时候效率更高。这样想来,在匹配时多耗费一些性能也能够想的通了。

合适使用css选择器

  • 尽量避免使用css表达式
    • 比如隔行变色
  • 尽量避免使用通配选择器
    • body > a {font-weight:blod}
  • 尽量避免类正则的属性选择器
    • *= |= ^= $=

提升css文件加载性能

  • 使用外链的css
  • 尽量避免使用 @import

精简css代码

  • 使用缩写语句
  • 删除不必要的 0
  • 删除不必要的单位
  • 删除过多分号
  • 删除空格和注释
  • 尽量减少样式表的大小

合理使用Web Fonts

  • 将字体部署到cdn
  • 将字体以base64性时保存在css中并通过localStorage进行缓存
  • Google字体库因为一些原因,应该使用国内托管服务

css动画优化

  • 尽量避免同时动画
  • 延迟动画初始化
  • 结合SVG

JS优化总体原则

  • 当需要时才优化
  • 考虑可维护性

提升js文件加载性能

  • 加载元素的顺序css文件放在里,js文件放在里或者之后

js变量和函数优化

  • 尽量使用id选择器,因为这样最快
  • 尽量避免使用eval
  • js函数尽可能保持简洁
  • 使用事件节流函数
  • 使用事件委托

JS动画优化

  • 避免添加大量JS动画
  • 尽量使用CSS3动画
  • 尽量使用Canvas动画
  • 合理使用requestAnimationFrame动画代替setTimeoutsetInterval
    • requestAnimationFrame可以在正确的时间进行渲染,setTimeout(callback)setInterval(callback)无法保证(callback)回调函数的执行时机
      • setTimeout相比,requestAnimationFrame最大的优势是**由系统来决定回调函数的执行时机。**具体一点讲,如果屏幕刷新率是60Hz,那么回调函数就每16.7ms被执行一次,如果刷新率是75Hz,那么这个时间间隔就变成了1000/75=13.3ms,换句话说就是,requestAnimationFrame的步伐跟着系统的刷新步伐走。它能保证回调函数在屏幕每一次的刷新间隔中只被执行一次,这样就不会引起丢帧现象,也不会导致动画出现卡顿的问题。

合理使用缓存

  • 合理缓存DOM对象
  • 缓存列表长度
  • 使用可缓存的Ajax

Cookie

  • 通常由浏览器存储,然后将Cookie与每个后续请求一起发送到同意服务器。收到HTTP请求时,服务器可以发送带有Cookieheader头。可以给Cookie设置有效时间
  • 应用于:
    • 会话管理:登录名,购物车商品,游戏得分或服务器应要记录的其他任何内容
    • 个性化:用户首选项,主题或其他设置
    • 跟踪:记录和分析用户行为,比如埋点,【谷歌分析】

sessionStorage

  • 创建一个本地存储的键 / 值对
  • 应用于:
    • 页面应用之间传值

IndexedDB

  • 索引数据库
  • 应用于:
    • 客户端存储大量结构化数据
    • 没有网络连接的情况下使用(比如Google Doc、石墨文档等在线文档)
    • 将冗余、很少修改、但经常访问得数据,以避免随时从服务器获取数据

LocalStorage

  • 本地存储
  • 应用于:
    • 缓存静态内容js / CSS(比如百度M站首页)
    • 缓存不常变更得API接口数据
    • 储存地理位置信息
    • 浏览在页面得具体位置

JS模块化加载方案和选型

  • CommonJS

    • 旨在Web浏览器之外为JavaScript建立模块生态系统
    • Node.js模块化方案受CommonJS,同步加载得方式
  • AMD(Asynchronous Module Definition)(异步模块定义规范)

    • 主要用于浏览器上
    • RequireJS 模块化加载器:基于 AMD API实现
  • CMD (Common Module Definition)(通用模块定义)规范

    • SeaJS模块加载器:遵循 CMD API编写
  • ES6 import

CommonJS
//CommonJS
//引入依赖
var store = require('store')
// exports
exports = function(){
	return store.get('customers')
}
NodeJS module
//引入依赖
var store = require('store')
function customerStore(){
	return store.get('customers')
}

// exports
modules.exports = customerStore
RequireJS AMD

SeaJS CMD
//方式一
define(function(require,exports,module){
	//模块代码
})
//方式二
define('module',['module1','module2'],function(require,exports,module){
	//模块代码
})
ES6 import
// square.js
export function square(x){
	return x*x
}

//main.js
import { square } from 'square'
console.log(square(10))	//100

减少浏览器的回流和重绘

CSS

  • 避免过多样式嵌套
  • 避免使用CSS 表达式
  • 使用 绝对定位,可以让动画元素脱离文档流
  • 避免使用table布局
  • 尽量不使用float布局
  • 图片最好设置好 widthheight
  • 尽量简化浏览器不必要的任务,减少页面重新布局
  • 使用Viewport设置屏幕缩放级别
  • 避免频繁设置样式,最好把新的style属性设置完成后,进行一次性更改
  • 避免使用引起 回流 / 重绘的属性,最好把相应变量缓存起来

JS

  • 最小化回流和重排
    • 为了减少回流发生次数,避免频繁或操作DOM,可以合并多次对DOM修改,然后一次性批量处理
  • 控制绘制过程和绘制区域
    • 绘制过程开销比较大的属性设置应该尽量避免减少使用
    • 减少绘制区域范围

操作:在浏览器控制台 x 边上的 三个点点击 ==> Main tool ==> Rendering ==> 勾选 Paint flashing ==> Performance

控制DOM大小

  • 页面交互卡顿和流畅度很大一部分原因就是页面有大量DOM元素。想象一下,从1w节点的DOM树上,使用querySelectorAllgetELementByTagName方法查找某一个节点,是非常耗时的,另外元素绑定事件,事件冒泡和事件捕获的执行也会相对耗时
  • 通常控制DOM大小的技巧包括
    • 合理的业务逻辑
    • 延迟加载即将呈现的内容,及暂时不需要展示的dom节点就隐藏等需要的时候在展示

简化DOM操作

  • DOM节点的操作统一处理后,再统一插入到DOM Tree
  • 可以使用fragment,尽量不在页面DOM Tree里直接操作
  • ReactVue 虚拟DOM技术,通过diff算法简化和减少DOM操作

静态文件打包方案

  • 公共组件拆分
  • 压缩:js / css / 图片
  • 合并 : JS / CSS文件合并,CSS Sprite
  • Combo:JS / CSS 文件 Combo http://cdn.com/??a.js,b.js内容

静态文件版本号更新策略

  • 缓存更新

    • cdnng后台刷新文件路径,更新文件header
  • 文件name-v100.js

    • 大功能迭代每次新增一个大版本,比如由v1v2
    • 小功能迭代新增加0.0.1或者0.1.0,比如从v1.0.0v1.0.1
    • 年末ng统一配置所有版本302至最新版
  • 时间戳。文件 name.js

    • 以每次上线时间点做差异
  • 文件hash.文件 name.js

    • 以文件内容 hash值 做 key
    • 每次上线,文件路径不一致

你可能感兴趣的:(前端)