页面加载速度-合并资源文件

前言

一直觉得自己的博客站点页面加载很慢, 就想着去优化一下. 呐, 下图是一次文章页面的加载, 需要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%的加载时间, 而这, 还仅仅是通过合并资源文件来实现的. 想象平常我们究竟为了这玩意浪费了多少用户的时间啊.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/508352.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

hbase/thrift/go连接失败

问题 在通过Go连接hbase的过程中, 发现 get操作可以查到数据, 但是scanner命令访问数据失败, 也没有报错, 就是单纯的查不到数据. 而且Python PHP都一切正常. 这里简单复述一下我出现问题的情况, 安装过程和网上大部分内容一致, 这里简单列一下, 只是为了查询问题时参考安装过…

常用搜索引擎及语法

在平常需要进行搜索的时候是不是只知道Google Baidu ?? 他们其实是全文搜索引擎, 还有一些特定领域的搜索引擎. 而且, 搜索时可以添加特定语法, 让你的搜索事半功倍. 本文整理各种场景下使用的搜索引擎, 以及各个搜索引擎支持的语法, 不定期进行更新. 如果你知道其他搜索引…

自旋锁与互斥锁

前言 在编程中经常需要使用到互斥. 互斥就是, 这个事情只能有一个人干, 我正在做着的时候, 别人要想做这件事就得等我做完了. 互斥的实现是通过锁的机制, 也就是我把这块锁上了, 别人就进不来了, 等我做完再把锁释放掉. 但是, 前辈们已经证明了, 要想单纯的在软件层面上实现…

printf缓冲区踩坑

问题 碰到了这样一段代码(经过简化的): #include "stdio.h" #include "unistd.h" #include "sys/wait.h"int main(){fork();printf("1\n");fork();printf("1\n");wait(NULL);return 0; }这里我们简单算一下, 结果会打印几…

进程切换时是如何保存上下文的

前言 当前操作系统大部分采用分时的进程调度, 既每个进程运行一小段时间, 然后切换到下一个进程运行, 依次往复. 当进程运行的时候是独占CPU的, 此时操作系统是无法强行介入的, 为了将执行权让出来, 就需要硬件的配合了. 硬件每个一个时钟周期(比如10ms), 就会产生一个时钟中…

GO/testing包

前言 之前在写GO单元测试的时候, 使用了这个结构testing.T. 进来无事翻了翻, 发现testing包中还有一些其他的结构体, 想来是不同用处. 没想到GO的testing包竟然默默做了这么多支持, 之前竟然不知道. 在testing包中包含一下结构体: testing.T: 这就是我们平常使用的单元测试t…

CPU的分支预测

前言 最近在进行性能调优的时候, 碰到了这样的一段代码(为了展示问题而简化的代码): <?php // 第一次运行 $start microtime(true); for ($i 0; $i < 100; $i) {for ($j 0; $j <1000; $j) {for ($k 0;$k < 10000; $k) {}} } $end microtime(true); echo fi…

Golang Context 简介

前言 在写Golang程序调用各种第三方库的时候, 经常会传一个叫做Context的参数. 之前基本上见到接Context, 根本不管是干什么用的, 直接无脑context.Background(). 但是, 传着传着就不免发生一些小疑问, 这个参数到底是干什么用的呢? 这么多库都在使用, 至少说明其是Golang中…

PHP获取Opcode及C源码

是什么 在开始之前, 必须要先介绍一下Opcode是什么. 众所周知, Java在执行的时候, 会将.java后缀的文件预先编译为.class字节码文件, JVM加载字节码文件进行解释执行. 而字节码文件存在的意义, 就是为了加速执行. 那么PHP的Opcode与之类似, 也是从.php文件到执行的过程中, 所…

PHP require/include 区别

前言 在PHP中, 载入文件可以选择使用require, 也可以使用include, 那么那他们有什么区别呢? 看了网上的一些文章, 说他们使用场景不同, require一般在文件开头引入文件, include一般在函数中动态引入文件. 但是我觉得并不是这么简单, require是作为语言结构(关键字)出现的, …

RESTful API规范

前言 我现在工作的公司是在毕业前实习的公司, 实习结束后直接转正, 因此也是我任职过的唯一一家公司. 在日常工作进行 HTTP 接口的开发时, 发现了一个疑惑, 只用到了POST和GET请求, 但我们知道 HTTP还有PUT/DELETE等等, 为什么不用呢? 并且, 接口的响应码也只有200, 接口是…

Golang 接口原理

问题 小提示, 若想直接查看原理, 可从接口原理开始查看. 有这样一段GO代码: func main() {var obj interface{}fmt.Printf("obj nil. %b\n", obj nil)type st struct{}var s *stobj sfmt.Printf("s nil. %b\n", s nil)fmt.Printf("obj nil. …

Docker kill 1无效

前言 我们在平常强制停用一个进程的时候, 会选择什么命令? 一般在测试使, 不考虑程序突然中断带来的影响, 直接使用kill -9 pid强制停止就行. 但是, 就在刚刚, 我启动了一个docker容器, 进入容器后执行命令kill -9 1没有任何效果??? 啊这, 为什么呀? 尝试 为了解释这个…

容器内存相关知识

这篇文章是我研究容器内存整理出的相关内容. 前后内容并没有上下文关系, 每个知识点都可以单独查看. 内存控制 使用这样的命令启动一个容器docker run -d -m 300M xxx. 可以限制容器使用的内存最大为300M. 那么docker是如何实现容器的内存限制呢? 其实是操作系统已经做好了…

三星识别文字_比亚迪电子助力三星Galaxy Note 10系列霸气首发!

三星有子初长成气宇轩昂 秀美俊逸减之一分则嫌柔增之一分则嫌赘2019年8月7日于纽约巴克莱发布Galaxy Note 10系列用简约 重构美三星Galaxy Note 10与Galaxy Note 10分别搭载了6.3英寸和6.8英寸的超感官全视曲面屏&#xff0c;均采用单摄挖孔屏&#xff0c;开孔位于屏幕正上方。…

lisp 设计盘形齿轮铣刀_机械设计基础——周转轮系传动比的计算

点击上方蓝色字体&#xff0c;关注我们15(视频来源于网络&#xff0c;仅供学习交流&#xff0c;侵权请联系删除)机械计重点学习指导机械原理全书重点提要轴的结构改错机械设计作业集01机械设计作业集02机械设计作业集答案机械原理作业集机械原理作业集答案轴的强度计算院校推荐…

b+树阶怎么确定_B站公布年度弹幕,这个排名我不太服气

也忘记了是从什么时候开始&#xff0c;B站开始公布自己的年度弹幕了&#xff0c;今年的年度弹幕排名前五的分别是&#xff1a;爷青回、武汉加油、有内味了、双厨狂喜、禁止套娃。话说今年真的是不容易啊&#xff0c;过年那段时间以及上半年不会忘记那一幕幕感人深邃的瞬间&…

css打印适应纸张_从生态平衡到打印机故障分析

生态平衡(ecological equilibrium)是指在一定时间内生态系统中的生物和环境之间、生物各个种群之间&#xff0c;通过能量流动、物质循环和信息传递&#xff0c;使它们相互之间达到高度适应、协调和统一的状态。也就是说当生态系统处于平衡状态时&#xff0c;系统内各组成成分之…

html5调用系统声音1s响一次_20款奔驰GLC260提车改柏林之声音响,音乐诉请,为爱发声!...

奔驰GLC车型在2020上半年可谓是风生水起&#xff0c;尤其是2020年1-5月份的豪华品牌SUV排名中&#xff0c;奔驰GLC车型以58982的销售量遥遥领先&#xff0c;同比增长了2%&#xff0c;奔驰GLC5月销量高达15275辆&#xff0c;再次打败老对手奥迪Q5L&#xff0c;夺得豪华SUV销量冠…

js排序的时间复杂度_冒泡排序最好时间复杂度为什么是O

展开全部冒泡排序的基本思想是&#xff0c;对相邻的元素进行两两比较&#xff0c;顺序相反则进行交换&#xff0c;这样&#xff0c;每一趟会e68a8462616964757a686964616f31333433616161将最小或最大的元素“浮”到顶端&#xff0c;最终达到完全有序代码实现在冒泡排序的过程中…