开篇

优化网站是一个系统性和持续性的过程。很多人认为优化网站的性能只需要合并图片啦,减小HTTP请求啦,部署CDN啦就行,实际上这都是见木不见林的做法。以上的做法经常会被面试者提起,在被问到自己在网页优化的经验和技巧时,大多数人都是例举出以上的这些方法。无可否认,上面这方法都可以在某种程度上提高网页的加载性能,然而仅仅知道几种方法,显然还远远不够。就好像我们学习一门新语言,如果只是知道的零散的一些单词,我们是无法完整地、自由地表达自己的思想的。我们需要的是方法论,用系统性的思维来解决系统性的问题。所以,本篇博文不会带你去细究哪一种方法会带给你优化性能,这些细节在文中提供的链接中的博文中都有非常详尽的介绍,本篇博文重要的是告诉你如何自顶而下地解决这类问题。

知识储备

追本溯源

一般来说,我们认为网站性能大概分为两种:加载性能交互性能。加载时间的长短以及交互反馈的时间是否及时能反应到界面上会提供给用户直接的预期感受。

加载瓶颈

加载性能指的是指用户从输入URL或者进入你的网站到可以与用户可以持续进行交互的这段时间。这段时间决定了用户的对网页的整体评价。通常,越快的网页加载性能,会提升用户的留存概率,而较长的白屏时间让用户等待,会降低用户的留存率,毕竟大家都这么忙,很少人会对着白色的屏幕发呆十几秒钟。造成网页加载的性能有很多:网络速度,硬件性能,代码的执行效率,资源的大小等都会影响我们看到完整界面的时间。你需要清晰地知道浏览器是怎么样呈现一张网页的,然后在顺着这条线去发现问题。

交互瓶颈

交互性能指的是,用户在网页可以完全交互后,在交互的过程当中,界面的流畅程度。交互性能一般与渲染帧数以及界面时间反馈有关系。人的眼睛能看到60帧(FPS)的动画为流畅,因此,如果界面的持续变化维持在60FPS会给用户的感觉提供很好的反馈。其次是对输入行为的时间响应,如果事件延迟执行100~300ms用户就会感觉到响应延迟,从而给客户带来流畅性不佳的体验。

浏览器

浏览器是Web应用的主要载体,自诞生以来它已经走过了30多个春秋了,从最初的只渲染简单的HTML标签,到现在的万花筒式的缤纷世界,浏览器的进化速度已经超过我们这个时代了。前端工程师的主要战场就是浏览器,因此对浏览器的足够认知有助于我们开发出更好的应用和产品。浏览器的技术底层细节非常复杂,如果要细细研究会花费不少的时间,然而其渲染流程的有一些基础的了解确是必不可少的。例如:浏览器是如何渲染出网页的,以及它是怎么执行脚本的,以及它在整个程序运行中的结构是如何的。我在这篇文章中大致的分析了在地址栏中输入URL到网页展示的全过程,你可以查看帮助你更好了解浏览器原理。自从08年chrome诞生以来,浏览器就不再是一个黑盒子,google对技术开源以及持续的改进,使得我们现在用的浏览器已经完全可以媲美一个操作系统了。在这篇文章中更加详细的介绍了浏览器的细节,了解他们有助于你开发自己的应用,从底层开始构建自己的知识体系。

另外利用好浏览器提供给我们的工具能够极大地提高我们找到性能瓶颈的速度。google提供了非常专业的浏览器开发工具dev tools,非常契合我们开发人员的开发习惯。通过Performance或者Lighthouse等面板,我们可以找到一些在Lab环境下的优化点。总之,浏览器不管作为终端或者开发端,都是前端工程师必须深入的一个知识领域。

HTTP

HTTP协议是互联网的基石,我们看到的所有的资源,都是通过tcp/ip协议从远程的另外一台机器上交换过来的。事实上,http在首页性能优化上占据了很大一部分。在日常开发中,我们往往遇到的网络或者服务问题会比其他浏览器相关的问题要多。在浏览器飞速发展的时代,基于tcp的http协议在几十年的进化过程中也不断的完善自身,例如http1.x,http2以及未来的http3都时时刻刻在改进着我们交换信息的方式。http的系统知识非常多,也非常广,你需要平时不断的积累,观察,到底你的网站在网络这块还有多少的改进空间。具体的问题例如:http的重传机制,http的快速恢复,滑动窗口等。另外,了解和部署以及观察http缓存在前端开发来说几乎可以说是一个硬技能。我在这篇文章中较为深入的探讨了http缓存。与浏览器不一样,http的差异体现在服务器的部署和网络传输上面,较浏览器更少的依赖于客户端设备性能,因此在针对http优化是需要考虑的角度与浏览器不同。

最后,虽然我们的信息在光纤中传播的速度非常快,但是对于日益增长的需求来上来说,还不够快。考虑到世界上两地的距离以及物理条件,我们可以确定,在http在很多地方还存在优化的可能。部署CDN是一个一举多得的举措,当然还有其他种种的措施。了解http将对你进行网站优化时提供一个全面的知识体系的指导。这篇专栏对http进行了非常详尽的讲解,我推荐你去把它看完。

性能指标

虽然性能体验有部分是主观上,但是对于普遍的体验来说,我们还是可以通过一些客观的标准来对其进行衡量和评估。Google团队在一直在标准的制定上扮演着重要的角色。为了帮助开发者评估自己的网页的性能,他们提出了一些列的指标,这些指标大多数都建立在用户的视觉的反馈上,从白屏到可完整地持续性的交互,包含了复杂的算法逻辑,为的就是尽可能的反应网站的的性能,你可以通过他们提供的工具来检测自己的网页性能。另外我在这篇博客中比较全面搜罗了这些指标的介绍,以及我对他们优劣的一些看法。最后要确定的是,如果我们的性能已经到了已经被感官感受到慢的时候,我们网页的内在问题其实是已经非常严重了。通过这些指标,我们可以更加细微客观的知道自己应用的短处。

工具

古人云,工欲善其事必先利其器。开发工具,测试工具,调试工具以及监控工具在前端的领域都有是不可不用的。时至今日,我们早已经不是使用IE6用alert来调试开发的时代了,当年的设计软件Dreamweaver也被大部分程序员淘汰了。靠着丰富开发的社区生态,我们可以站在巨人的肩膀上,搭建自己的工具链条。我在下面列出集中在开发中常见的性能调试工具,来帮助定位网页的性能:

1.Dev tools

相信任何做前端的工程师都离不开这个工具,它是集成到谷歌浏览器中的工具面板(在其他的浏览器中也有相关的工具,例如firefox的firebug等。我们对他们的统称为dev tools),提供给开发者专业全面的信息。其中功能非常丰富,你甚至可以在里面发现一些彩蛋。我在这个系列中比较全面地介绍了chrome的开发者工具一些用法,你感兴趣的话可以去看看。

这篇文章写成时间较早,相对于Chrome浏览器如今两个礼拜一个版本的速度来说显然有些落伍了。

2.Lighthouse

Lighthouse是一种基于web的网页测试性能的系统,你只需要在输入框中输入你需测试的网站的地址,它就会给出我们之前提到过的各种指标。当然,这些指标只是基于特定的环境(网络,机器,浏览器)下进行评估的,不具备普遍性。Lighthouse集成在chrome浏览器中,你可以很方便地使用它对网页进行整体的性能评估。

3.Fiddler & Charles & Wirmsharp

Fiddler和Charles分别是一款在window上和ios上的抓包工具。他们的功能都是非常丰富,提供了抓包,替换,监控请求的诸多功能。相对于前两者来说,wirmsharp在更深层次的细读上更加详细。但对于我们日常开发来说,选择前两者就足够了。抓包工具无论在开发还是在测试的过程中都非常有用,它不仅可以快速地定位问题的根源,而且在线上调试上有很好的辅助作用。

4.WebpageTest

Lighthouse一样,webpagetest也是基于网页的性能测试系统,同样是输入测试网站地址,它会给出结果,只不过它侧重http的方面的,而且在网络细度上具备丰富的可调节性,例如,可以测试某个地方的网页加载速度,可以在地图上选择即可。对CDN的应用的效果测试十分重要。

5.PageSpeed Insights

PageSpeed Insight也是google的一些性能服务报告。你只需要提供一个原始的url链接,它会帮助你分析你的网页性能。PSI与之前的工具不一样的是,它是基于谷歌爬虫的历史数据的,并非时时的对当前这次访问做各项性能数据统计。这对我们的性能评估工作有非常大的广泛的作用。PSI的缺点就是并非所有的网页都被google爬虫爬取,因此,在正对特定的或者不开发的应用来说,它的作用就显得比较小了。

6.Chrome User Experience Report

CUER是一项google的性能检测计划,通过引入google提供的脚本,将我们的客户端数据上报google,从而统计你的网页的性能报告和评估。开发者可通过查询该数据集来了解使用不同硬件、软件和网络的实际 Chrome 用户的上网体验。分析很多网络原点可帮助网站开发者和网络社区了解它们的表现出色之处,发现需要改进的领域。

7.Eruda

Eruda是在移动端开启调试的利器。它通过模拟PC端的devtools,提供给我们移动端的一个类似的dev tools的调试界面。在调试网络和缓存方面尤其有用。缺点就是功能远远不如桌面版真实的dev tools强大。这是一个阉割版本的调试工具,功能非常有限。

资源准备

You can't optimise what you don't measure。我们很多时候凭自己的感觉来判断一个网页的性能,然而往往人的感觉并不可靠。而且我们在判断一个网页的性能是只是单独的在一个特定的条件下做判断,这种判断其实是孤立的,不可靠的。当性能已经能被人的感观捕获的话,事情往往就已经太迟了。

在一个网站上线后我们需要对它进行持续的,全面的,广泛的性能检测。而这样一种工作的前提条件就是搭建一套性能监控系统。我在这篇文章里面讲到过如何去搭建一个性能监控系统。搭建一个监控系统并不容易,需要的人力和物力资源不在少数。在大型一点的公司,都有资源和人力控制自己的额团队搭建一套完善的系统,在中小性公司,我建议还是使用第三方的别人的优秀开源作品。

所以你在开始动手干大事之前,请确保你的资源协调能力,安排人员和资源,预估好时间,以免因为客观的因素半途而废。尤其是打算自己动手搭建监控系统的时候,往往需要统筹全局的权力去安排协调各个部门的人力。所以,实现对你的资源进行评估后再开始做这件事,做到未雨绸缪。

锱铢必较

预算

在搭建一个网页应用之前制定预算并不是天方夜谭。在一开始对网站应用的体积进行合理的预测,能够知道你后续在开发新功能和接受新需求时变得谨慎。合理地制定预算方式是需要一定的经验,而最终的预算值也并非一定要十分精确,只需要给出合理的预期即可。一般我最好能够有参照的标准:例如你的竞争对手的应用,或者行业内做的最好,体验最好的那家企业的应用。通常随着功能的完善和丰富,我们的代码数量也会越来越多,时时刻刻对照着我们最初安排的那张“预算表”去对对照你的搭建过程。另外,提前制定预算也可以在面对产品不合理的诉求时当挡箭牌(到时候加载慢可不能怨我哦)。

资源

web应用的丰富发展使得我们需要从服务器上加载的东西越来越多,尤其是图片,视频和字体等媒体资源,我们在一开始的时候就需要对他们进行一些处理。例如,压缩图片和视频使得体积更小巧,还有选择不同格式的图片可以有效的减小体积。Google developer上的一系列文字详尽的讲明白了图片以及视频的处理方式,以及如何找到合适的策略构建自己的图片资源。

积沙成塔

性能优化不是一蹴而就的,需要长时间的,反复的去实践。有可能我们发一次版本也就是解决一个很小的优化点。但是这些点经过时间的积累,最终会反馈到整体的网页性能上。保守的策略是逐步的解决性能问题。不论是优化一段代码,还是减少一条http请求,只要长期地,充满干劲的去朝着一个方向做优化工作,性能肯定得到有效的改进。

整体思维

预见未来

如果你是从头开始做一个项目,那么在某种程度上来说你的未来是由你自己的决定的。但事实是很多项目,我们接手过来时倒腾了好几手的,这些项目不幸现在落在了你的头上,你的老板于是叫你优化项目,这时候你一定要小心翼翼,以免掉到了别人给你的坑。而如果是个全新开始的新项目,那么你就能放手一搏了,不不不,在面临一个新的项目的时候,你同样需要小心翼翼的,这种小心是在预见上,而不同于之前的是在放手去做上。你在你选择某个功能的时候你需要仔细它思考,尤其在底层一些设计上,更需要兼顾功能和性能。

前期架构

前期架构多网站来说十分钟重要。我认为在架构方面的工作直接或者间接影响了我们在后面一些列的开发和优化的细节打方向。架构其实是属于选方向的。古语哟云,条条道路通罗马。我们的一个产品,在功能上的接口是统一的,但是实现的方式确实有很多种。例如,架构师在前期就根据各项指标评估,这个产品用什么样的方式去完成选用什么语言,何种优化的方式监控后续的需求迭代。例如:PWASPA的优化逻辑不一样,MPA和SPA的优化也不一样,REACTVUE或者ANGLAR在细节上以及优化上的逻辑思路也是不一样的,又比如,我们的网页应用的定位决定了我们是使用高清的图片还是次一点的小格式图片,又或是字体等。虽然我们都可以用他们去实现统一的目标,但是考虑到人员,这是储备,维护,扩展等方面,架构师在选择这些重要的因素是,就应该多方思考,权衡利弊。或者使用APP SHELL或者其他形式承载你的应用。

编写代码

前端程序员经常被人戏称为API调用工程师,有时候不知道是不是应该感到该无奈?我认为如今进入前端这一领域已经很低了,而且在可预见未来,门槛会越来越低。如果你用过那种可视化IDE功能强大的web应用,你就应该知道,以后学习前端技术去做一个网页应用几乎只需要几天甚至几小时的学习时间就可以了。如今框架的兴起也方便了开发人员的工作量,而很多交互性能,我们基本上都可以有框架底层来给你解决。我们能做到的只能是在代码的可维护性上做做文章。(或者是使用for替代forEach提升性能o(╥﹏╥)o)。虽然如此,但这并不是你不去深入研究的原因。我认为在编写代码的过程刻意地使用关注底层CPU的计算性能优化虽然不太可能,但是我们可以通过其他方式提升业务性能,例如:根据业务类型安排还http的请求时序,根据框架提供的异步能力加载JavaScript或者其他资源,在某些大型的计算上刻意地使用worker或者自己的算法能力等。只要你愿意学习进步,任何地方做任何事情都能够让你大展拳脚。

后期监控

后期监控我已经在很多地方强调过了。好的监控能帮我们发现系统的漏洞,性能的缺陷,我认为大多数人在功能完成后就很少持续关注现实的代码运行状况了,只是在临时发现了bug或者老板打电话怒气冲冲的职责网页加载速度慢的时候,才会去线上看看自己的代码,这种是属于被动的监控。真正的监控的不止防范于未然,而且还能预测未来,对照现在,让我们在对比中不停的磨练自己写出更好的代码。

改革与革命

历史的教训

改革,在古代被称之为变法。回顾历史的变法者,功成名就的寥寥无几,大多数是以失败告终。而革命又因为是成功人写就的历史,往往是在即成的历史上对革命者歌功颂德,但实际确实残酷血腥而成就微小升职反而不如前代。例如辛亥革命虽然革了大清朝的名,但在面对新中国的现代化等一些列问题时,毫无建树和改变。只是换了一个国号而已。我本人也不喜欢激进的做法,我比较相信时间能够抚平一切包括旧制度的缺陷,激烈的革命带来的往往是流血战争,真正需要转变的是人的思维和观念,消灭一个人很简单,要给遗体个人灌输观念就需要常年累月的付出。工业革命其实也是从逐步改良的蒸汽机而发展起来的,第二次,第三次的工业革命也是在第一次工业革命的低限度的手工业改良而来的。

历史对改革者都不太公平。我们都知道商鞅也好,王安石也好,还有张居正和阚友伟,变法者的境遇都是十分悲惨。当然一部分原因是因为既得利益者势力过于强大,但是另外一部分是他们的错失太过于强硬和激进。历史告诉我们,一时的热情终究会消散,只有对目标有坚定的信仰的并且懂得利用时间的人,才能达到自己的目的。罗马不是一日建成的,伟大的事业也不是一天只能完成的,这些道理同样适用于我们今天的主题。我认为在面对旧项目或者新项目的优化工作时,只要走对了方向,剩下的还是要交给时间。

环境与现实

如果你都是个性能优化老手,在精通了各项性能要素以及优化性能的方法后,你这时候需要面对一个现实的问题。这个问题也是在我在后续优化的时候遇到的:你的优化方案的现实性。我说的实现性是指公司环境,团队的技术能力,时间等客观条件。我曾经天真得以为如果自己什么都懂,就能什么都做。后来我才知道,很多事情并不是自己知道就能做的成功。例如你在搭建监控环境时需要的服务器资源,你在优化时具体到每个项目以及与这些项目负责人的沟通,还需要考虑当前你自己的工作量,排期,最后还需要考虑你这样做是否符合公司的基本要求,领导是否对你支持,公司环境(软硬件)限制等等,这时候你就需要给自己一些软件能,包括沟通能力,分享能力还有一点点小滑头。如果实在不行,那只能用脚投票了。

最终的抉择

性能在不明显的时候即主观也客观,通过数据和指标,我们可以客观地评估一个网页应用是否存在性能问题。主观是因为每个人对网页加载或者运行的感官是不一样的(你在非洲和欧洲上网时对网页加载速度的预期是不一样的)。我们即可以通过上面所学知识来达到优化的目的,同时也可以通过一个简单的loading来反馈给用户,让他在主观意识上减少性能加载缓慢带来的心理焦虑。或者两者都同时采用。当然无论你猜用何种方式,最终我可以通过数据来了解在性能这块上,用户的感受。例如留存率,留存时间甚至是手动调查问卷结果等。

总结

很可惜,这个世界上速成的东西大多数都很廉价。在你需要对既有的项目进行优化时你要做的和掌握的知识就得非常系统,并且在细节上有清晰的认识。而且改进性能这件事情上需要持续的投入精力才能逐步看到结果。性能优化其实需要掌握的知识是很广的,有些知识需要深入理解,但总体上,这些知识学习的成本和难度不高。你需要多方面的知识,需要慢慢的摸索在,掌握,没有捷径。

引用文档

Google Developers Document

Goolge Web Fundamentals

浅谈web前端优化的更多相关文章

  1. 浅谈web前端性能优化

    前端性能优化: 一.尽可能减少前端http请求. 1.合并优化脚本文件和css文件. 2.同种类型的背景图片尽量放在一起,用css控制显示. 二.使用浏览器缓存. 如果能强制浏览器缓存在本地,将会降低 ...

  2. 浅谈web前端开发

    我个人认为前端攻城狮其实就是编程技术人员,用一句话来形容“比UI设计懂技术,比技术人员更懂交互”,当然也有人说前端工程师是工程师中的设计师,是设计师中的工程师. 好了废话不多说了,下面进入正题吧!   ...

  3. 浅谈Web图像优化

    前端优化有很多,图像优化也是其中的一部分.无论是渐进增强还是优雅降级,图像优化成为了开发上不可忽视的一部分. 知其然,须知其所以然 图像优化的前提是需要了解图像的基本原理.常规的图像格式分为矢量图和位 ...

  4. 浅谈web前端开发阅历

    WEB前端研发工程师,在国内算是一个朝阳职业,这个领域没有学校的正轨教育,大多数人都是靠本人自学成才.本文次要引见本人从事web开发以来(从大二至今)看过的书籍和本人的成长过程,目的是给想了解Java ...

  5. 浅谈web前端就业的学习路线

    初级前端 主要学习三个部分:HTML,CSS,JavaScript 一.html + css部分: 这部分特别简单,到网上搜资料,书籍视频非常多.css中盒子模型,流动,block,inline,层叠 ...

  6. 初学者:浅谈web前端就业的学习路线

    初级前端 主要学习三个部分:HTML,CSS,JavaScript 一.html + css部分: 这部分特别简单,到网上搜资料,书籍视频非常多.css中盒子模型,流动,block,inline,层叠 ...

  7. 浅谈web前端安全

    单纯地在你的客户端弹出信息只是类似于迫使你在自己的房间脱衣服--没人看得到,自然也不算啥恶意行为.那么如果我把你的信息通过脚本发送到我的服务器保存起来呢?先放心,我不打算这么做,也没那笔闲钱去购置一个 ...

  8. 浅谈Web前端浏览器兼容问题

    对于兼容最近一直困扰我,以前写的代码只是针对高质量用户来使用 不考虑IE7,8 这样的浏览器 ,但是最近我开发的时候必须要兼容,大喊一声我曹,没有办法,自己来吧! 所谓的浏览器兼容性问题,是指因为不同 ...

  9. 浅谈WEB前端规范化标准之ESlint

    规范化标准 软件开发需要多人开发,不同的开发者具有不同的编码习惯和喜好,不同的喜好增加项目的维护成本,所以需要明确统一的标准,决定 了项目的可维护性,人为的约定不可靠,所以需要专门的工具进行约束,并且 ...

随机推荐

  1. 【Markdown】Shell命令高亮显示

    [问题]shell命令,黏贴到简书的代码块上,#后面的命令显示成被注释掉的效果 image.png [目的]高亮显示shell命令 [方案1]在代码块标示符后,加上此代码块所用的语言名(请注意要用小写 ...

  2. Java8通过Function获取字段名(获取实体类的字段名称)

    看似很鸡肋其实在某些特殊场景还是比较有用的.比如你将实体类转Map或者拿到一个Map结果的时候,你是怎么获取某个map的key和value.方法一:声明 String key1="name& ...

  3. Spring Boot引入Swagger并对界面进行美化

    Swagger是一个接口文档生成工具,在前后端分离的开发中经常会用到,下面就来介绍下Swagger的使用: 引入依赖 <dependency> <groupId>io.spri ...

  4. Python | JSON 数据解析(Json & JsonPath)

    一.什么是JSON? JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式.它基于 ECMAScript (欧洲计算机协会制定的js规范)的一 ...

  5. CF911G Mass Change Queries(线段树+暴力)

    cf机子真的快. 其实这个题的维护的信息还是很巧妙的. 首先,观察到题目中涉及到,区间修改这个操作,然后最后只查询一次,我们不妨用线段树来维护这个过程. 但是貌似直接维护每个位置的值可能不太好维护. ...

  6. 2021年1月-第02阶段-前端基础-HTML+CSS进阶-VS Code 软件

    软件安装 VSCode软件 能够安装 VS Code 能够熟练使用 VS Code 软件 能够安装 VS Code 最常用的插件 1. VS Code简介 1.1 VS Code 简介 Visual ...

  7. silky微服务快速开始

    项目介绍 Silky框架旨在帮助开发者在.net平台下,通过简单代码和配置快速构建一个微服务开发框架. Silky 通过 .net core的主机来托管微服务应用.通过 Asp.Net Core 提供 ...

  8. 脚本注入3(blind)

    布尔盲注适用于任何情况回显都不变的情况. (由此,可以看出,回显啥的其实都不重要,最重要的是判断注入点.只要找到注入点了,其他的都是浮云.) 在操作上,时间盲注还稍微简单一点:它不需要像布尔盲注那样, ...

  9. 【UE4 C++】学习笔记汇总

    UE4 概念知识 基础概念--文件结构.类型.反射.编译.接口.垃圾回收.序列化[导图] GamePlay架构[导图] 类的继承层级关系[导图] 反射机制 垃圾回收机制/算法 序列化 Actor 的生 ...

  10. 【c++ Prime 学习笔记】第18章 用于大型程序的工具

    大规模应用程序的特殊要求包括: 在独立开发的子系统之间协同处理错误:异常处理 使用各种库(可能包含独立开发的库)进行协同开发:命名空间 对比较复杂的应用概念建模:多重继承 18.1 异常处理 异常处理 ...