zhaobinglong / myBlog

https://zhaobinglong.github.io/myBlog/
MIT License
7 stars 0 forks source link

web性能优化总览(整理这篇发布到掘金) #63

Open zhaobinglong opened 4 years ago

zhaobinglong commented 4 years ago

如何有调理的回答性能优化

web性能优化是一个非常庞大的概念,在回答这个问题的时候,涉及到很多个方面,必须要有一个原则或者是个线索来回答。我认为最好的方式是,顺着一个网页的生命周期来回答。一张网页从出现到消失,整个链路上的所有缓环节,任何一个环节为了性能做出来的调调整,都输入web性能优化的一部分

我的分类

协议层优化:输入URL开始

当浏览器中输入URL开始发起请求,第一个优化的细节,是使用http1.1协议还是http2,这是第一个优化点,http2可以提升30%请求速度,http2需要SSL协议的配合,这也是为什么一般https都是走的http2的协议。达成目标:推动产品全站https,使用http2协议

server {
        listen       443 ssl http2;
        server_name  http2.yuni.com;
}
// 淘宝网站使用http协议访问自动跳转https,为什么使用302不实用301呢?
Request URL: http://taobao.com/
Request Method: GET
Status Code: 302 Found
Remote Address: 140.205.94.189:80
Referrer Policy: strict-origin-when-cross-origin

协议层优化:HSTS可以少一次301

全站https后,诞生一个新的问题,用户访问网站的时候,是不会输入协议名字的,会直接键入域名进行访问,那如果直接域名访问,浏览器只能走http协议,在服务器端做一次301重定向,才能访问到目标网站,这一次重定向,就是一次资源的浪费。本次优化,减少了600ms左右的重定向时间

HSTS(HTTP Strict Transport Security)国际互联网工程组织IETE正在推行一种新的Web安全协议,作用是强制客户端(如浏览器)使用HTTPS与服务器创建连接。

// 用http协议访问百度首页,会发生一次302临时重定向,,为什么是临时不是永久呢?思考中
Request URL: http://baidu.com/
Request Method: GET
Status Code: 302 Moved Temporarily
Remote Address: 39.156.69.79:80
Referrer Policy: strict-origin-when-cross-origin
zhaobinglong commented 3 years ago

服务层优化:加内存和宽带

阿里云ECS服务器1M带宽1核1G带宽是当前主流的入门级服务器配置,很多用户关心它能跑多少个网站,运行多少流量。用户都希望能够把服务器用到极致。为此本文详细说说1核2G1M配置的性能和使用。

每天2000PV的访问量没问题,套上 cdn 可以跑更多,不过这时候要考虑带宽的问题,超过一定数量的话要根据实际请调整带宽了。

服务层优化:静态资源CDN

CDN的原理:CDN网络是在用户和服务器之间增加Cache层,主要是通过接管DNS实现,将用户的请求引导到Cache上获得源服务器的数据,从而降低网络的访问的速度。目标:推动全站静态资源CDN化 image

服务层优化:开启压缩

经过Gzip压缩后页面大小可以变为原来的30%甚至更小,这样,用户浏览页面的时候速度会快得多。浏览器那里不需要我们担心,因为目前的巨大多数浏览器 都支持解析Gzip过的页面。

     // 线上常用的配置
    gzip: on
    gzip_min_length  1k;  //设置允许压缩的页面最小字节数; 这里表示如果文件小于10个字节,就不用压缩,因为没有意义,本来就很小.
    gzip_buffers     4 16k; // #设置压缩缓冲区大小,此处设置为4个16K内存作为压缩结果流缓存
    gzip_http_version 1.1; // #压缩版本
    gzip_comp_level  6; //  #设置压缩比率,等级1-9,一般折中为6
    gzip_types       text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php application/javascript application/json;
    gzip_disable "MSIE [1-6]\."; // #配置禁用gzip条件,支持正则。此处表示ie6及以下不启用gzip(因为ie低版本不支持)
    gzip_vary on;

两类资源不适合压缩

1) 图片类型资源 (还有视频文件) 原因:图片如jpg、png文件本身就会有压缩,所以就算开启gzip后,压缩前和压缩后大小没有多大区别,所以开启了反而会白白的浪费资源。(可以试试将一张jpg图片压缩为zip,观察大小并没有多大的变化。虽然zip和gzip算法不一样,但是可以看出压缩图片的价值并不大)

2) 大文件资源 原因:会消耗大量的cpu资源,且不一定有明显的效果。

服务层优化

nginx开启负载均衡

zhaobinglong commented 3 years ago

数据库层优化:redis缓存

数据库层优化:查询优化

数据库层优化:物理设备优化

mysql的并发和性能依赖缓存和磁盘IO。磁盘io限制比较大,目前主流的SD硬盘读写速度约500MB/s

zhaobinglong commented 3 years ago

代码层优化:提前加载CSS资源异步加载 JavaScript 资源

异步的 JavaScript 资源不会阻塞文档解析,所以允许在浏览器中优先渲染页面,延后加载脚本执行。例如: 使用 async 时,加载和渲染后续文档元素的过程和 main.js 的加载与执行是并行的。 使用 defer 时,加载后续文档元素的过程和 main.js 的加载是并行的,但是 main.js 的执行要在页面所有元素解析完成之后才开始执行。

<link src="xxxx">
<script src="main.js" defer></script>   // 用它,异步加载,执行要等待所有的脚本load后才执行
<script src="main.js" async></script>  // 不要用async,因为它是异步,但是没有时许的概念,适合不依赖任何脚本执行的,比如百度统计、谷歌分析
<body>
  xxxx
</body>

link:https://segmentfault.com/q/1010000000640869

代码层优化:DNS预解析

DNS 作为互联网的基础协议,其解析的速度似乎很容易被网站优化人员忽视。现在大多数新浏览器已经针对DNS解析进行了优化,典型的一次DNS解析需要耗费 20-120 毫秒,减少DNS解析时间和次数是个很好的优化方式。

DNS Prefetching 是让具有此属性的域名不需要用户点击链接就在后台解析,而域名解析和内容载入是串行的网络操作,所以这个方式能 减少用户的等待时间,提升用户体验 。

这样可以极大的加速(尤其是移动网络环境下)页面的加载。在某些图片较多的页面中,在发起图片加载请求之前预先把域名解析好将会有至少 5% 的图片加载速度提升。

<meta http-equiv="x-dns-prefetch-control" content="on">
<link rel="dns-prefetch" href="//www.zhix.net">
<link rel="dns-prefetch" href="//api.share.zhix.net">
<link rel="dns-prefetch" href="//bdimg.share.zhix.net">

代码层优化:资源预加载prefetch和preload

// 
<link rel="preload" href="/main.js" as="script">
<link rel="prefetch" href="main.js">
zhaobinglong commented 3 years ago

代码层优化:CSS解析优化

css样式规则的匹配是从右边往左边解析

// good
.a .b .c .d {color: red}

// bad
.d {color: red}

内联首屏关键CSS(Critical CSS)

性能优化中有一个重要的指标—— 首次有效绘制(First Meaningful Paint,简称FMP) 即指页面的首要内容(primary content)出现在屏幕上的时间。这一指标影响用户看到页面前所需等待的时间,而内联首屏关键CSS(即Critical CSS,可以称之为首屏关键CSS)能减少这一时间。

如何确定首屏关键CSS了。显然,我们不需要手动确定哪些内容是首屏关键CSS。Github上有一个项目Critical CSS4,可以将属于首屏的关键样式提取出来,大家可以看一下该项目,结合自己的构建工具进行使用。当然为了保证正确,大家最好再亲自确认下提取出的内容是否有缺失。

不过内联CSS有一个缺点,内联之后的CSS不会进行缓存,每次都会重新下载。不过如上所说,如果我们将内联后的文件大小控制在了14.6kb以内,这似乎并不是什么大问题。

link:https://github.com/filamentgroup/criticalCSS

代码层优化:减少重排

下面的行为都会导致浏览器发生重排

代码层优化:不要使用@import引入CSS

不建议使用@import主要有以下两点原因。

  1. 首先,使用@import引入CSS会影响浏览器的并行下载。使用@import引用的CSS文件只有在引用它的那个css文件被下载、解析之后,浏览器才会知道还有另外一个css需要下载,这时才去下载,然后下载后开始解析、构建render tree等一系列操作。这就导致浏览器无法并行下载所需的样式文件。

  2. 其次,多个@import会导致下载顺序紊乱。在IE中,@import会引发资源文件的下载顺序被打乱,即排列在@import后面的js文件先于@import下载,并且打乱甚至破坏@import自身的并行下载。

所以不要使用这一方法,使用link标签就行了。

代码层优化:transtion动画效果优先选择transform,尽量不使用height,width,margin和padding

在使用css3 transtion做动画效果时,transform实现的动画是与合成器线程相关的,不需要主线程样式计算或者 JS 执行,计算速度是很快的;而使用height,width,margin和padding时,导致布局和绘制的调整,主线程需要重新计算样式并且执行JS,计算速度自然就慢了。

transform比margin性能好50%~70%。

代码层优化:css书写规则

zhaobinglong commented 3 years ago

代码层优化:img标签避免src为空

// src为空的情况下,浏览器依然会发起请求
<img src="">

代码层优化:使用压缩率更大的图片资源

from:#94

zhaobinglong commented 3 years ago

浏览器层优化:多域名并发请求

实际上,浏览器确实使用并行连接,但它们将并行连接的总数限制为少量(通常为四个)。服务器可以自由地关闭来自特定客户端的过多连接。一些主流浏览器对单一域名的最大并发连接数目,大部分都是六个并发,六个之外的请求都要等。所以这里的优化手段可以使用多域名的方式,将静态资源使用多个独立的域名来提供

多域名会引发域名收敛的问题,所以不能无限制的多

浏览器层优化:减少cookie或者没有cookie

请求静态资源的时候,使用独立的域名,浏览器因为通源策略的原因,就不会携带cookie

Request URL: https://img.alicdn.com/bao/uploaded/TB1WgndFVXXXXc1XpXXwu0bFXXX.png_170x170q90.jpg
Request Method: GET
Status Code: 200 
Remote Address: 116.77.238.123:443
Referrer Policy: strict-origin-when-cross-origin

浏览器层优化:缓存!

  1. 添加Expires头和Cache-Control Expires头,浏览器端根据过期时间选择是否加载最新的版本。缺点是:需要服务器和客户端时间的严格同步, HTTP1.1引入了Cache-Control头来克服Expires头的限制。Cache-Control使用max-age制定组件被缓存多久,使用秒为单位,例如Cache-Control:max-age=3600;表示组件将被缓存60分钟。如果max-age和Expires同时出现,则max-age有更高的优先级,浏览器会根据max-age的时间来确认缓存过期时间。
  2. Last-Modified 在上次传输中,服务器给浏览器发送了Last-Modified或Etag数据,再次浏览时浏览器将提交这些数据到服务器,验证本地版本是否最新的,如果为最新的则服务器返回304代码,告诉浏览器直接使用本地版本,否则下载新版本。一般来说,有且只有静态文件,服务器端才会给出这些数据。

浏览器层优化:减少http请求