贴吧性能优化实践 - o'reillyvelocity.oreilly.com.cn/2013/ppts/performance... ·...
TRANSCRIPT
贴吧性能优化实践@berg
#velocity#2013.8
13年8⽉月20⽇日星期⼆二
About me
•雷志兴 (berg)
•百度贴吧前端负责人•前端基础库,开发工具、框架• http://tangram.baidu.com
• http://fis.baidu.com
•微博:@berg 微信订阅号:DevLife
13年8⽉月20⽇日星期⼆二
Also a cyclist13年8⽉月20⽇日星期⼆二
Agenda
•贴吧前端性能的挑战•全过程地性能优化•监控、分析方法•架构支撑优化•无线设备的优化
•总结和展望13年8⽉月20⽇日星期⼆二
贴吧的性能挑战
13年8⽉月20⽇日星期⼆二
版本、页面复杂
•PC版
•手机版• iPad版
•不同类型的吧和贴子•明星吧、活动吧、官方吧、图片区•直播贴、访谈贴
13年8⽉月20⽇日星期⼆二
13年8⽉月20⽇日星期⼆二
13年8⽉月20⽇日星期⼆二
13年8⽉月20⽇日星期⼆二
13年8⽉月20⽇日星期⼆二
13年8⽉月20⽇日星期⼆二
13年8⽉月20⽇日星期⼆二
13年8⽉月20⽇日星期⼆二
版本、页面复杂
•贴子百亿级,吧千万级•功能复杂•各色第三方模块•迭代速度快•每天5-‐10次上线
13年8⽉月20⽇日星期⼆二
产品 vs 性能
•无线页面改版•+ 摘要图
•+ Banner
•性能下降 10%
•流量下跌 20%
13年8⽉月20⽇日星期⼆二
性能优化没有尽头
•Andy & Bill's Law
•What Andy giveth, Bill taketh away
•性能与产品指标相关
•前端的「系统性」挑战
http://velocityconf.com/velocity2009/public/schedule/detail/852313年8⽉月20⽇日星期⼆二
愿景
•快速发现有价值的优化点•在高速迭代中完成优化•不断提高移动设备下的性能
13年8⽉月20⽇日星期⼆二
全过程地性能优化
13年8⽉月20⽇日星期⼆二
监控
分析优化
性能优化三部曲13年8⽉月20⽇日星期⼆二
监控
分析优化
13年8⽉月20⽇日星期⼆二
连接数的小故事
Browser HTTP 1.0 HTTP 1.1
IE 6,7 2 4
IE 8 6 6
Firefox 6 6
Safari 4 4
Chrome 6 6
Opera 4 4
13年8⽉月20⽇日星期⼆二
Browser HTTP 1.0 HTTP 1.1
IE 6,7 2 4
IE 8 6 6
Firefox 6 6
Safari 4 4
Chrome 6 6
Opera 4 4
连接数的小故事
真的吗?
13年8⽉月20⽇日星期⼆二
浏览器 服务端
测试方法
同时发起请求
并发限制
在3-‐4s间检测返回个数
Hold请求3s
剩余请求
13年8⽉月20⽇日星期⼆二
连接数的真相
64.7% 3.9%
8.0%
1.9%1.4%
1.0%
14.2%
1.4%3.5%
NA12345678+
13年8⽉月20⽇日星期⼆二
数据支撑优化
•CDN域名拆分方案
•连接数统计•组件合并最佳方案•用户带宽统计•组件利用率统计•PV重叠率统计
•……
13年8⽉月20⽇日星期⼆二
监控
•真实用户抽样•全国布点,真机监控•监控产品指标
13年8⽉月20⽇日星期⼆二
用户抽样
•真实用户•数据样本大•环境维度全•统计可自定义
1,852,084(样本数)
13年8⽉月20⽇日星期⼆二
onload首屏时间
DOM Ready
13年8⽉月20⽇日星期⼆二
全国布点,真机监控
•用户瀑布流•首包时间•白屏时间•页面最慢元素•竞品对比
13年8⽉月20⽇日星期⼆二
首屏时间
首包时间
DNS时间
真实网络环境13年8⽉月20⽇日星期⼆二
•减少条数、异步加载
•30条 — 5条
•首屏时间 +30%
•onload时间 +30%
13年8⽉月20⽇日星期⼆二
技术指标会误导我们
依赖外部脚本 请求时间长 失败率高
13年8⽉月20⽇日星期⼆二
依赖外部脚本 请求时间长 失败率高
•加载更多按钮
•1/5的2G用户无法使用
•响应时间长达5-‐10s
http://www.stevesouders.com/blog/2013/05/13/moving-beyond-window-onload/13年8⽉月20⽇日星期⼆二
监控 关注产品指标3秒后可用
13年8⽉月20⽇日星期⼆二
产品指标的重要性
•时刻关注正确的问题•让所有人看到性能优化的价值
•Steve souders: Creating a Performance Culture
13年8⽉月20⽇日星期⼆二
•从上层获得支持Get Support from the Top
•使用正确的语言Speak the Right Vocabulary
•从监控开始Start with Metrics
•让所有人都考虑性能Get Everyone on Board
http://www.stevesouders.com/blog/2013/05/17/creating-‐a-‐performance-‐culture/13年8⽉月20⽇日星期⼆二
监控
分析优化
13年8⽉月20⽇日星期⼆二
分析
•前提:基于充分的监控数据
•分析工具•有效地利用数据•合理的分析方法
13年8⽉月20⽇日星期⼆二
分析工具
•DynaTrace
•Chrome DevTools
•性能的关键路径(白屏、首屏时间)•加载过程,瀑布流•按资源大小、加载时间排序
13年8⽉月20⽇日星期⼆二
具象化你的数据
组织你的数据
13年8⽉月20⽇日星期⼆二
昨日 前日
1460ms 1435ms
3082ms 3001ms
6258ms 6040ms
1809ms 1745ms
1749ms 1689ms
3123ms 3050ms
3250ms 3171ms 图表:最基本的可视化
13年8⽉月20⽇日星期⼆二
白屏 1200ms
首屏 1370ms
onload 6906ms
功能A 2968ms
功能B 3087ms
功能C 5165ms
区域A 1370ms
42/100
分数最直观
13年8⽉月20⽇日星期⼆二
•性能指数:
•指标权重: 白屏40%;首屏40%;功能可用15% (含多个权重);总下载5%
•极限指数:
•理想指数:
•性能得分:
13年8⽉月20⽇日星期⼆二
•找到值得衡量的指标
•不同的指标重要性有区别
•迅速看到理想和现实的差距
•建立性能评估体系
13年8⽉月20⽇日星期⼆二
平均 电信 联通 移动 教育网
首屏 1.50 1.52 1.46 1.53 1.45
总下载 4.05 4.01 4.12 4.06 4.48
可用性 99.57 99.55 99.72 98.36 99.62
2s+(%) 78.12 3087 77.63 69.72 90.77
5s+(%) 25.32 5165 26.70 23.47 32.36
和竞品对比(红色表示最慢,绿色表示最快)
13年8⽉月20⽇日星期⼆二
合理的分析方法
13年8⽉月20⽇日星期⼆二
16%
38%
18%
28%
0.8s
2.0s
0.2s
首屏时间的用户占比
} 更有优化意义
} 公司员工在此(双核+8G内存+chrome)
13年8⽉月20⽇日星期⼆二
• IE用户
•脚本加载和运行时间长• DOM节点过多
• 2G用户
•请求数过多•功能依赖外链Javascript
•移动低端机•页面复杂、动画过多•前端渲染多
重点分析慢速用户
13年8⽉月20⽇日星期⼆二
监控
分析优化
13年8⽉月20⽇日星期⼆二
优化
•架构支撑性能优化•静态资源快速调优•框架级完成同步异步切换
•无线性能优化•网络层优化
13年8⽉月20⽇日星期⼆二
组件化
13年8⽉月20⽇日星期⼆二
<html>
<? $widget-‐>load("A") ?>
<? $widget-‐>load("B") ?>
<? $widget-‐>load("C") ?>
</html>
源码结构
13年8⽉月20⽇日星期⼆二
<html>
<link rel="stylesheet" href="abc_MD5.css" />
<script src="loader_MD5.js"></script>
<A></A>
<B></B>
<C></C>
<script>
F.use("A", fn1);F.use("B", fn2);
</script>
</html>
最终页面
异步请求 AB_MD5.js
13年8⽉月20⽇日星期⼆二
function widget($name){
array_push($this-‐>allWidgets, $name);
//Render Widget HTML
}
function echoScript(){
$html = "";
foreach($this-‐>allWidgets as $widget){
$html .= $this-‐>getScriptFrag($widget);
}
return $html;
}
实现原理
13年8⽉月20⽇日星期⼆二
异步、并行加载脚本提高首屏时间
13年8⽉月20⽇日星期⼆二
<html>
<link rel="stylesheet" href="md5(abc).css" />
<A></A>
<B></B>
<C></C>
<script>
F.use("A", fn1);F.use("B", fn2);
</script>
</html>
重点功能,优先加载
13年8⽉月20⽇日星期⼆二
<html>
<? $widget-‐>load("A") ?>
<? $widget-‐>load("B", "important") ?>
<? $widget-‐>load("C") ?>
</html>
13年8⽉月20⽇日星期⼆二
<html>
<link rel="stylesheet" href="abc_MD5.css" />
<A></A>
<B></B>
<script src="b_MD5.js"></script>
<script> F.use("B", fn2); </script>
<C></C>
<script>
F.use("A", fn1);
</script>
</html>
异步请求 A_MD5.js
13年8⽉月20⽇日星期⼆二
<html>
<? $widget-‐>load("A") ?>
<? $widget-‐>load("B", "inline") ?>
<? $widget-‐>load("C") ?>
</html>
13年8⽉月20⽇日星期⼆二
<html>
<link rel="stylesheet" href="abc_MD5.css" />
<A></A>
<B></B>
<script>
//B & B depends' inline here
F.use("B", fn2);
</script>
<C></C>
<script>
F.use("A", fn1);
</script>
</html>
13年8⽉月20⽇日星期⼆二
重点功能提前提高可操作时间
13年8⽉月20⽇日星期⼆二
•自动异步加载,重点功能提前•自动动态合并•无用代码自动下线•根据权重自动调整包结构
•细分用户•非登录不加载发贴(减少1/4代码)
•CSS Sprites也如法炮制
组件化解决静态资源问题
http://fis.baidu.com13年8⽉月20⽇日星期⼆二
同步,或者异步?
13年8⽉月20⽇日星期⼆二
糟糕的2G网络
13年8⽉月20⽇日星期⼆二
DOM Ready
wifi
3G
2G
2.5s
5.2s
8.5s首包时间 5.5 -‐ 6s
13年8⽉月20⽇日星期⼆二
20%失败率
13年8⽉月20⽇日星期⼆二
2G网络
•建立连接时间长,失败概率高•首屏内容同步加载•重点Javascript inline加载
•无Javascript,也保证基本功能
•避免异步加载•为2G提供极速版本
13年8⽉月20⽇日星期⼆二
优化效果
• 2G下图片压缩、条数减少
•提速 30%
•加载异步改同步•功能可用时间提速 40%
• PV小幅提升
• 2G极速版本(无JS,极少CSS)
•提速 50 -‐ 60%
13年8⽉月20⽇日星期⼆二
异步同步混用
13年8⽉月20⽇日星期⼆二
13年8⽉月20⽇日星期⼆二
widget/thread_list.js
widget/thread_list.css
widget/thread_list.php:
<div class="thread_list">
<div class="title">...</div>
</div>
template/thread.php:
$widget-‐>load(
"thread_list",
array(/*data*/)
);
组件
页面
13年8⽉月20⽇日星期⼆二
首次打开,同步加载
13年8⽉月20⽇日星期⼆二
<code style="display:none" id="__cnt_2">
<!-‐-‐
<div class="thread_list">
贴子列表
</div>
-‐-‐>
</code>
<code style="display:none" id="__cnt_3">
<!-‐-‐
<div class="nav">
导航
</div>
-‐-‐>
</code>
全页inline输出
13年8⽉月20⽇日星期⼆二
<script>
TB.onPageArrived({
"id":"thread_list",
"parent_id":"thread",
"html_id":"__cnt_2"
});
</script>
分片注册组件
13年8⽉月20⽇日星期⼆二
<script>
TB.register({
"pkg" : {
"xcommon:p0" : {
"uri":"aio_658cdaf.js",
"type":"js",
"has":[]
}
}
});
</script>
注册静态资源
13年8⽉月20⽇日星期⼆二
用户操作,异步加载
13年8⽉月20⽇日星期⼆二
{
title: "",
widgets: [{
id: "thread_list",
parent_id: "pb",
html: "<div ...>"
}, {…}],
resource_map: {/* pkg: js, css*/},
script: "/*注册事件,初始化控件等 */"
}
接管URL
HTML
静态文件依赖
初始化脚本
<a data-‐href="/wow">WOW吧</a>
-‐-‐> http://tieba.baidu.com/wow?action=pb
13年8⽉月20⽇日星期⼆二
无线设备优化
13年8⽉月20⽇日星期⼆二
快速「响应」
13年8⽉月20⽇日星期⼆二
减少渲染
•首屏以外滚动渲染• 用textarea存放首屏外的HTML
• 提速 30%+,用户无感知
•逐楼分批渲染• setTimeout 分片
•做好动画开关13年8⽉月20⽇日星期⼆二
减少渲染
•避免前端模板渲染• 架构清晰
• gzip后JSON和HTML差别不大
•屏幕翻转,避免批量渲染• 通过 devicemotion事件模拟onbeforeorientationchange
http://www.slideshare.net/nzakas/enough-withthejavascriptalready13年8⽉月20⽇日星期⼆二
13年8⽉月20⽇日星期⼆二
13年8⽉月20⽇日星期⼆二
http://www.html5rocks.com/en/tutorials/device/orientation/
http://dev.w3.org/geo/api/spec-‐source-‐orientation.html
window.bind("devicemotion", function(event) {
});
13年8⽉月20⽇日星期⼆二
减少资源消耗
• DOM量大时,适当清理内存
•缓存数据而非DOM
•拒绝iScroll、避免CSS 3D加速
•减少CSS比Javascript更重要
•内存比CPU更重要
13年8⽉月20⽇日星期⼆二
网络优化13年8⽉月20⽇日星期⼆二
贴吧服务集群
用户
全国CDN节点
调度DNSISP DNS
13年8⽉月20⽇日星期⼆二
•静态资源上CDN
•下载提速 16%
•动态加速•跨机房长联
•优化TCP窗口
•下载提速 10% -‐ 20%
•缓存加速•命中则提速 60%
•受限于缓存利用率,贴吧低至0.5%
13年8⽉月20⽇日星期⼆二
总结13年8⽉月20⽇日星期⼆二
•全过程的性能优化•模拟布点和真实用户监控并重,并让数据具象化•确保监控指标和产品指标结合•关注用户的感受,并公平地对待用户
•由底层架构保证上层性能•用自动化工具和架构支撑优化,让性能优化可持续
•在安迪-‐比尔定律下,性能优化没有尽头
•节约移动设备的每一份资源
小结
13年8⽉月20⽇日星期⼆二
Thanks@berg
13年8⽉月20⽇日星期⼆二
Q&A@berg
13年8⽉月20⽇日星期⼆二