网站优化,提升网站速度
也会因此而感谢你,当然他们可能压根没注意到你的网站速度加快了——这是好事。
在这篇文章里,我会告诉你一些提升网站速度的方法。
我们开始吧。
基准
首先,用你的网站来做示例。
你需要使用 Google 的 Pagespeed Insights 网站测试工具来测试你的网站,它会告诉你,你的网站需要优化移动端还是桌面端。
Google 基于网页的渲染速度来打分。它会计算你的网站需要多久呈现到用户眼前。用户等待的时间越长,网站的得分就越低。
我对 Google 的 Pagespeed Insights 测试工具的主要不满在于它太慢了。可以说是……难以忍受的慢。
如何解决呢?
Lighthouse。
使用 Lighthouse
你可以通过 npm
下载 Lighthouse
到电脑上。它实际上是一个功能更强大的Pagespeed Insights
测试工具(Pagespeed Insights
是基于 Lighthouse
实现的)。
当你在本地使用它时,测试生成的所有信息都可以保存下来。
使用方法如下:
- 下载
npm install -g lighthouse
此外需要确保已经下载了某些版本的 Google Chrome
。
- 接下来你就可以使用它并生成测试结果了:
lighthouse https://www.xxxx.com
--view 会在你的默认浏览器中打开测试结果。以下是我之前使用 Lighthouse 测试的结果:
lighthouse是直接集成到chrome开发者工具中的,位于Audits
面板下。
首先,你得下载安装 了chrome浏览器,相信每个做开发的人员都应该拥有chrome浏览器。
其次,在chrome浏览器中打开你需要测试的网站,按f12进入开发者调试模式,点击Audits
选项
当然,前提是你有个梯子
测试结果不仅包括性能得分,还包括可访问性、最佳实践和 SEO 建议。它的不足之处是每次只能测试一个页面。我建议你测试内容较多的页面,这样一来,你测得的就是网站中性能最差的一页的结果。当你修复了最差的页面,整个网站的性能也会得到大幅提升。
图一 CPANEL,图二BACKSTAGE,图三JOYNOP.COM(本站)
性能量化
下列举了基本的性能指标,并且给出页面加载时间的概览。
First meaningful paint——这代表用户看到初始内容所需的时间。请尽量让它的值小于1秒。
First interactive——这代表可交互元素从展示到响应所需的时间。
Perceptual Speed Index——这是页面展示可见部分所需时间的平均值。它以毫秒为单位并且取决于窗口的大小。应该尽量让它减少到1250毫秒以内。
Estimated Input Latency——这是网页响应用户输入所需的毫秒数。
Opportunities——这一部分包含更多的性能细节,将图片、CSS和响应时间的信息都聚合起来了。下面我会逐个讲解并且给出改良策略。
Reduce render-blocking stylesheets
下载CSS文件会阻塞浏览器的渲染过程。也就是说,浏览器会等到CSS文件下载完后才开始渲染内容。比如说你使用了bootstrap,但在项目才启动的时候,你并不需要加载整个组件库来美化你的页面。对此,最简单的处理方法就是只加载必要的CSS文件。
接着,你希望针对不同的屏幕尺寸进行优化。为了减少加载的CSS数量,你可以使用选择性加载的方式,只加载当前屏幕需要的CSS文件。就像下面的代码:
<link href="other.css" rel="stylesheet" media="(min-width: 40em)">
<link href="print.css" rel="stylesheet" media="print">
如果这还没有完全解决你的问题, 在不阻塞页面渲染的情况下加载CSS文件。这个技巧使用了一个媒体查询为无效值的link元素。当媒体查询的计算结果为false时,浏览器仍然会下载样式表,但是不会延迟页面的渲染。你可以把必需的CSS文件分离出来然后再下载它们。
Keep server response times low
减少请求数的重要性不言而喻,但我们仍然要经常提醒自己,不要忘记它。为了减少服务器响应次数,你可以考虑使用CDN存放部分资源文件。还可以使用HTTP2协议、删除不必要的请求或是渲染页面后再懒加载资源等等。
Properly size Images, Offscreen images 和 next-gen formats
这三个部分都属于图片优化这一类。你可以在Network标签中通过筛选IMG来获取实际加载了哪些图片以及它们的体积大小。现在只看Size和Time这两列的数据,看看你是否满意这样的结果。目前还没有普适的标准规定每个文件应该有多大,这完全依赖于客户端设备种类、客户群体和其他你能想到的所有因素。
查看加载的图片
关于图片优化我还想再补充几点,因为这个问题在Audit的结果报告中会多次出现。
图片优化
图片分为两类:位图和矢量图。一个位图由像素构成,往往被用来展示图片和复制的动画。比如jpg、jpeg和gif格式。
矢量图由图形组成,被用来展示logo和图标。因为它们在缩放时也能有优异的表现。比如svg。
SVG
SVG本身体积已经很小了,但是你还可以通过压缩让它们更小:
SvgOmg
Svg-optimiser
位图
由于位图的体积较大,所以要用的优化技巧会多一些。下面是一些让位图保持较大尺寸但又有较小体积的黑科技。
事前准备
在优化前请先准备好不同版本的图片。我想你不希望在普通手机上展示适用于retina屏幕的图片吧?先准备个三四种版本。手机版、平板、桌面版。它们的尺寸取决于你的目标设备。如果你不清楚目标设备属于这四种中的哪一个,可以参考这个链接。
Srcset属性
图片都准备好了吗?img标签的src属性能够帮助我们决定什么时候加载图片。
<img src="ing.jpg" srcset="img.jpg, img2x.jpg 2x" alt="img">
设置src是防止浏览器不支持srcset属性,而srcset是为了那些支持该属性的浏览器。img2x.jpg是为了适配dpr = 2的retina屏幕。
<img src="img.jpg" srcset="img1024.jpg 1024w, img2048.jpg 2048w" alt="img">
设置src是防止浏览器不支持srcset属性,而srcset是为了那些支持该属性的浏览器。img1024是为了适配宽度为1024像素的屏幕。
上面引用的是MDN的两个例子。
媒体查询
你也可以使用媒体查询,比如说根据平板或手机使用不同的样式。这种方法最好与CSS预处理配合使用。
作为srcset属性的替代品,媒体查询的规则是写在CSS样式中,而不是写在HTML文件里。在单纯的CSS文件里,这种方法往往事倍功半。但如果你使用CSS预处理提供的mixin和变量的话,效率就会非常高了。当然,是使用srcset还是媒体查询都随你意。
@desktop: ~"only screen and (min-width: 960px) and (max-width: 1199px)";
@tablet: ~"only screen and (min-width: 720px) and (max-width: 959px)";
@media @desktop {
footer {
width: 940px;
}
}
@media @tablet {
footer {
width: 768px;
}
}
CDN
当准备好图片资源并且代码优化后,你需要考虑分发的问题。像Cloudinary这样的工具能够有效地降低响应延时。它们的服务器遍布全球,所以能够快速分发数据。HTTP协议限制用户每次只能向一个服务器并行发送6个请求,而使用CDN的话你能发送的请求数是它的数倍。
懒加载
有的图片色彩更饱满但体积也更大。如果你的网站还有很高的加载延迟,可以试试blurry image或是懒加载。
懒加载能够让图片按需加载。如果一个画廊有1000张图片,那么这些图片并不需要一开始就被下载好。我们可以先加载前十张图片,然后在用户想要查看时再加载剩下的。
关于懒加载的第三方库实在是太多了。
优化网络字体
之前我们提到过CSS优化,那么现在再来聊聊网络字体的优化。
在我们的网站中,往往会使用到EOT、TTF、WOFF或WOFF2格式的字体文件。
由于没有统一的标准格式,所以对于每个浏览器我们都需要使用一种不同的字体文件来适配。关于这个问题你可以看看这篇文章。在此之前,你可以先问问自己是否真的需要使用网络字体。这个答案也许可以在这篇文章中找到。
字体压缩
字体是图形和路径的集合,这个集合帮助我们生成字母和文字。幸运的是,每一个不同的字母都有相似的地方,所以我们可以对它们进行压缩。
由于EOT和TTF格式默认是未压缩的,所以确保你的服务器已经开启GZIP配置。
WOFF是内置了压缩功能的,所以在你的服务器上请使用最优压缩方式。
WOFF2则有预处理机制。
限制字符集
如果你的网站语言是英文,那么没必要引入阿拉伯或希腊文。你也可以使用unicode字符集,这样可以让浏览器将大的unicode字体拆分成一个一个子集。
字体加载策略
由于浏览器在构建DOM时需要使用到字体,因此加载字体文件也会阻塞页面的渲染。
合理地使用字体加载策略能够降低加载的延迟。CSS属性font-display就是一种字体加载策略。
JavaScript优化
减少引入不必要的依赖
目前,ES6的模块机制让Webpack和Gulp被广泛使用。当项目中需要使用第三方库时,切记你需要的只是整个库中的一小部分。所以当你不需要lodash的全部功能时,你可以只导入需要的函数:
import _ from 'lodash';——整个lodash库都会被打包
import {map} from 'lodash';——这也会打包整个lodash模块。你可以使用lodash-webpack-plugin
或babel-plugin-lodash
等插件。
import map from 'lodash/map';——这样只会打包map模块
仔细检查你使用的框架中有哪些原生方法与ES6方法。有时候你并不需要针对每个功能都引入一个不同的库。你可以使用下面链接中的工具检查bundle包是如何生成的。
Webpack bundle analyzer
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。
评论已关闭