Skip to content
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

前端性能优化 #38

Open
aermin opened this issue Mar 14, 2018 · 0 comments
Open

前端性能优化 #38

aermin opened this issue Mar 14, 2018 · 0 comments
Labels

Comments

@aermin
Copy link
Owner

aermin commented Mar 14, 2018

优化方向 优化手段
请求数量 合并脚本和样式表,CSS Sprites,按需加载资源,简化页面的设计
请求带宽 开启GZip,压缩JavaScript和CSS ,移除重复脚本,图像优化
缓存利用 使用CDN,使用外部JavaScript和CSS,添加Expires头,配置ETag,减少DNS查找,使AjaX可缓存
页面结构 将样式表放在顶部,将脚本放在底部,尽早刷新文档的输出
代码校验 避免重定向

减少HTTP请求

合并脚本和样式表(模块打包)

模块打包(合并文件)是通过合并所有脚本文件成单一脚本以及合并所有样式成单一样式表的方式来减少HTTP请求数目。

CSS Sprites

将背景图片合并到一张图片上,然后使用CSS背景图片和背景属性来呈现期望的图片片段。详细使用看这篇文章

按需加载资源

资源(特别是图片)的按需加载或者说惰性加载,可以有助于你的 Web 应用在整体上获得更好的性能。对于使用大量图片的页面来说惰性加载有着显著的三个好处:

  • 减少向服务器发出的并发请求数量(这就使得页面的其他部分获得更快的加载时间)
  • 减少浏览器的内存使用率(更少的图片,更少的内存)
  • 减少服务器端的负载

大体上的理念就是只在必要的时候才去加载图片或资源(如视频),比如在第一次被显示的时候,或者是在将要显示的时候对其进行加载。

图片具体怎么lazy load可看我的一篇文章

简化页面的设计

没必要花哨就少花哨。

请求带宽 (各种压缩?)

计算机网络的带宽是指网络可通过的最高数据率,即每秒多少比特。描述带宽时常常把“比特/秒”省略。例如,带宽是1M,实际上是1Mbps,这里的Mbps是指兆位/s。那到底什么是带宽呢?带宽的意义又是什么?为了更形象地理解带宽、位宽、时钟频率的关系,我们举个比较形象的例子,工人加工零件,如果一个人干,在大家单个加工速度相同的情况下,肯定不如两个人干的多,带宽就像是工人能够加工零件的总数量,位宽仿佛工人数量,时钟工作频率相当于加工单个零件的速度,位宽越宽,时钟频率越高则总线带宽越大,其好处也是显而易见的。

开启GZip

详细请参考这篇文章你真的了解 gzip 吗?

gzip压缩比率在3到10倍左右,可以大大节省服务器的网络带宽。而在实际应用中,并不是对所有文件进行压缩,通常只是压缩静态文件。

image

步骤:

1)浏览器请求url,并在request
header中设置属性accept-encoding:gzip。表明浏览器支持gzip。

2)服务器收到浏览器发送的请求之后,判断浏览器是否支持gzip,如果支持gzip,则向浏览器传送压缩过的内容,不支持则向浏览器发送未经压缩的内容。一般情况下,浏览器和服务器都支持gzip,response headers返回包含content-encoding:gzip。

3)浏览器接收到服务器的响应之后判断内容是否被压缩,如果被压缩则解压缩显示页面内容。

image

image

压缩JavaScript和CSS

压缩是从代码中去除不必要的字符进而实现减少尺寸然后缩短载入时间的惯用技巧。当所有注释被移除而且所有不需要的空白字符(空格、换行和Tab)被清除时,代码也就是mini化的啦。这种移除对于JavaScript来说,会改善响应时间性能,因为下载文件的尺寸被减小啦。
另外外部的脚本和样式、内联的以及代码块都应该被压缩。即使你使用gzip你的脚本和样式,使用Minification压缩这些脚本和样式仍然减少尺寸大小高达5%。随着JavaScript和CSS使用的人越来越多以及尺寸越来越大,因此通过压缩你的代码来获取savings。

gulp,webpack都能很方便地压缩。

移除重复脚本

一个页面中包含两个相同的JavaScript文件是很伤性能的。这个可能和你平常想的不一样。对美国排名前十的网站回顾可以发现:其中有两个网站包含废弃的脚本。两大因素 增加了在一个页面中出现脚本被重复的几率:团队的规模以及脚本的数量。当这件事确实发生了,重复的脚本通过创建可有可无的HTTP请求以及浪费JavaScript解析器资源的方式来损伤性能。
不必要的HTTP请求最开始出现在IE中,但是没有出现在FireFox。如果外部的脚本被引入两次而且没有被缓存起来。在页面加载期间,会产生两个HTTP请求。即使脚本被缓存起来,在用户进行页面重新载入时,额外的HTTP请求还是会出现。
另外产生浪费资源的HTTP请求,脚本进行多次计算时很耗时间的哦。不管脚本是否被缓存,多余的JavaScript执行环境还是会在IE和FireFox发生。
避免意外引入两个相同的脚本的方法是在你的模板系统中实现脚本管理模块。一般在页面中包含脚本的做法是在HTML页面中使用SCRIPT标签。

图像优化

这个不是很懂,反正就是看图片还有没有优化的空间(减小体积)。

缓存利用

这边主要参考张云龙大神的文章前端工程之CDN部署

image

ps:缓存利用 分类中保留了 添加Expires头 和 配置ETag 两项。或许有些人会质疑,明明这两项只要配置了服务器的相关选项就可以实现,为什么说它们难以解决呢?确实,开启这两项很容易,但开启了缓存后,我们的项目就开始面临另一个挑战: 如何更新这些缓存?
我之前实习的公司是用时间戳作为url修改的依据<script type="text/javascript" src="a.js?t=201404231826"></script>

使用CDN

浏览器缓存始终只是为了提升二次访问的速度,对于首次访问的加速,我们需要从网络层面进行优化,最常见的手段就是CDN(Content Delivery Network,内容分发网络)加速。通过将静态资源缓存到离用户很近的相同网络运营商的CDN节点上,不但能提升用户的访问速度,还能节省服务器的带宽消耗,降低负载。

不同地区的用户会访问到离自己最近的相同网络线路上的CDN节点,当请求达到CDN节点后,节点会判断自己的内容缓存是否有效,如果有效,则立即响应缓存内容给用户,从而加快响应速度。如果CDN节点的缓存失效,它会根据服务配置去我们的内容源服务器获取最新的资源响应给用户,并将内容缓存下来以便响应给后续访问的用户。因此,一个地区内只要有一个用户先加载资源,在CDN中建立了缓存,该地区的其他后续用户都能因此而受益。

使用外部JavaScript和CSS

如果JavaScript和CSS都会内联在HTML文档中,每次HTML文档被请求时,是能减少HTTP请求数目,但是增加了HTML文档的尺寸。
在现实世界中使用外部文件通常可以促成快响应页面产生,因为外部JavaScript和CSS文件会被浏览器缓存下来,如果JavaScript和CSS存在(浏览器缓存的)外部文件中,HTML尺寸会减少(且没有增加HTTP请求数目)。

添加Expires头,配置ETag

这部分属于强缓存和协商缓存,我之前已经一篇总结,这边不再展开。HTTP强缓存和协商缓存

减少DNS查找

域名系统(DNS)实现了域名和IP地址的映射,就像电话本实现了人名和电话号码的映射。当你将www.yahoo.com写进浏览器地址栏时,通过浏览器进行DNS解析然后返回服务器的IP地址。DNS是有代价的。给定的域名用DNS查询IP地址通常需要花费20-120毫秒。在DNS查询未完成之前浏览器不进行从这个网址任何下载。

为了更好的性能DNS查询是会缓存的。这个缓存机制会出现在专门的可缓存的服务器中(包括用户的ISP服务商或者本地的局域网),但是DNS查询在用户个人电脑上也会有缓存。

当客户端没有DNS缓存(浏览器和操作系统),网页里含有多少个独一无二的域名就要进行多少次DNS查询。独一无二的域名包括在页面中使用域名的URL、图片、脚本文件、样式、Flash等。

方法:减少唯一域名的数量就可以减少页面中的并行下载。避免DNS查询缩短响应时间,但是减少并行下载可能增加响应时间。我的意见是在至少2个但不多于4个域名情况下,将这些组件分离。这样实现在减少DNS查询和允许高程度的并行下载两种情况的折中。

下面是新浪微博的图片域名,我们可以看到他有多个域名,这样可以保证这些不同域名能够同时去下载图片,而不用排队。不过如果当使用的域名过多时,响应时间就会慢,因为不用响应域名时间不一致。

image

使AjaX可缓存

张云龙大神说:剩下的两项优化原则要做到并不容易,真正可缓存的Ajax在现实开发中比较少见。

那就日后有时间再补。

页面结构

将样式表放在顶部,将脚本放在底部,尽早刷新文档的输出

网页上的资源加载时从上网下顺序加载的,所以css放在页面的顶部能够优先渲染页面,让用户感觉页面加载很快。

当文档加载过程中遇到js文件,html文档会挂起渲染(加载解析渲染同步)的线程,不仅要等待文档中js文件加载完毕,还要等待解析执行完毕,才可以恢复html文档的渲染线程。因为JS有可能会修改DOM,最为经典的document.write,这意味着,在JS执行完成前,后续所有资源的下载可能是没有必要的,这是js阻塞后续资源下载的根本原因。
加载js时会对后续的资源造成阻塞,必须得等js加载完才去加载后续的文件 ,所以就把js放在页面底部最后加载。

更详细更参考这篇文章该把JS文件放在HTML文档的那个位置

代码校验

避免重定向

最浪费性能的重定向经常发生然而web开发人员通常没有意识到。当URL中本应该有正斜杠但实际上没有正斜杠(/)的时候,就会发生上面的情况。例如,去http://astrology.yahoo.com/astrology/,但是输入了http://astrology.yahoo.com/astrology(注意少了斜杠),导致301重定向,降低用户体验。

文章参考
网站性能优化35计
有没有前端性能优化知识推荐,包括css和js?
Web性能优化
前端工程与性能优化
Web前端应该从哪些方面来优化网站?
【译】唯快不破:Web 应用的 13 个优化步骤

@aermin aermin changed the title 网站性能优化 前端性能优化 Mar 14, 2018
@aermin aermin added the http label Feb 17, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant