leadscloud

Google SEO|外贸营销推广

一些刚刚走出校门的大学毕业生很难找到工作。其他人则接受了他们觉得大材小用的工作。与此同时,学生债务已经突破1万亿美元大关。

这足以引发一波关于大学教育是否仍然值得的问题。

一组新的收入统计数据非常清楚地回答了这些问题:是的,大学值得上,而且差别还不是一丁点。尽管许多年轻的大学毕业生面临种种困境,但一个四年制学位或许从来没有比现在更有价值。

华盛顿经济政策研究所(Economic Policy Institute)根据劳工部统计数据所做的最新分析显示,大学毕业生和其他人的薪酬差距在去年达到历史最高。2013年,有四年制大学学位的美国人的平均时薪比没有学位的美国人足足高了98%。五年前、10年前和上世纪80年代初的薪酬差距分别是89%、85%和64%。

这种趋势并没有任何必然性。如果大学毕业生的人数超过经济需要,薪酬差距就会缩小。这种差距的最近一次增长尤为显著,因为它是在大学毕业生数量增长(其部分原因是,许多人在“大衰退”期间重返学校深造)之后出现的。薪酬差距仍然继续增长这一事实意味着,美国培养的大学生依然不够用。

“目前的大学毕业生太少了,”麻省理工学院(MIT)经济学家大卫·奥特尔(David Autor)说。“准备上大学的人也太少了。”奥特尔并未参与经济政策研究所的分析。

强调这些不足是非常重要的,因为如今的公开讨论(新闻媒体对此担有一定责任)通常聚焦于一个无可否认的事实:一个学士学位并不能确保成功。当然不能。没有什么东西能确保成功,特别是经过15年令人失望的经济增长和日益严重的不平等之后。

几乎可以肯定是,当专家和记者花费这么多时间谈论教育的局限性时,他们其实是在劝阻一些青少年不要上大学,成年人不要重返学校攻读学位。(与此同时,这些专家和记者正在送自己的子女上大学,而且经常为应该上哪所大学而困扰。)由于担心不划算而决定不上大学,是一个人在2014年有可能做出的最缺乏经济理性的决策之一。

受到热烈讨论的上大学成本也无法改变这个事实。根据奥特尔上周四发表于《科学》杂志(Science)的一篇论文,大学学位的真实成本大约是负50万美元。这是正确的:从长远来看,大学教育比免费还便宜。不上大学将使你损失大约50万美元。

奥特尔这篇论文以经济学家克里斯托弗·艾利(Christopher Avery)和莎拉·特纳(Sarah Turner)的研究成果为基础。它首先通过计算大学学杂费的真实成本得出一个数字,随后用大学毕业生和高中毕业生的终生收入差距减去这个金额。剔除通货膨胀和货币时间价值因素后,上大学的净成本为负50万美元,几乎是30年前的两倍。

这样计算肯定是不太精确的,因为它没有控制大学毕业生和非大学毕业生预先存在的差异,即无论上不上大学都会存在的差异。然而,还有一些研究在比较了其他方面类似的大学毕业生和非大学毕业生之后,也发现大学教育能够带来丰厚回报。

与此类似,经济政策研究所的新数据还显示,上大学的好处不仅仅属于通常会继续攻读研究生学位的名牌大学毕业生。只拥有学士学位的人和无学位人群的工资差距也在不断上升。

但引人注目的是,上过大学但未获得学士学位的人(这一群体还包括社区大学毕业生)的工资溢价并没有上涨。高经济回报属于那些有四年制大学学位的人。这些回报突显了减少大学辍学率的重要性——在《纽约时报杂志》(Times Magazine)最近一篇文章中,保罗·塔夫(Paul Tough)描述了得克萨斯大学(University of Texas)为减少辍学率所做的努力。

但你肯定听说有不少大学生负债累累,而且还找不到工作,这些令人震惊的故事又该如何解释呢?

这些轶事可能是真的,但传统思维往往夸大了这个问题。办理贷款的四年制大学毕业生人均负债约2.5万美元,与上大学的经济收益相比,这笔钱显得微乎其微。(扣除通胀因素后,我自己的学生债务几乎等同于这个数字。)拥有学士学位的25至34岁年轻人在4月份的失业率仅仅3%而已。

我发现经济政策研究所的数据特别耐人寻味。原因是,这家左翼研究机构特意强调,教育并非所有经济问题的解决方案。这也是很重要的。如同几乎所有其他人一样,大学毕业生也正在遭受经济增长乏力,增长收益不成比例地流向最富裕家庭等现象的负面影响。

过去10年,大学毕业生的平均时薪仅上涨了1%,到大约32.60美元。薪酬差距增大的主要原因是,其他人的平均工资下降了——下降5%,降至大约16.50美元。“在我看来,整体现状是,几乎所有人的工资都没有增长,无论他或她从事何种工作,”该研究所所长劳伦斯·米舍尔(Lawrence Mishel)对我说。“工资的增长趋势在2002年就基本停止了。”

从整个国家的角度来看,教育只能解决美国经济的部分问题。我们还需要找到其他方式来提升生活水平——更不用说我们需要设法为没有大学学位的人提供好工作。

但从几乎任何个体的角度来看,上大学是一个无需动脑就可以做出的决定。这是迈入中产阶级乃至更富裕阶层的最可靠的入场券。质疑大学教育价值的人往往是那些明知道自己的孩子将来会上大学的人。

就在几十年前,高中还被视为教育的前沿。有些人甚至认为,鼓励出身卑微的美国人花费四年光阴上高中是一种浪费。到了今天,每个人都应该接受13年学校教育这种观点显然是不容置疑的。

但大约13年的教育没有什么神奇之处。随着经济在技术层面变得更加复杂,人们需要接受教育的时间将会上升。在某个时点,15年或17年教育将成为一个更有意义的普遍目标。

这个时点,其实已经到来。

在本地开发的插件如果没有上传到firefox的在线扩展里面,你需要设置一个自动更新,如果有更新,安装你插件的用户便可以自动更新。
http://www.borngeek.com/firefox/automatic-firefox-extension-updates/ 这篇文章,详细介绍了如何设置自动更新。

关于调试:

在about:config里,将extensions.logging值设为true,并关闭firefox
在命令行下运行firefox -console,这样启动时,控制台会有extension的log输出。
从命令行界面可以看到一些提示信息,根据这些信息,你可以更好的知道自己的插件为什么不能更新。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function getHostname(url){
var a = document.createElement('a');
a.href = url;
return a.hostname;
}

function GetTopDomain(host){
if(host.indexOf("http") > -1)
host = getHostname(host);
var index = host.lastIndexOf('.'), last = 4;
while (index > 0 && index >= last - 4){
last = index;
index = host.lastIndexOf('.', last - 1);
}
var domain = host.substring(index + 1);
return domain.length > 6 ? domain : host;
}

引方法只能针对部分域名,对于 xxxx.com.cn xxxx.co.in xxxxx.com xxx.in 都是可以识别的,但如果域名长度小于tld, 比如 xxx.com.cn 这样的就无法判断出来。

原文:http://www.ruanyifeng.com/blog/2006/11/the_logic_of_collective_action_public_goods_and_the_theory_of_groups.html

这几天,我就在看这本书。它是制度经济学领域的名著,出版于1965年,作者奥尔森(Mancur Olson,1932-1998)是马里兰大学的教授,已经去世了。

它问了一个很简单的问题:人们什么会组成集团?

传统的看法是,因为人们有共同利益,所以组成集团后,便于采取行动维护共同利益。

但是奥尔森回答说,不是这样。

人们之所以会加入集团,是因为集团本质上提供了一种集体性的公共商品(public good),也就是说,如果不加入,就享受不到特殊利益。比如,在西方某些企业只雇佣工会成员,所以只有加入工会,才能到该企业就业。再比如,只有加入美国医疗协会,才能在美国行医。

因此,奥尔森说,本质上集团的存在是一种”搭便车”行为(free ride)。只有当一个集团能够提供排他性的个人收益时,这个集团才能存在下去。

从这一点出发,可以得到两点推论。

(1)如果当一个集团为其成员提供的收益在下降,那么这个集团很可能就会走向衰弱。

(2)由于集团提供的是所有成员都可以享受的公共品,所以大集团的成员维护集团公共利益的动机会弱于小集团的成员,因为在大集团中,个人的贡献越大,他可以享受到的回报就越少。

[参考链接]

1. Wikpedia:Mancur Olson

2. Wikipedia:The Logic of Collective Action

(一)

上面这张图是统计学中很常见的一个图形,一般将它称为二八定律。它是19世纪末20世纪初意大利经济学家帕累托发现的,因为也被叫做”帕累托定律”。这个定律的内容是: >

在任何一组东西中,最重要的只占其中一小部分,约20%,其余80%尽管是多数,却是次要的。

在图形上看就是,20%的样本点占据了曲线下80%的面积,其余80%的样本点形成了一个只占20%面积的长尾巴。

这种现象在日常生活中非常常见,比如,20%的人占有的全社会80%的财富;商店80%的营业额是20%的商品产生的;你的英语单词量是10000个,但你经常使用的,不过只是其中的2000个单词。

(二)

2004年,_Wired_杂志的编辑Chris Anderson发表了一篇文章,在”二八定律”的基础上提出了”长尾理论”。

虽然都是基于同样的统计图形,但是”长尾理论”与”二八定律”的涵义截然相反。”长尾理论”提出: >

80%次要用户的那根”长尾巴”是很重要的。

“长尾理论”主要用来解释,像Amazon那样的网上书店为什么能够成功。这个理论提出,访问者能够在Amazon的网站上找到各种各样的书,因此这根长尾巴可以转变为销售量,而在实体书店中是没有办法找到这么多书的。所以,Amazon可以将潜在市场转变为销售量。

(三)

下面就是一个有趣的问题: >

作为一个个人,你是愿意处在那重要的20%的”少数”之中,还是愿意处在那根80%的”长尾巴”之中?

好消息是,根据”长尾理论”,在信息时代,个性化需求更容易得到满足,所以在”长尾巴”之中有更大的机会发展你的个性。

坏消息是,根据”二八定律”,”长尾”部分和”主干”部分的差异会非常明显,而且会越来越明显。

让我们来考虑搜索引擎的例子:市场上有许多搜索引擎,但是80%以上的市场份额是被两三家主导公司占领的,比如Google和Yahoo!,这是”二八定律”。那么其他众多小型搜索引擎应该怎么办?”长尾理论”的建议是,如果你没有办法做得比Google和Yahoo!更出色,那么就应该盯住那根”长尾巴”,注重满足用户的个性化需求。

同样道理,走好人生的道路,其实也只有两种方法:一是专业化,二是成为本领域中最优秀的。

(完)

[参考链接]

1. Wikipedia: The Long Tail

2. Wikipedia: Pareto principle

原文:http://www.ruanyifeng.com/blog/2006/10/pareto_principle_and_the_long_tail.html

昨天,我说我想推荐二部电影。

一部是故事片《Gran Torino》,另一部就是今天想说的纪录片《Religulous》,中文名为《宗教的荒谬》。

如果你去查词典,里面是没有Religulous这个词的。它是由主持人比尔·马赫(Bill Maher)创造出来的,意为religious(宗教)和ridiculous(荒谬)的合成。比尔·马赫就是想探讨下面这个问题: >

为什么有人相信那些荒诞的宗教传说?

据说,世界是由上帝创造出来的,圣母玛丽亚生下耶稣的时候还是处女,人死后灵魂会升入天堂……这些东西真的有人相信,而且是很多人相信。比尔·马赫走遍美国,采访不同的信徒,请他们解释为什么。这就是纪录片《Religulous》的主要内容。

它的可看性非常强,根据wikipedia的资料,该片是去年美国票房最高的纪录片(2008年10月上映),在历史上所有纪录片中排名第7位。如果你想了解美国社会中的宗教状况,这部纪录片是必看的。

==========================

下面,我想谈谈我的感想。

我觉得,从思想层面看,这部作品的价值并不大。

因为,我认为比尔·马赫将宗教和宗教传说混为一谈了。宗教传说是荒唐的,但是宗教本身是有其合理性的。你不能因为”创世纪”的传说是荒唐的,就推定基督教也是荒唐的。宗教传说不等于宗教精神和宗教情怀。很多人相信宗教,不是因为相信上帝创造了一切,而是因为他们需要精神的安慰和寄托。

《圣经》是不是真的,与基督教应不应该存在,完全就是两回事。《Religulous》犯的错误就是,好像相信基督教就等于相信《圣经》中的每一句话。所以,我觉得这个片子不是很深刻,批判深度不够,最多只是社会风俗的记录而已。

========================

但是,比尔·马赫在片中说了一段很精彩的话,这才是我今天真正想说的东西: >

My big thing is I don’t know.

我的问题是我不相信。

That is What I preach. I preach the gospel of I don’t know!

这就是我要传播的东西。我所散布的福音,就是我不相信!

I mean that’s what I’m here promoting–doubt. That is my product. The other guys are selling certainty, not me.

我就是在推销怀疑!这就是我的产品。其他人出售的是让你相信,我出售的是让你怀疑。

我觉得这段话说得好极了!

怀疑是一切科学的起点。因为只有你怀疑了,你才不会盲从;只有你不盲从了,你才不会犯前人的错误;只有你不犯前人的错误,你才会做出新的东西;只有做出新的东西,你才能创造一个更美好的世界。

我的网志其实就是在做这件事:我在推销怀疑!

这个网志的一个目的,就是我想示范,独立思考是可以做到的,而且一点都不难。我不在乎别人认为我说的是对是错,我只希望你看了我的文章以后,自己也开始独立思考,开始用理性批判的精神进行怀疑。因为怀疑现行的秩序,这正是通往民主与科学的唯一道路。

我始终认为,中国人最落后的地方,就是思想太落后。大多数中国人的思想境界,还停留在封建时代。如果思想没有实现现代化,专制和愚昧就永远在这块土地上有市场。如果我们要建立一个民主和科学的新中国,那么第一步就是要改造人们的思想。而改造思想的第一步,就是传播怀疑。

如果大多数人不相信别人告诉他们的话,学会用自己的大脑,判断眼前发生的一切。凡事先想一想为什么,学会用不同来源的信息比对真伪,学会用逻辑的法则判断不同主张的合理性。那么,谎言就会无法生存,专制的基础就会动摇,中国发生变革的时刻,也就到来了。

[延伸阅读]

* 如何变得有思想?

(完)

原文: http://www.ruanyifeng.com/blog/2009/02/value_of_doubt.html

百度FEX上的一篇文章,感觉很不错。

引言

前阵子在w3ctech走进名企 - 百度前端 FEX 专场上曾“夸下海口”说听完讲座后七天就可以打造自己的前端性能监控系统,既然说出去了也不能食言。从前一篇文章前端数据之美相信大家对前端数据有了一定的了解,下面就针对其中的性能数据及其监控进行详细阐述。

开始行动

本文中的性能主要指 web 页面加载性能,对性能还不了解?不用担心,接下来的“每一天”跟我一起进入前端性能的世界。

Day 1 为什么要监控性能?

“If you cannot measure it, you cannot improve it” ———— William Thomson

这是一个最基本的问题,为什么要关注和监控前端性能?对于公司来说,性能在一定程度上与利益直接相关。国外有很多这方面的调研数据:

性能 收益
Google 延迟 400ms 搜索量下降 0.59%
Bing 延迟 2s 收入下降 4.3%
Yahoo 延迟 400ms 流量下降 5-9%
Mozilla 页面打开减少 2.2s 下载量提升 15.4%
Netflix 开启 Gzip 性能提升 13.25% 带宽减少50%

数据来源:http://www.slideshare.net/bitcurrent/impact-of-web-latency-on-conversion-rates http://stevesouders.com/docs/jsdayit-20110511.pptx

为什么性能会影响公司的收益呢?根本原因还是在于性能影响了用户体验。加载的延迟、操作的卡顿等都会影响用户的使用体验。尤其是移动端,用户对页面响应延迟和连接中断的容忍度很低。想象一下你拿着手机打开一个网页想看到某个信息却加载半天的心情,你很可能选择直接离开换一个网页。谷歌也将页面加载速度作为 SEO 的一个权重,页面加载速度对用户体验和 SEO 的影响的调研有很多

尽管性能很重要,开发迭代过程中难免会有所忽视,性能会伴随产品的迭代而有所衰减。特别在移动端,网络一直是一个很大的瓶颈,而页面却越来越大,功能越来越复杂。并没有简单的几条黄金规则就可以搞定性能优化工作,我们需要一套性能监控系统持续监控、评估、预警页面性能状况、发现瓶颈,指导优化工作的进行。

Day 2 有什么可用的工具?

工欲善其事必先利其器

页面性能的评估与监控有很多成熟优秀的工具,合理利用已有工具能达到事半功倍的效果。下面简单介绍几个常用的工具:

Page Speed

Page Speed 是谷歌开发的分析和优化网页的工具,可以作为浏览器插件使用。工具基于一系列优化规则对网站进行检测,对于未通过的规则会给出详细的建议。与此类似的工具还有 Yslow 等,推荐使用gtmetrix网站同时查看多个分析工具的结果,如下图所示:

gtmetrix

WebPagetest

WebPageTest 是一款非常优秀的网页前端性能测试工具,已开源。可以使用在线版,也可以自己搭建。国内也有利用 WebPagetest 搭建的性能测试平台,推荐使用阿里测 (以下示例使用阿里测进行测试)。

使用 WebPagetest,你可以详细掌握网站加载过程中的瀑布流、性能得分、元素分布、视图分析等数据。其中比较直观的视图分析功能可以直接看到页面加载各个阶段的截屏:

webpagetest

: 整个测试结果请点击此处

上图直观地展现了浏览类网站两个重要的时间点:白屏时间和首屏时间,即用户多久能在页面中看到内容,以及多久首屏渲染完成(包含图片等元素加载完成)。这两个时间点直接决定了用户需要等待多久才能看到自己想看到的信息。谷歌优化建议中也提到减少非首屏使用的 css 及 JS,尽快让首屏呈现。

PhantomJS

PhantomJS轻松地将监控带入了自动化的行列。Phantom JS 是一个服务器端的 JavaScript API 的 WebKit,基于它可以轻松实现 web 自动化测试。PhantomJS 需要一定编程工作,但也更灵活。官方文档中已经有一个完整的获取网页加载 har 文件的示例,具体说明可以查看此文档,国内也有不少关于此工具的介绍。另外新浪@貘吃馍香开发的类似工具berserkJS也挺不错,还贴心的提供了首屏统计的功能,具体文章可以查看此处

Day 3 开始线上真实用户性能监控

取其所长,避其所短

到此肯定有同学问,既然有这么多优秀的工具,为什么要监控线上用户真实访问性能呢?

我们发现,工具模拟测试会在一定程度上与真实情况偏离,有时无法反映性能的波动情况。另外除了白屏首屏之类的基础指标,产品线同样关注产品相关的指标,例如广告可见、搜索可用、签到可用等,这些功能直接与页面 JS 加载相关,通过工具较难模拟。

为了持续监控不同网络环境下用户访问情况与页面各功能可用状况,我们选择在页面中植入 JS 来监控线上真实用户访问性能,同时利用已有的分析工具作为辅助,形成一套完整多元的数据监控体系,为产品线的评估与优化提供可靠的数据。

关于不同监控方式的简单对比可以查看下表:

类型 优点 缺点 示例
非侵入式 指标齐全、客户端主动监测、竞品监控 无法知道性能影响用户数、采样少容易失真、无法监控复杂应用与细分功能 Pagespeed、PhantomJS、UAQ
侵入式 真实海量用户数据、能监控复杂应用与业务功能、用户点击与区域渲染 插入脚本统计、网络指标不全、无法监控竞品 DP 、Google 统计

Day 4 如何采集性能数据?

监控用户的痛点

线上监控哪些指标呢?如何更好地反映用户感知?

对于用户来说他感觉到的为什么页面打不开、为什么按钮点击不了、为什么图片显示这么慢。而对于工程师来说,可能关注的是 DNS 查询、TCP 连接、服务响应等浏览器加载过程指标。我们根据用户的痛点,将浏览器加载过程抽取出四个关键指标,即白屏时间、首屏时间、用户可操作、总下载时间(定义可见上篇文章)。这些指标是如何统计的呢?

确定统计起点

我们需要在用户输入 URL 或者点击链接的时候就开始统计,因为这样才能衡量用户的等待时间。如果你的用户高端浏览器占比很高,那么可以直接使用Navigation Timing接口来获取统计起点以及加载过程中的各个阶段耗时。另外也可以通过 cookie 记录时间戳的方式来统计,需要注意的是 Cookie 方式只能统计到站内跳转的数据。

统计白屏时间

白屏时间是用户首次看到内容的时间,也叫做首次渲染时间,chrome 高版本有 firstPaintTime 接口来获取这个耗时,但大部分浏览器并不支持,必须想其他办法来监测。仔细观察 WebPagetest 视图分析发现,白屏时间出现在头部外链资源加载完附近,因为浏览器只有加载并解析完头部资源才会真正渲染页面。基于此我们可以通过获取头部资源加载完的时刻来近似统计白屏时间。尽管并不精确,但却考虑了影响白屏的主要因素:首字节时间和头部资源加载时间。

如何统计头部资源加载呢?我们发现头部内嵌的 JS 通常需等待前面的 JS\CSS 加载完才会执行,是不是可以在浏览器 head 内底部加一句 JS 统计头部资源加载结束点呢?可以通过一个简单的示例进行测试:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8"/>
<script>
var start_time = +new Date; //测试时间起点,实际统计起点为 DNS 查询
</script>
<!-- 3s 后这个 js 才会返回 -->
<script src="script.php"></script>
<script>
var end_time = +new Date; //时间终点
var headtime = end_time - start_time; //头部资源加载时间
console.log(headtime);
</script>
</head>
<body>
<p>在头部资源加载完之前页面将是白屏</p>
<p>script.php 被模拟设置 3s 后返回,head 底部内嵌 JS 等待前面 js 返回后才执行</p>
<p>script.php 替换成一个执行长时间循环的 js 效果也一样</p>
</body>
</html>

经测试发现,统计的头部加载时间正好跟头部资源下载时间相近,而且换成一个执行时间很长的 JS 也会等到 JS 执行完才统计。说明此方法是可行的(具体原因可查看浏览器渲染原理及 JS 单线程相关介绍)。

统计首屏时间

首屏时间的统计比较复杂,因为涉及图片等多种元素及异步渲染等方式。观察加载视图可发现,影响首屏的主要因素的图片的加载。通过统计首屏内图片的加载时间便可以获取首屏渲染完成的时间。统计流程如下:

首屏位置调用 API 开始统计 -> 绑定首屏内所有图片的 load 事件 -> 页面加载完后判断图片是否在首屏内,找出加载最慢的一张 -> 首屏时间

这是同步加载情况下的简单统计逻辑,另外需要注意的几点:

  • 页面存在 iframe 的情况下也需要判断加载时间
  • gif 图片在 IE 上可能重复触发 load 事件需排除
  • 异步渲染的情况下应在异步获取数据插入之后再计算首屏
  • css 重要背景图片可以通过 JS 请求图片 url 来统计(浏览器不会重复加载)
  • 没有图片则以统计 JS 执行时间为首屏,即认为文字出现时间

统计用户可操作和总下载

用户可操作默认可以统计domready时间,因为通常会在这时候绑定事件操作。对于使用了模块化异步加载的 JS 可以在代码中去主动标记重要 JS 的加载时间,这也是产品指标的统计方式。

总下载时间默认可以统计onload时间,这样可以统计同步加载的资源全部加载完的耗时。如果页面中存在很多异步渲染,可以将异步渲染全部完成的时间作为总下载时间。

网络指标

网络类型判断

对于移动端来说,网络是页面加载速度最大的影响因素,需要根据不同的网络来采取相应的优化措施,例如对于 2G 用户采用简版等。但 web 上没有接口获取用户的网络类型。为了获取用户网络类型,可以通过测速的方式来判断不同 IP 段对应的网络。测速例如比较经典的有 facebook 的方案。经过测速后的分析,用户的加载速率有明显的分布区间,如下图所示:

gtmetrix

各个分布区间正好对应不同的网络类型,经过与客户端的辅助测试,成功率可以在 95%以上。有了这个 IP 库对应的速率数据,就可以在分析用户数据时根据 IP 来判断用户网络类型。

网络耗时统计

网络耗时数据可以借助前面提到 Navigation Timing 接口获取,与之类似的还有Resource Timing,可以获取页面所有静态资源的加载耗时。通过此接口可以轻松获取 DNS、TCP、首字节、html 传输等耗时,Navigation Timing 的接口示意图如下所示:

gtmetrix

以上重点介绍了数据采集部分,这也是系统中最关键的一部分,只有保证数据能真实反映用户感知,才能对症下药提升用户体验。数据采集完之后我们可以在页面加载完之后统一上报,如示例:

1
http://xxx.baidu.com/tj.gif?dns=100&ct=210&st=300&tt=703&c_dnslookup=0&c_connecting=0&c_waiting=296&c_receiving=403&c_fetch_dns=0&c_nav_dns=75&c_nav_fetch=75&drt=1423&drt_end=1436&lt=3410&c_nfpt=619&nav_type=0&redirect_count=0&_screen=1366*768|1366*728&product_id=10&page_id=200&_t=1399822334414

Day 5 如何分析性能数据?

让数据会说话

而数据分析过程,如前一篇文章所述,可以从多个维度去分析数据。大数据处理需要借助 hadoop、Hive 等方式,而对于普通站点则任意一种后端语言处理即可。

均值与分布

均值与分布是数据处理中最常见的两种方式。因为它能直观的表示指标的趋势与分布状况,方便进行评估、瓶颈发现与告警。处理过程中应去除异常值,例如明显超过阈值的脏数据等。

耗时的评估中,有很多这方面的研究数据。例如有人提出三个基本的时间范围:

  • 0.1秒 : 0.1 秒是用户感知的最小粒度,在这个时间范围内完成的操作被认为是流畅没有延迟的
  • 1.0秒 : 1.0 秒内完成的响应认为不会干扰用户的思维流。尽管用户能感觉到延迟,但 0.1 秒 -1.0 秒内完成的操作并不需要给出明显 loading 提示
  • 10秒 : 达到 10 秒用户将无法保持注意力,很可能选择离开做其他事情

我们根据业界的一些调研,结合不同指标的特点,制定了指标的分布评估区间。如下图所示:

gtmetrix

评估区间的制定方便我们了解当前性能状况,同时对性能趋势波动做出反应。

多维分析

为了方便挖掘性能可能的瓶颈,需要从多维的角度对数据进行分析。例如移动端最重要的维度就是网络,数据处理上除了总体数据,还需要根据网络类型对数据进行分析。常见的维度还有系统、浏览器、地域运营商等。我们还可以根据自身产品的特点来确定一些维度,例如页面长度分布、简版炫版等。

需要注意的是维度并不是越多越好,需要根据产品的特点及终端来确定。维度是为了方便查找性能瓶颈

小插曲 :之前从微博中看到有人评价说想做监控但是公司没有日志服务器。并不需要单独的日志服务器,只要能把统计的这个请求访问日志保存下来即可。如果网站自己的独立服务器都没有还有解决办法,在百度开发者中心新建一个应用,写一个简单的 Web 服务将接收到的统计数据解析存到百度云免费的数据库中,然后每天再用 Mysql 处理下当天的数据即可,对于普通站点的抽样性能数据应该没问题。请叫我雷锋。

Day 6 如何利用监控数据解决问题?

发现瓶颈,对症下药

对于图表制作,比较出名的有Highcharts,百度开发的Echarts也很不错。不管使用什么工具,最关键的一点就是让报表能突出重点,直观明了

制作报表前多问几个如何让人直观看到目前状况和可能存在的问题,哪些地方可以加强,哪些可以去掉,使用是否习惯等。

gtmetrix

有了能反映用户感知的真实世界、并且细分到各个业务功能,有详细的网络等辅助数据,我们在解决前端性能上便更加得心应手。监控系统已经对线上访问状况有了连续的反馈,根据现有评估与瓶颈选择对应方案进行优化,最后根据反馈进行调整,相信性能优化不再是个难题。

如何选择优化方案呢?这又是一个比较大的话题了,好在已经有很多经验可以借鉴。附录中就整理了部分性能的学习资料,可以根据需要阅读学习。

gtmetrix

Day 7 总结

通过以上“几天”的努力,我们可以搭建一个小而美的前端性能监控系统。但这仅仅是开始,前端数据有很多挖掘的价值。性能优化也是一门需要认真学习的课程,为了打造流畅的使用体验,为了让用户更加满意,赶紧搭建起自己的前端数据平台吧!

该文写在w3ctech走进名企 - 百度前端 FEX 专场之后,分享时的 PPT 在这里,视频在这里

华丽非分割线 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

福利——前端性能学习资料整理

性能准则 ★★★★★

分析工具 ★★★

入门

  • pageSpeed 基于谷歌性能准则的检测,可浏览器安装插件运行
  • Yslow 基于雅虎性能准则的检测工具,可浏览器安装插件运行
  • pageCheck 百度内部开发,指标齐全,支持自动运行

进阶

  • webPageTest 查看页面加载瀑布流等数据,进阶必备工具
  • Chrome 开发者工具 功能强大,值得学习
  • PhantomJS 功能强大的分析工具,高手必备瑞士军刀
  • JsPerf JS 执行性能分析网站,谁用谁知道

浏览器与 Html 标准 ★★

入门

进阶

开发实战 ★★★★

通用

动画与渲染

移动端开发

性能监控 ★★★★

相关会议 ★★★

推荐博客 ★★★

作者:zhangtao (http://weibo.com/u/1733215473) - 学无止境

1
2
PRAGMA short_column_names;
PRAGMA short_column_names = 0 | 1;

查询或修改 short-column-names 标志。 该标志会影响当 SELECT 查询后面的列表是一个 “表-列名” 或 “*”时 SQLite返回列名的方式。 通常, 如果 SELECT 语句连接两个或多个表, 结果列名将是 <表名/别名><列名>; 而若仅仅对单个表查询时,将是 。 但如果设置了 short-column-names 标志,列名将永远是 , 而不管是只查询一个表或同时连接多个表。

如果 short-column-names 和 full-column-names 都设置了, 则以 full-column-names 标志为准。

如果在pdo sqlite中使用join查询时,返回的关联数组会带有表名,如table.filed形式的,如果你不想带有表名,使用PRAGMA short_column_names = ON可强制取消。以下是具体的说明:

http://www.php.net/manual/en/function.sqlite-fetch-array.php

Typecho博客程序就有此问题,它会影响目录页面,导致目录页面无法获取文章,因为sqlite数据库下,返回的关联数组的key,都带有表名,但是在程序引用的时候,是没有带有表名的,会导致很多错误情况。

[Editor’s note: to get short column names there’s an undocumented PRAGMA setting. You can exec “PRAGMA short_column_names = ON” to force that behavior.]

I noticed that if you use Joins in SQL queries, the field name is messed up with the dot!
for example if you have this query:
SELECT n.*, m.nickname FROM news AS n, members AS m WHERE n.memberID = m.id;
now if you want to print_r the results returned using SQLITE_ASSOC type, the result array is like this :
array
(
[n.memberID] => 2
[n.title] => test title
[m.nickname] => NeverMind
[tablename.fieldname] => value
)
and I think it looks horriable to use the variable ,for example, $news[‘m.nickname’] I just don’t like it!

so I’ve made a small function that will remove the table name (or its Alias) and will return the array after its index is cleaned

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php 
function CleanName($array)
{
foreach ($array as $key => $value) {
//if you want to keep the old element with its key remove the following line
unset($array[$key]);

//now we clean the key from the dot and tablename (alise) and set the new element
$key = substr($key, strpos($key, '.')+1);
$array[$key] = $value;
}
return $array;
}
?>

Google前几日的排名算法发生了一些改变,可能是近期的又一次调整。Google每年都会频繁调整它的排名算法,这对英文SEO一块来说,是愈发难做了。目前来看,Google的这次调整主要的是针对网站外链因素的考虑。

原文: Google Algorithm & Ranking Shifts On Fire This Month

Despite Google saying nothing is going on, we’ve been seeing signs of major changes and reports of major changes in the Google search results and rankings.

Again, over the weekend, I’ve been getting private emails with tons of public chatter in theWebmasterWorld and even BlackHatWorld forums about Google making a lot of changes over the weekend.

Some are suspecting a massive Penguin update is about to hit, while others think it might be a Panda refresh and others think it is just Google’s normal actions on link networks. It is almost impossible to tell without a confirmation from Google, for all we know, it can be all three or more.

Even the tracking tools are all over the place, it seems like it even broke MozCast,SERPS.com shows major activity on Saturday, so does SERP Metrics and Algoroo.

click for full size

click for full size

click for full size

Here are some recent chatter comments from the forums:

Regardless of the weather anywhere overall my lowest-ever page views at 45.7% of 2014 average with the UK at 37.4% however fortunately not as bad as Friday at 26.5%, what a mess.

i did a small analysis.. i used two of my sites and ranked purely with GSA and 10 articles scraped and smashed one was used. it got hit. 

for my one another site i used 5 unique articles, spun with wordai, smashed as 1 articles with GSA.. it got hit but only 4-9 position drops.. not like first one..

so its getting clear that its penguin 3.0

Forum discussion at WebmasterWorld and BlackHatWorld.

本站用到了“相关阅读”插件,在文章尾部显示相关文章的链接,该插件非常实用。但是最近发现一个问题,就是当新的文章发布时,新文章尾部可以关联到已有文章,但是在老文章的相关阅读的列表并没有加入新发布的文章。感觉,应该是发布了新文章后,没有重建整个关联关系。插件本身为了性能考虑,应该只刷新了当前文章的关联信息,而没有刷新其他文章的。下面的代码分析也印证了这一点。

首先需要了解插件的运行流程,这里顺带发一下Yet Another Related Posts Plugin的代码分析。

插件的主函数为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public function __construct() {

$this->yarppPro = get_option('yarpp_pro');
$this->load_default_options();

/* Loads the plugin's translated strings. */
load_plugin_textdomain('yarpp', false, plugin_basename(YARPP_DIR).'/lang');

/* Load cache object. */
$this->storage_class = 'YARPP_Cache_'.ucfirst(YARPP_CACHE_TYPE);
$this->cache = new $this->storage_class($this);
$this->cache_bypass = new YARPP_Cache_Bypass($this);

register_activation_hook(__FILE__, array($this, 'activate'));

/**
* @since 3.2 Update cache on delete.
*/
add_action('delete_post', array($this->cache, 'delete_post'), 10, 1);

/**
* @since 3.5.3 Use transition_post_status instead of save_post hook.
* @since 3.2.1 Handle post_status transitions.
*/
add_action('transition_post_status', array($this->cache, 'transition_post_status'), 10, 3);

/* Automatic display hooks: */
add_filter('the_content', array($this, 'the_content'), 1200);
add_filter('the_content_feed', array($this, 'the_content_feed'), 600);
add_filter('the_excerpt_rss', array($this, 'the_excerpt_rss' ), 600);
add_action('wp_enqueue_scripts', array($this, 'maybe_enqueue_thumbnails'));

注意,其中的几个filter和action,filter是显示文章的时候调用的回调,action是增、删、改文章时的回调。这里重点关注action。delete_post,当删除文章时,需要删除该文章的关联信息,还要删除指向该文章的关联信息。分析代码:

1
2
3
4
5
6
7
8
9
10
11
/**
* Clear the cache for this entry and for all posts which are "related" to it.
* @since 3.2 This is called when a post is deleted.
*/
function delete_post($post_ID) {
// Clear the cache for this post.
$this->clear((int) $post_ID);

// Find all "peers" which list this post as a related post and clear their caches
if ($peers = $this->related(null, (int) $post_ID)) $this->clear($peers);
}

可以看到这个函数分作两步,首先是删除当前文章的关联信息,接下来删除指向该文章的关联。

而修改文章状态,如:从草稿变成发布,从发布改为私密,等等,使用的是这个回调:

1
add_action('transition_post_status', array($this->cache, 'transition_post_status'), 10, 3);

当有文章的状态出现变化时,这个回调就会起作用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/**
* @since 3.2.1 Handle various post_status transitions
*/
function transition_post_status( $new_status, $old_status, $post ) {
$post_ID = $post->ID;

/**
* @since 3.4 Don't compute on revisions
* @since 3.5 Compute on the parent instead
*/
if ($the_post = wp_is_post_revision($post_ID)) $post_ID = $the_post;

// Un-publish
if ($old_status === 'publish' &amp;&amp; $new_status !== 'publish') {
// Find all "peers" which list this post as a related post and clear their caches
if ($peers = $this->related(null, (int) $post_ID)) $this->clear($peers);
}

// Publish
if ($old_status !== 'publish' &amp;&amp; $new_status === 'publish') {
/*
* Find everything which is related to this post, and clear them,
* so that this post might show up as related to them.
*/
if ($related = $this->related($post_ID, null)) $this->clear($related);
}

/**
* @since 3.4 Simply clear the cache on save; don't recompute.
*/
$this->clear((int) $post_ID);

}

可以看到,这里只处理当文章的状态从发布修改为非发布等情况,对于新增文章,这里应该是什么都不做,也就是说,新增文章的关联关系是在另外的地方建立,而且每一次文章展示时,都会检查是否有关联关系,如果没有,则会全新计算生成。

那么这里就有了解决上面提到的功能增强的方法了,每次有文章更改时,清空关联关系表即可。增加一个方法:

1
2
public function clearall() {
}

在基类(YARPP_Cache)中提供默认实现,如上,什么都不做,由管理关联关系表的子类来实现清空关联表即可,在YARPP_Cache_Tables类中提供如下实现:

1
2
3
4
public function clearall() {
global $wpdb;
$wpdb->query("TRUNCATE TABLE {$wpdb->prefix}" . YARPP_TABLES_RELATED_TABLE);
}

在上述的delete_post和transition_post_status的回调中,增加这个方法的调用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/**
* Clear the cache for this entry and for all posts which are "related" to it.
* @since 3.2 This is called when a post is deleted.
*/
function delete_post($post_ID) {
// Clear the cache for this post.
$this->clear((int) $post_ID);

$this->clearall();

// Find all "peers" which list this post as a related post and clear their caches
if ($peers = $this->related(null, (int) $post_ID)) $this->clear($peers);
}
/**
* @since 3.2.1 Handle various post_status transitions
*/
function transition_post_status( $new_status, $old_status, $post ) {
$post_ID = $post->ID;

/**
* @since 3.4 Don't compute on revisions
* @since 3.5 Compute on the parent instead
*/
if ($the_post = wp_is_post_revision($post_ID)) $post_ID = $the_post;

// Un-publish
if ($old_status === 'publish' &amp;&amp; $new_status !== 'publish') {
// Find all "peers" which list this post as a related post and clear their caches
if ($peers = $this->related(null, (int) $post_ID)) $this->clear($peers);
}

// Publish
if ($old_status !== 'publish' &amp;&amp; $new_status === 'publish') {
/*
* Find everything which is related to this post, and clear them,
* so that this post might show up as related to them.
*/
if ($related = $this->related($post_ID, null)) $this->clear($related);
}

/**
* @since 3.4 Simply clear the cache on save; don't recompute.
*/
$this->clear((int) $post_ID);

$this->clearall();
}

注意,仅仅从操作关联关系表来看,在这两个方法中只需要clearall即可,其他流程都不需要,但是这个是基类,这个框架供各个子类使用,没有分析另外两个子类的功能,因此这里仅仅只增加clearall的流程,保留之前的已有实现。

在博客站点的文章数量不是特别多的情况下,该方法应该是非常有用的,如果文章特别多,则需要定点修改与该文章关联的文章的关联关系,将修改范围尽可能缩小,但是,可以想象,该实现将会非常复杂。建立关联关系的过程消耗站点的访问性能应该说是非常少的,如果只是访问一片文章,那么只会建这一篇文章的关联,不会全部创建,因此不会出现阻塞页面呈现的情况。

经过本站实测,该问题得到了解决。

来源:http://shentar.me/wordpress-%E7%9B%B8%E5%85%B3%E9%98%85%E8%AF%BB%E6%8F%92%E4%BB%B6%E5%8A%9F%E8%83%BD%E5%A2%9E%E5%BC%BA/

0%