New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

阿里无线前端性能优化指南 (Pt.1 加载期优化) #1

Open
lvscar opened this Issue Jul 15, 2015 · 38 comments

Comments

Projects
None yet
@lvscar
Contributor

lvscar commented Jul 15, 2015

阿里无线前端性能优化指南 (Pt.1 加载优化)

前言

阿里无线前端团队在过去一年对所负责业务进行了全面的性能优化。以下是我们根据实际经验总结的优化指南,希望对大家有所帮助。

第一部分仅包括数据加载期优化。

图片控制

对于网页特别是电商类页面来说,图片通常会占据了大量的视觉空间,是页面中最为重要的展现内容,并且占据网页传输字节的大部分。因此,对图片的优化是我们性能优化的重点.

启用WebP

WebP是一种支持有损压缩和无损压缩的图片文件格式,派生自视频编码格式 VP8。根据 Google 官方的数据,无损压缩后的 WebP 比 PNG 文件少了 26% 的文件大小,有损压缩在具有同等SSIM索引的情况下WebP 比 JPEG 文件少25-34%的文件大小。WebP支持无损透明度(也叫做alpha通道),支持动画格式Animated WebP 。

虽然目前仅Android系统原生支持WebP格式, 但由于其对页面性能优化的巨大意义, 我们会在页面加载时进行环境探测, 如页面渲染环境支持WebP我们会替换页面中的图片链接为WebP格式的版本。 如果页面专门用于可控的客户端内(我们能在客户端中放置专门的WebP decoder),就算是iOS环境我们也会启用WebP.

优化高分屏和弱网适配

从苹果的Retina开始,手机厂商开始越来越多的使用高像素密度显示屏。在浏览器里我们的一个CSS像素往往能对应两个或更多个设备像素,在这种环境下为了追求最好的显示效果,我们会采用数倍于浏览器CSS像素标识的图片尺寸. 这里需要注意的是,如果你采用了2x (两倍CSS像素分辨率) 的图片,由于水平和垂直像素都进行了加倍,最终图片体积会增加4倍(内存占用也会增加4倍). 同理,如果你采用了3x的图片,最终增加的传输体积会增至9倍.

用户喜欢清晰绚丽的图片, 但用户更加痛恨打不开的页面. 在我们的实践中,我们最多使用2x(两倍CSS像素分辨率)的图片。 如果页面专门用于可控的客户端内,我们会根据从客户端获取的网络情况替换页面所使用的图片资源. 在最糟糕的网络环境(2G移动网络),我们甚至会采用按30%质量进行压缩的图片以替换原始图片链接。

单张图片大小控制

有时,如果不设限无论你如何优化糟糕的情况总会出现。在我们的实践中, 针对图片我们设置了单张图片大小不超过50Kb的限制。在每次发布时,我们会对页面图片进行检查, 如果图片超过这个限制仍需要发布,就得走特别的流程了.

合理使用CSS/SVG/ICON Font替代图片

传统桌面Web中,针对页面内的图标,我们往往采用Sprite(雪碧图)技术把多个图标合并到一张大图片中,针对不同的图标显示大图中不同的部分。但在移动互联网环境下, 由于设备内存有限,每使用Sprite技术展示一个图标,都需要浏览器把整个大图解码到内存中一次,考虑到前文提到的多倍CSS像素分辨率情况, 占用的内存和解码时间往往是可观的。不合理的使用Sprite技术会造成移动页面性能不升反降。

更合适的选择是CSS3,SVG和ICON Font技术。如果你的图标能使用这些技术绘制,在任何分辨率和缩放设置都可以提供清晰的效果并减小传输和内存的开销.

对图片进行按需加载

电商类型网站多用多图列表页面展现商品内容, 我们会在非WIFI网络环境时对图片资源进行按需加载,仅仅当图片资源出现在首屏或随着用户滑动屏幕进入可见区域时,我们才进行加载. 进行这项优化的关键在于对全局的图片呈现进行一层抽象,以便统一控制.

网络请求

今天我们谈论的无线页面,很多时候已不再是传统的"页面",而是一个个"单页应用"。随着应用复杂度的逐渐增加,所需加载的除图片等静态数据外,动态数据也会越来越多。如果想追求高质量的单页应用,对这些请求的优化势在必行.

域名收敛

如果你页面中引入的各种资源来自不同的域名,注意每增加一个域名,都会增加一次域名解析开销。 在复杂的国内移动互联网网络环境下,不同域名的解析速度可能会相差数十倍。 所以你需要有意识的收敛页面资源所需解析的域名数, 特别是会阻塞页面渲染的CSS,JS,Font资源。 很多性能糟糕页面究其原因或许会是引入的资源域名解析速度很慢或完全不能正确解析。在我们的实践中, 一个页面所产生的域名解析数不能超过5个。

减少请求数

在优化了需要解析的域名数后,你需要关注页面资源请求数. 如果是长期维护的产品型页面 ,页面中引入的静态资源除最通用的基础库外需要按依赖顺序进行合并压缩. 一般是JS和CSS请求各一。 针对电商厂商多见的营销活动页面,我们甚至开发了工具把全部的CSS和JS资源内联入页面,从而实现除图片外的其余资源One Request就能获得.

另外,资源请求重定向也应该尽量避免,少一次重定向,少一个请求数.

文本数据的优化与压缩

文本数据(HTML,CSS,JavaScript)的优化与压缩分为三个阶段,分别是发布准备(去除注释,合并CSS声明,去除不会被执行的JS代码块), 编译期压缩(合并文件,去除空格,混淆) 和 传输阶段压缩( GZip ) . 这项优化的关键在于梳理流程确保压缩的自动化和服务器GZip指令被正确配置。

数据接口优化与监控

随着近两年Web前后端分离思潮的流行与前端模板技术的发展 , 我们越来越倾向在页面加载完成后再通过接口获取JSON数据并在前端进行页面渲染。这种方式带来了页面第一次加载速度的提升,但常常把原有的性能问题隐藏了起来。 需要花功夫优化的数据获取并最终呈现时间往往被隐藏在空页面快速呈现的表象之下。更严重的情况发生在需要从多个不同接口获取数据,并且这些接口调用还存在互相依赖的情况下,一旦出现这样的情况,页面性能往往是不升反降的.

在我们的实践中, 我们要求数据在后端组装完成后再交由前端渲染,一屏中完整渲染所需数据不能来自多过一个接口。 所有数据源统一收敛到单一的接口服务层,以便进行统计和监控。

@hongru

This comment has been minimized.

Show comment
Hide comment
@hongru

hongru Jul 15, 2015

Contributor

如果作为一个用户来看,在配套文章出来之后,如果文章能整合一些跟性能优化相关的项目,代码,工具,解决方案,共享出来就nb了,纯粹的文字稍微有点干

Contributor

hongru commented Jul 15, 2015

如果作为一个用户来看,在配套文章出来之后,如果文章能整合一些跟性能优化相关的项目,代码,工具,解决方案,共享出来就nb了,纯粹的文字稍微有点干

@Nice-PLQ

This comment has been minimized.

Show comment
Hide comment
@Nice-PLQ

Nice-PLQ Jul 16, 2015

确实像楼上说的那样

Nice-PLQ commented Jul 16, 2015

确实像楼上说的那样

@koshitang

This comment has been minimized.

Show comment
Hide comment
@koshitang

koshitang Jul 16, 2015

请问一下你们图片压缩,是通过什么工具来搞的呢。

koshitang commented Jul 16, 2015

请问一下你们图片压缩,是通过什么工具来搞的呢。

@zeronexm

This comment has been minimized.

Show comment
Hide comment
@zeronexm

zeronexm Jul 16, 2015

https://developers.google.com/speed/webp/download 官网有工具介绍的;顺便请教下cwebp能不能批量转换图片

zeronexm commented Jul 16, 2015

https://developers.google.com/speed/webp/download 官网有工具介绍的;顺便请教下cwebp能不能批量转换图片

@Tancy

This comment has been minimized.

Show comment
Hide comment
@Tancy

Tancy Jul 16, 2015

Contributor

@koshitang 如果是UI类的图片直接PS或者FW 导出,产品类的图片Alicdn的服务给生成各种尺寸,质量,锐化的规格的图片。

Contributor

Tancy commented Jul 16, 2015

@koshitang 如果是UI类的图片直接PS或者FW 导出,产品类的图片Alicdn的服务给生成各种尺寸,质量,锐化的规格的图片。

@zeronexm

This comment has been minimized.

Show comment
Hide comment
@zeronexm

zeronexm Jul 16, 2015

单张很大的图片如何限制到50kb,支付宝首页那些图好大,也只有80k左右,如何压缩到这么小的..

zeronexm commented Jul 16, 2015

单张很大的图片如何限制到50kb,支付宝首页那些图好大,也只有80k左右,如何压缩到这么小的..

@yesvods

This comment has been minimized.

Show comment
Hide comment
@yesvods

yesvods Jul 16, 2015

期待后续优化思路,的确,有配套方案会是一个不错的参考

yesvods commented Jul 16, 2015

期待后续优化思路,的确,有配套方案会是一个不错的参考

@Tancy

This comment has been minimized.

Show comment
Hide comment
@Tancy

Tancy Jul 16, 2015

Contributor

@xiaowtz 这个针对无线端的。文件大小尽量往这个方向靠拢,具体的方法看图片内容而定,矢量绘画的图片和照片类的位图方法也有些区别。

Contributor

Tancy commented Jul 16, 2015

@xiaowtz 这个针对无线端的。文件大小尽量往这个方向靠拢,具体的方法看图片内容而定,矢量绘画的图片和照片类的位图方法也有些区别。

@liya3719

This comment has been minimized.

Show comment
Hide comment
@liya3719

liya3719 Jul 16, 2015

干巴巴的文字

liya3719 commented Jul 16, 2015

干巴巴的文字

@quaggan

This comment has been minimized.

Show comment
Hide comment
@quaggan

quaggan Jul 16, 2015

建议结合实例。 想看看 弱网适配和图片按需加载 这几个方面具体示例和工具技术 学习下

quaggan commented Jul 16, 2015

建议结合实例。 想看看 弱网适配和图片按需加载 这几个方面具体示例和工具技术 学习下

@ChenQiuge

This comment has been minimized.

Show comment
Hide comment
@ChenQiuge

ChenQiuge Jul 17, 2015

谢谢分享实践经验,文章已被转载至CSDN极客头条:http://geek.csdn.net/news/detail/35826。

ChenQiuge commented Jul 17, 2015

谢谢分享实践经验,文章已被转载至CSDN极客头条:http://geek.csdn.net/news/detail/35826。

@creeperyang

This comment has been minimized.

Show comment
Hide comment
@creeperyang

creeperyang Jul 17, 2015

启用webp感觉激进了点,另外合理使用CSS/SVG/ICON Font替代图片能详细讲讲吗,如 svg的兼容性处理, icon font 按需制作还是有冗余 等等。

creeperyang commented Jul 17, 2015

启用webp感觉激进了点,另外合理使用CSS/SVG/ICON Font替代图片能详细讲讲吗,如 svg的兼容性处理, icon font 按需制作还是有冗余 等等。

@Tancy

This comment has been minimized.

Show comment
Hide comment
@Tancy

Tancy Jul 17, 2015

Contributor

@creeperyang 手机淘宝使用webp格式已经2年了,另外google facebook也在大量使用。我不认为这个是激进的做法,在国内的无线网络情况下,使用webp格式有非常大的收益。(这份文档主要针对无线网络,当然淘宝PC也有很多业务支持了webp)可以看实例:http://ntx.me/2015/05/18/webp/

Contributor

Tancy commented Jul 17, 2015

@creeperyang 手机淘宝使用webp格式已经2年了,另外google facebook也在大量使用。我不认为这个是激进的做法,在国内的无线网络情况下,使用webp格式有非常大的收益。(这份文档主要针对无线网络,当然淘宝PC也有很多业务支持了webp)可以看实例:http://ntx.me/2015/05/18/webp/

@creeperyang

This comment has been minimized.

Show comment
Hide comment
@lichunqiang

This comment has been minimized.

Show comment
Hide comment
@lichunqiang

lichunqiang commented Jul 17, 2015

👍

@Tancy

This comment has been minimized.

Show comment
Hide comment
@Tancy

Tancy Jul 17, 2015

Contributor

@creeperyang 关于icon font,这里有一份说明,可以参考一下。http://ntx.me/2015/05/21/IconFont/

Contributor

Tancy commented Jul 17, 2015

@creeperyang 关于icon font,这里有一份说明,可以参考一下。http://ntx.me/2015/05/21/IconFont/

@monw3c

This comment has been minimized.

Show comment
Hide comment
@monw3c

monw3c Jul 20, 2015

最后一点“在我们的实践中, 我们要求数据在后端组装完成后再交由前端渲染,一屏中完整渲染所需数据不能来自多过一个接口。 所有数据源统一收敛到单一的接口服务层,以便进行统计和监控。” 很多公司都不容易能做到...

monw3c commented Jul 20, 2015

最后一点“在我们的实践中, 我们要求数据在后端组装完成后再交由前端渲染,一屏中完整渲染所需数据不能来自多过一个接口。 所有数据源统一收敛到单一的接口服务层,以便进行统计和监控。” 很多公司都不容易能做到...

@Tancy

This comment has been minimized.

Show comment
Hide comment
@Tancy

Tancy Jul 20, 2015

Contributor

@monw3c 这个在任何公司都不容易做到。但是是一个很有价值的优化点。如果前端来分块获取内容
就会容易出现下图的情况,整个页面显示完成时间被拉长。消耗的时间也不稳定(dns解析,tcp建链,服务器响应等),而这部分由服务端完成的话会非常高效和稳定(有线高速网络,高性能服务器)。我们的经验来看,服务端能在200ms内完成,有些甚至几十ms。
http://gtms02.alicdn.com/tps/i2/TB1BpwkIFXXXXaoXXXXcs.SVFXX-946-362.png
图片为公司wifi下的数据,消耗的具体时间数值仅供参考。

Contributor

Tancy commented Jul 20, 2015

@monw3c 这个在任何公司都不容易做到。但是是一个很有价值的优化点。如果前端来分块获取内容
就会容易出现下图的情况,整个页面显示完成时间被拉长。消耗的时间也不稳定(dns解析,tcp建链,服务器响应等),而这部分由服务端完成的话会非常高效和稳定(有线高速网络,高性能服务器)。我们的经验来看,服务端能在200ms内完成,有些甚至几十ms。
http://gtms02.alicdn.com/tps/i2/TB1BpwkIFXXXXaoXXXXcs.SVFXX-946-362.png
图片为公司wifi下的数据,消耗的具体时间数值仅供参考。

@creeperyang

This comment has been minimized.

Show comment
Hide comment
@creeperyang

creeperyang Jul 20, 2015

@Tancy 最后一点有没有区分首屏或非首屏。首屏后端渲染的话没必要合并数据接口,而其它屏感觉应该没这么敏感。另外就是分散化的数据接口可以细粒度控制缓存。

creeperyang commented Jul 20, 2015

@Tancy 最后一点有没有区分首屏或非首屏。首屏后端渲染的话没必要合并数据接口,而其它屏感觉应该没这么敏感。另外就是分散化的数据接口可以细粒度控制缓存。

@Tancy

This comment has been minimized.

Show comment
Hide comment
@Tancy

Tancy Jul 20, 2015

Contributor

@creeperyang 最后一点的合并接口 主要是针对首屏且首屏渲染由前端完成的情况。

Contributor

Tancy commented Jul 20, 2015

@creeperyang 最后一点的合并接口 主要是针对首屏且首屏渲染由前端完成的情况。

@MicroConan

This comment has been minimized.

Show comment
Hide comment
@MicroConan

MicroConan Jul 24, 2015

直接把给老大汇报邮件发出来了吧。。。

MicroConan commented Jul 24, 2015

直接把给老大汇报邮件发出来了吧。。。

@perfmjs

This comment has been minimized.

Show comment
Hide comment
@perfmjs

perfmjs commented Jul 25, 2015

哈哈

@amowu

This comment has been minimized.

Show comment
Hide comment
@amowu

amowu commented Jul 26, 2015

👍

@unclay

This comment has been minimized.

Show comment
Hide comment
@unclay

unclay Jul 27, 2015

这算是一个优化思路,可以后期扩展成自己的一套具体优化方案

unclay commented Jul 27, 2015

这算是一个优化思路,可以后期扩展成自己的一套具体优化方案

@hkongm

This comment has been minimized.

Show comment
Hide comment
@hkongm

hkongm Jul 27, 2015

这篇挺一般的,没啥特别的

hkongm commented Jul 27, 2015

这篇挺一般的,没啥特别的

@kainy

This comment has been minimized.

Show comment
Hide comment
@kainy

kainy Nov 17, 2015

赞赞赞。

kainy commented Nov 17, 2015

赞赞赞。

@zollero

This comment has been minimized.

Show comment
Hide comment
@zollero

zollero Nov 18, 2015

来点配图或实例就更好了,还是赞

zollero commented Nov 18, 2015

来点配图或实例就更好了,还是赞

@izayl

This comment has been minimized.

Show comment
Hide comment
@izayl

izayl commented Nov 18, 2015

@AidanDai

This comment has been minimized.

Show comment
Hide comment
@AidanDai

AidanDai commented Nov 18, 2015

@summeroct

This comment has been minimized.

Show comment
Hide comment
@summeroct

summeroct Nov 19, 2015

赞,如果再搞一些具体实践的Demo就更有意义了,真正能让学习者从中受益

summeroct commented Nov 19, 2015

赞,如果再搞一些具体实践的Demo就更有意义了,真正能让学习者从中受益

@Tancy

This comment has been minimized.

Show comment
Hide comment
@Tancy

Tancy Nov 19, 2015

Contributor

保持关注,马上有全面的图文的最佳性能实践出台.

summeroct notifications@github.com于2015年11月19日 周四上午10:06写道:

赞,如果再搞一些具体实践的Demo就更有意义了,真正能让学习者从中受益


Reply to this email directly or view it on GitHub
#1 (comment).

Contributor

Tancy commented Nov 19, 2015

保持关注,马上有全面的图文的最佳性能实践出台.

summeroct notifications@github.com于2015年11月19日 周四上午10:06写道:

赞,如果再搞一些具体实践的Demo就更有意义了,真正能让学习者从中受益


Reply to this email directly or view it on GitHub
#1 (comment).

@TNT-Likely

This comment has been minimized.

Show comment
Hide comment
@TNT-Likely

TNT-Likely Nov 20, 2015

还是不错的,具体细节可以更详细一点会更好。

TNT-Likely commented Nov 20, 2015

还是不错的,具体细节可以更详细一点会更好。

@iwillow

This comment has been minimized.

Show comment
Hide comment
@iwillow

iwillow Nov 23, 2015

学习一个

iwillow commented Nov 23, 2015

学习一个

@sojuker

This comment has been minimized.

Show comment
Hide comment
@sojuker

sojuker Nov 28, 2015

在我们的实践中, 我们要求数据在后端组装完成后再交由前端渲染,一屏中完整渲染所需数据不能来自多过一个接口。 所有数据源统一收敛到单一的接口服务层,以便进行统计和监控。

这个说得好。 数据源还是收敛更好一些,不然的确是无端端地引入很多复杂度。

sojuker commented Nov 28, 2015

在我们的实践中, 我们要求数据在后端组装完成后再交由前端渲染,一屏中完整渲染所需数据不能来自多过一个接口。 所有数据源统一收敛到单一的接口服务层,以便进行统计和监控。

这个说得好。 数据源还是收敛更好一些,不然的确是无端端地引入很多复杂度。

@vincent1988

This comment has been minimized.

Show comment
Hide comment
@vincent1988

vincent1988 commented Nov 30, 2015

mark

@sxliusir

This comment has been minimized.

Show comment
Hide comment
@sxliusir

sxliusir commented Dec 11, 2015

mark

@shenghua

This comment has been minimized.

Show comment
Hide comment
@shenghua

shenghua commented Mar 14, 2016

mark

OpenRed referenced this issue in OpenRed/Hello-world Apr 6, 2016

@timy-life

This comment has been minimized.

Show comment
Hide comment
@timy-life

timy-life commented Apr 8, 2016

mark

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment