WEB 性能优化实战

WEB 访问速度直接影响了用户体验,本文从以下几个方面对学校就业网做了简单优化,

  • 减少 HTTP 请求

  • 减少 TCP 连接

  • 启用压缩

  • 启用 HTTP 缓存

  • 静态页面缓存

优化前,首页请求总数达到 110 多个,每次请求完成时间 Finished 在 8s 左右,DOM 加载 DOMContentLoaded 在 4s 左右,页面加载 Load 在 6 秒。对页面进行优化后,首次请求如下图:

二次请求如下:

性能提高近 3 倍。

减少 HTTP 请求

减少 HTTP 请求可以间接减少 TCP 连接次数,减少页面加载时间。

使用打包工具 webpack 等可以将一个文件下的外引 JS、CSS 文件合并、压缩,也可以手动合并、压缩。

减少 TCP 连接

HTTP 是无状态连接方式,作用于网络七层的应用层,在 HTTP 1.0 版本中,每个 HTTP 请求都会发起一个 TCP 连接,TCP 连接进行三次握手,因此每个 HTTP 请求都需要等待 TCP 连接完成才能返回数据。为了减少 TCP 连接的等待时间,实现连接复用,HTTP 1.1 版本引入 keep-alive以实现 TCP 多个 HTTP 请求共享 TCP 连接通道。

对于 Apache ,只需在配置文件 httpd.conf 中加入以下代码即可启用 keep-alive,

1
2
3
KeepAlive On
MaxKeepAliveRequests 300
KeepAliveTimeout 10

KeepAlive在增加访问效率的同时,也会增加服务器的压力。因此要根据服务器性能合理设置 MaxKeepAliveRequests 和 KeepAliveTimeout 的值。可参考《KeepAlive,你优化了吗》

【备注】 keep-alive 是 HTTP 1.1 和 1.0 版本的一个差异,此外 1.1 版本还引入了 5 中 HTTP 请求方式,OPTIONS、PUT、DELETE、TRACE、CONNECT,1.1 之后又增加了一种 PATCH。详情

启用压缩

HTTP 是超文本传输协议,如果以原始文本传输,传输速度并不是最优,为了使得文本传输数据包尽可能小,HTTP 允许使用 GZIP 等方式对文本进行压缩,请求头信息中的 Accept-EncodingContent-Type控制压缩。开启 gzip 压缩以后,其体积可以减小 60%~90%,可以节省下大量的带宽与用户等待时间。

LAMP 架构中,配置 Apache 或 PHP 都可以开启 GZIP 压缩,根据情况选择其中一种方式即可,

Apache 开启 GZIP

打开配置文件 httpd.conf,找到以下模块,去掉前面的注释,

1
2
LoadModule deflate_module modules/mod_deflate.so
LoadModule headers_module modules/mod_headers.so

添加以下代码,

1
2
3
4
5
6
7
<IfModule deflate_module>
SetOutputFilter DEFLATE
SetEnvIfNoCase Request_URI .(?:gif|jpe?g|png)$ no-gzip dont-vary
SetEnvIfNoCase Request_URI .(?:exe|t?gz|zip|bz2|sit|rar)$ no-gzip dont-vary
SetEnvIfNoCase Request_URI .(?:pdf|doc|avi|mov|mp3|rm)$ no-gzip dont-vary
AddOutputFilterByType DEFLATE application/x-javascript text/html text/plain text/xml text/css
</IfModule>

PHP 开启 GZIP

PHP 开启 GZIP 可以通过修改配置文件,如果只针对特定 PHP 页面开启压缩,也可以使用 ob_start 函数

  • 修改 php.ini
    打开 PHP 目录下的 php.ini 文件,找到 zlib.output_compression = off,改为

    1
    2
    zlib.output_compression = On
    zlib.output_compression_level = -1
  • 特定 PHP 文件开启 GZIP

    1
    2
    3
    4
    5
    if (substr_count($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip')) {
    ob_start('ob_gzhandler');
    }else{
    ob_start();
    }

【备注1】 PHP GZIP 以来 zlib 模块,PHP 4.3 以后 zlib 模块内置在 PHP 中,如果没有相应模块需要编译安装。
【备注2】 为了 HTTP 性能, HTTP 2.0 版本中将使用二进制传输。

启用 HTTP 缓存

HTTP 缓存对性能的优化是相当重要的,HTTP 花费的时间主要在等待和下载上,启用缓存后使用 Last-Modified 或者 ETag 监测资源的变化,如果资源不发生改变且本地缓存不过期,资源将直接从本地取回,缩短了 HTTP 请求的时间。

对于 Apache 服务器,可以通过 mod_expires 模块来设定 Expires HTTP 头或 Cache-Contro lHTTP 头的 max-age 指令,打开 httpd.conf 搜索 expires_module,确保该模块已经引入,

1
LoadModule expires_module modules/mod_expires.so

添加以下代码,

1
2
3
4
5
6
7
8
9
10
11
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType text/css "access plus 1 week"
ExpiresByType application/javascript "access plus 2 weeks"
ExpiresByType image/x-icon "access plus 6 months"
ExpiresByType image/gif "access plus 6 months"
ExpiresByType image/png "access plus 6 months"
ExpiresByType image/jpeg "access plus 6 months"
ExpiresByType video/x-flv "access plus 6 months"
ExpiresByType application/pdf "access plus 6 months"
</IfModule>

启用 keep-alive、gzip 和 cache-cotrol 后,头信息如下


1
2
3
4
5
6
7
8
9
10
11
Accept-Ranges:bytes
Cache-Control:max-age=604800
Content-Encoding:gzip
Content-Length:12582
Content-Type:text/css
Date:Wed, 30 Aug 2017 11:51:04 GMT
ETag:"2006d7-f7b2-557cf4809c580"
Expires:Wed, 06 Sep 2017 11:51:04 GMT
Last-Modified:Mon, 28 Aug 2017 12:17:42 GMT
Server:Apache/2.2.15 (CentOS)
Vary:Accept-Encoding

静态页面缓存

对于很少变化的 PHP 页面,可以将 PHP 解析结果缓存起来,动态页面静态化,以减少数据库操作,加快响应速度。

如下案例,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$file  = "./cache/index.html";
$ctime = filectime($file);
$expr = 3600*2; //过期时间 2 小时

if(file_exists($file) && $ctime+$expr> time()) {
echo file_get_contents($file);
}else{
ob_start();
unlink($file); //删除过期的静态页文件

// 数据库操作

$content = ob_get_contents();
file_put_contents($file,$content); // 写入内容到对应静态文件中
ob_end_flush();
}

减少数据库操作

使用 Memcached 缓存

  • 安装

    1
    2
    yum install libevent libevent-deve
    yum install memcached
  • 运行

1
2
3
4
5
6
7
8
9
10
11
12
memcached -p 11211 -m 256m -vv

# 后台启动
memcached -p 11211 -m 256m -d

-d是启动一个守护进程;
-m是分配给Memcache使用的内存数量,单位是MB;
-u是运行Memcache的用户;
-l是监听的服务器IP地址,可以有多个地址;
-p是设置Memcache监听的端口,,最好是1024以上的端口;
-c是最大运行的并发连接数,默认是1024;
-P是设置保存Memcache的pid文件。
  • 在 PHP 中使用

    MySQL 数据优化

    PHP 操作数据库时,将数据缓存也是减少减小数据库压力增加响应速度的策略之一,使用 Redis 或 Memecached 可以实现。关于数据库的优化参考之前文章。

参考

本文标题:WEB 性能优化实战

文章作者:Pylon, Syncher

发布时间:2017年08月31日 - 11:08

最后更新:2023年03月11日 - 17:03

原始链接:https://0x400.com/experience/practice/frontend-web-performance-optimization/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。