前端极限性能优化合集
性能优化是老生常谈了,从雅虎的N条军规,前端各种优化准则,到2010年Google IO上Steven提出的高性能建站指南,都在告诉开发者,一个站点的性能非常重要,如何在有限的带宽条件下,达到极限的访问性能,如何让访问者,无论是从响应速度,视觉感官,操作流畅度都达到最佳体验,是目前Web技术上的一个至关重要的挑战.
相较于前端,后端的性能优化手段非常多。这里前端的放在后面讨论,先从Back-End开始.
1.使用Nginx做转发
Nginx作为一个开源的高性能负载均衡的HTTP和反向代理服务器, 是开源界的业界标杆之作, 一般来说,通过后台程序启动的服务, 通过Nginx作转发可以轻松的做到:
·负载均衡
·限制对于资源路径的访问
·对静态资源自动开启Gzip压缩
·配合分布式服务器架构
2.Redis, Varnish做缓存
使用缓存中间层可以极大程度上的减少对于数据库的重复读写操作次数,减小服务器的压力。极限配置过的Varnish缓存层面可以自动检测到已经修改的文件,没有改变的文件则告诉客户端使用缓存,而改变过的文件会自动返回新的文件,这种技术详情请见Github IO站点,非常适合静态资源
·减少对于数据库层面的读写操作
·缓存静态数据,配置,资源
·并发量大时,减小服务器压力
3.字段加密,字段压缩
从后端的开发角度来说,直接读写数据库之后,原样返回数据库对应字段作为响应数据是一种极其懒惰愚蠢的行为,这样的做法不单是告诉攻击者数据库的字段就是这样的,更是让有经验的人容易的揣测到数据库的表结构。所以字段的加密,字段的压缩,就变得极其的重要.
字段的加密,压缩意思是指,从数据库中拿出的对应数据自动转化成非逻辑形态数据
id: 201293 a : 201293
name: "Sam" -> z : 88
score: 88 n : "U2Ft"
配合前端的filter的层面,将数据转化成视图对应所需要的平行话格式
4.静态资源分离,发布自动化
运维当然是必不可少的,将静态资源自动抽离,通过Python,或者Shell脚本自动化将静态资源分布到CDN服务器,替换对应的文本等操作, 内存监控等一系列的task,当然,中小公司很少有这么专业的干活。
1.jsCSS极简化,减少文件大小
从带宽能力的角度上来说,一个站点的访问速度,最直观的其实是从文件的大小入手,而不是执行效率。当并发量变得极其庞大时(Google首页,百度首页),减少css和js的文件大小就变得相当的重要,假设每秒一个访问者每次访问该站点可以少加载2KB大小的资源的加载, 那么100个访问者会怎么样?1000个访问者,1000万个访问者呢?这就是为什么 腾讯QQ空间项目组,减少CSS JS文件大小10KB就有丰厚的年终奖的原因了.
至于减少字节的各种奇技淫巧我就不展示那么详细了,举个几个例子
Css
// 减少1字节
font-weight: bold -> font-weight:700
// 组合写法// 减少n字节
margin-top:**
margin-left: **
margin-right: **
margin-bottom: **
-> margin : ** ** ** **;
var str = "abcd"
if(str.indexOf("d") === -1)
...
// 使用取反运算// 减少3字节if(!~str.indexOf("d"))
...
2.真正意义上将样式,配置逻辑embed到页面中,从而减少http请求
CSS放在头部加载,JS放在尾部加载这种调调听的太多了,人云亦云,123456789,跟着一起喊,实际情况并不是这样,现代浏览器越来越快,多线程并行加载CSS的能力得到了巨幅提升,很多人没有真正去理解Steven在2010年Google IO大会上论述的:“减少http请求”
通过观察Google的首页我们发现,居然没有CSS请求?查看页面源码时发现,Google将样式embed到了页面中一起加载过来 。
这样的做法有4个好处
·浏览器预先加载CSS不会执行并行加载CSS文件,减少http请求
·随页面享受Gzip压缩,并且随时可以解决缓存问题
· embed在页面中,浏览器预解析,不会造成并行下载css同时解析html时出现的回流或者重绘等问题
·让观察者无法轻松调试,定位,甚至修改。
3.图片的压缩,静态资源CDN化
主要是将图片,CSS,JS等资源,CDN化,从而很大程度上减少主服务器的压力.图片压缩,WebP格式可以说是Web图片格式的未来趋势,压缩算法真心屌,不过只有Chrome和Opera支持的最好, 其他浏览器都不太Care,希望Chrome赶紧一统江湖吧.
一般的JPG其实只需要70%的质量就差不多了.但是,它仍然不是最理想的状态,图片的除了压缩质量以外,还需要移除掉图片的其他信息,压缩最好是在后端完成,而不是用前端的Canvas(需要考虑Base64码比原图片要大的问题)
4.视图层使用js模版,或者完整的View框架(React),以Lazyload的形式分块加载
看看淘宝和天猫首页是怎么做的就知道了,将视图模版化,访问者滚动时才加载对应的数据,从而很大程度上减少一次性数据的传输量.
5. CSS JS选择器ID化
这一点可能很多人不相信,而一段时间的总结和实践后我发现,ID选择器是最快的,主业务逻辑的元素绑定ID是一种非常不错的做法,而给ID写样式,也不是一种糟糕的实践,而可以一定程度上加快解析,渲染的速度。详情可以参见Google首页的样式,非常多的ID写法.
YouTube作为全球最大的视频网站,每天都承载了数亿级别的PV,自然YouTube的前端必须要做到极致,为了加快渲染速度,除了Embed CSS和JS之外,CSS大部分使用了ID的写法,更多细节请科学上网:
6. PC站点和移动端完全分开,拒绝响应式
2011年前后掀起的响应式站点浪潮,其中最著名的CSS框架相信大家绝对不会陌生,BootStrap,也是Github上少有的可以突破10万Star的项目, 一个站点,多屏幕,多设备适配,通过编写不同的Media Query CSS就可以做到,但是从性能角度来讲确是一个非常糟糕的实践.所以基本上没有大公司搞响应式(国内)
其缺点如下:
·多余的HTML结构和CSS样式,在media query下不同屏幕要对css进行重写或者增强
·同样的图片可能需要两套(小屏幕,大屏幕)
· Sprite IMG无法得到充分的利用,Background Size,Position微小像素差等问题
·其实根本没有人会闲的蛋疼的去不停的缩放屏幕
·两套事件绑定(Click,Tap) 偷懒的话只用Click事件,导致点击触控方面体验极差
·资源文件体积过大,不利于优化,手机加载解析速度慢
7.活用LocalStorage,存储用户状态,组件状态,而非JS或者模板
之前看到有文章说“利用LocalStorage存储JS”, 当然这种做法是错误的,极其不靠谱,问题就在于把JS存在LocalStorage中很容易遭到XSS攻击,另外,存储模板也不靠谱,模板最好是直接输出在页面后直接进行编译,不要存储在LocalStorage中,会涉及到模板缓存,占用空间, 暴露视图逻辑等问题.同时,存储时最好进行加密(关键字段)
经过长时间的实践,LocalStorage最适合存储用户状态, 组件状态(和业务逻辑,数据逻辑无半毛钱关系的状态),等不涉及到业务数据存储的字段 比如:
·用户的搜索记录
·用户的名称,ID,上一次访问的URL地址
·组件的使用记录(状态)
·用户的UA
·后台输出的固定数据,需要在请求时带回去的字段
8.给视图根元素定义固定的Height和Width
一直以来,重绘和回流都是前端很讨厌的问题,很多网站,加载之后,布局样式会出现“抖” 一下的情况,甚至整个页面“闪一下“,”跳一下” ? 其实都是出现了严重的重绘,为了防止出现这种情况,我们给每一个可以预测板式的元素都定义固定的高度和宽度,保证内部的元素在懒加载(LazyLoad)或者直接渲染时,不会造成视图根元素的抖动,从而间接的影响到周围元素的排版,详情你可以参考一下天猫首页样式
9. DNS网络解析加速,并且利用好站长工具
此优化属于网络层面,当然也是值得一提的,具体这里不阐述,提一下.
利用好站长工具,这里不是指提高访问量或者SEO。