IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> PHP知识库 -> 页面加载速度-合并资源文件 -> 正文阅读

[PHP知识库]页面加载速度-合并资源文件

前言

一直觉得自己的博客站点页面加载很慢, 就想着去优化一下. 呐, 下图是一次文章页面的加载, 需要2.5s. 其中 js 文件就有18个. 众所周知, 浏览器对资源文件的并行下载数量是有限制的(不同浏览器限制不同). 也就是说, 这18个 js 文件是无法同时下载的, 再说了, 页面中还有其他资源文件, 因此. 减少资源文件的数量, 就可以提高页面的加载速度.

image-20220409161419851

合并 js 文件

首先, 尝试将页面的 js 文件进行合并. 这里我使用了比较通用的方法, 正则匹配. 因此需要的话, 你大概率也可以使用:

<?php 
// 开启页面缓冲
ob_start(function($content){
  // 根据正则表达式, 将特定部分的 js 内容进行提取
  $mergePatternJsData = function ($content, $pattern, $replaceStr){
    // 没有找到匹配的内容
    $noMatch = fn() =>  str_replace($replaceStr, "", $content);
    // 将内容进行匹配提取
    preg_match($pattern, $content, $matches);
    if(empty($matches[0])) return $noMatch();
    // 匹配其中的 js 文件
    $pattern = "/<script\s*src='(.*)'.*><\/script>/U";
    preg_match_all($pattern, $matches[0], $itemMatch);
    // 这里对页面中的部分 js 文件进行过滤
    // 因为一些 js 文件中使用相对位置引入了其他资源文件
    // 因此若是将其链接挪走了, 会导致引入资源文件失败
    $itemMatch = fileCantMergeFile($itemMatch);
    if(empty($itemMatch[0])) return $noMatch();
    // 将匹配到的 js 文件进行合并, 并返回合并后的链接
    $replaceUrl = self::mergeResData($itemMatch[1]);
    // 将原本的 js 内容去掉
    $content = str_replace($itemMatch[0], '', $content);
    //  替换新的 js 文件
    return str_replace($replaceStr, "<script src='{$replaceUrl}'></script>", $content);
  };
  // JS_REPLACE_HEAD_STR/JS_REPLACE_FOOTER_STR 是提前在 header/footer 中放好的等待替换的字符串. 这里简单处理了, 其他处理方式也是可以的
  // 这里说一下为什么 head 和 body 中的 js 资源不能进行合并
  // 因为资源文件的加载时机不同, 因此不能进行合并
  
  // 匹配 header 中的 js 文件
  $headerPattern = '/<head>[\S\s]*<\/head>/U';
  $content = $mergePatternJsData($content, $headerPattern, self::JS_REPLACE_HEAD_STR);
  // 匹配 body 中的 js
  $bodyPattern = '/<body[\s>][\S\s]*<\/body>/U';
  return $mergePatternJsData($content, $bodyPattern, self::JS_REPLACE_FOOTER_STR);
});

function mergeResData($urlList){
    if(empty($urlList)) return null;
    $workPath = __DIR__; // 项目路径, 自行修改
    // 保存缓存文件的路径, 相对于项目的相对路径
    // 这一, 这个路径要 nginx 可访问哦
    $relativePath = ''; 
    // 获取合并后的本地缓存 js 文件
    $filename = md5(implode('', $urlList)).'.js';
    $filepath = "{$workPath}/{$relativePath}/{$filename}";
    // 若缓存文件已经存在直接返回, 这里没有考虑 js 文件更新的情况. 若需要的话, 请自行处理
    if(!file_exists($filepath)){ // 创建文件
        // 提取所有文件的内容合集
        $allContent = '';
        foreach ($urlList as $itemUrl){
            $allContent .= PHP_EOL.file_get_contents($workPath.parse_url($itemUrl, PHP_URL_PATH));
        }
        $dirname = dirname($filepath);
        if(!is_dir($dirname)) mkdir($dirname, 0777, true);
        file_put_contents($filepath, $allContent);
    }
    return "http://xxx.com/{$relativePath}/{$filename}";
}

如此一来, 就可以将页面中的 js 文件数量降低为2个了. 看一下效果, 效果还是十分显著的, js 数量减少了12个(多出来的是由 js 文件引入的 js), 时间减少了差不多0.9s

image-20220409164818816

合并 css

既然 js 文件可以合并, 那么自然, css 也能够合并. 合并的代码拿上面的改改就出来了. 这里直接上效果

在合并之前, css 文件9个. 合并后为2个(因为其中一个使用了相对路径), 时间减少了差不多0.1s 左右. 这里是因为 css 文件数量不多, 且文件本身较小, 所以效果没有 js 那么明显.

image-20220409165403007

js 和 css 都进行了合并, 难道就完了么? 不. 我们还可以对其进行压缩.

压缩 js/css

找到了这个库: mrclay/minify . 直接composer require mrclay/minify 引进来就行.

使用如下方法在将内容写入到缓存文件时, 对其进行压缩:

<?php
// 压缩 js 内容
$allContent = JSMin::minify($allContent)
// 压缩 css 内容
$allContent = Minify_CSSmin::minify($allContent)

这里, 因为加载的 js 和 css 本身大部分就已经是压缩过的了, 因此效果并不是那么明显. 时间仅减少了0.1s. 若是 资源文件本身没有压缩, 效果会更明显.

image-20220409165909085

最终

最终效果, 页面的加载时间从原本的2.5s, 降低到了1.4s. 当然, 不同的网络环境, 时间也会不同, 但这也减少了差不多45%的加载时间, 而这, 还仅仅是通过合并资源文件来实现的. 想象平常我们究竟为了这玩意浪费了多少用户的时间啊.

  PHP知识库 最新文章
Laravel 下实现 Google 2fa 验证
UUCTF WP
DASCTF10月 web
XAMPP任意命令执行提升权限漏洞(CVE-2020-
[GYCTF2020]Easyphp
iwebsec靶场 代码执行关卡通关笔记
多个线程同步执行,多个线程依次执行,多个
php 没事记录下常用方法 (TP5.1)
php之jwt
2021-09-18
上一篇文章      下一篇文章      查看所有文章
加:2022-04-13 22:06:44  更:2022-04-13 22:15:52 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/18 17:33:50-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码