无需插件即可优化网页速度--专业人士的手动措施

我在不使用插件的情况下,通过人工干预来优化 wordpress 的速度,从而明显缩短加载时间,并可靠地达到网站的核心要求。这就是我如何控制 要求资源和副作用,从源头上消除镇流器。

中心点

  • 图片 上传前持续压缩并转换为 WebP 格式
  • 懒加载 本机通过 HTML 属性,而不是重载扩展
  • 缓存 通过 .htaccess/server 和清洁页眉策略
  • 代码 最小化、捆绑并避免渲染阻塞程序
  • 镇流器 删除 WordPress、数据库和主题

我为什么不使用插件进行优化

插件看似方便,但它们添加的请求、脚本和样式会阻塞初始呈现路径,使我的 TTFB 恶化。每增加一个依赖关系,都会增加误差面,增加分析性能下降原因的难度。我使用人工措施来减少负载链,尽量减少活动组件的数量。这让我能够减少开销,保持灵活性,并更快地对新需求做出反应。这种方法可以防止更新链带来的副作用,并将维护工作保持在最低水平。 苗条.

让图像纤薄格式、大小、压缩

大图像不会扼杀第一字节所需时间,但它们会影响传输时间和 LCP,因此我减少了每项资产 事先.我将照片导出为 JPEG 或 WebP 格式,只有真正的透明照片才使用 PNG 格式。我将尺寸精确缩放至所需的视口宽度,而不是在 800px 已经足够的情况下再加载 4000px。然后,我会使用 Squoosh、ImageOptim 或 Photoshop 进行一致的压缩,并检查是否有可见的伪影。对于响应式变体,我依赖于 srcset/sizes,并喜欢使用以下短语 响应式图像指南这样浏览器就会自动加载最小的有意义的源代码,而我的 数据传输 减少。

本地使用懒加载

我只在图像和 iFrame 进入视口时通过 HTML5 本地加载它们,而不是集成额外的脚本,这意味着 主线 加载。在现代浏览器中,loading="lazy "属性完全足够。通过这种方式,我减少了初始字节数,并均衡了关键的渲染阶段。同时,控件保持透明,我可以决定哪些折叠上方的元素需要急于加载。关键的英雄图像使用 loading="expire",其他图像则使用 loading 胶印.

<img src="beispiel.jpg" alt="图片示例" loading="lazy">
<iframe src="video.html" title="录像" loading="lazy"></iframe>

有针对性地加快 LCP:优先事项和占位符

为了提高 "最大内容油漆 "的稳定性,我明确标记了最大的折叠元素。图片被赋予 fetchpriority="high"(高优先级)和定义的尺寸,这样浏览器就会优先选择它们,并且 CLS 避免。如有必要,我会在路径畅通的情况下增加预加载。

<!-- LCP-Image priorisieren -->
<link rel="preload" as="image" href="/assets/hero.webp" imagesrcset="/assets/hero-800.webp 800w, /assets/hero-1200.webp 1200w" imagesizes="(min-width: 800px) 1200px, 100vw">
<img src="/assets/hero-800.webp"
     srcset="/assets/hero-800.webp 800w, /assets/hero-1200.webp 1200w"
     sizes="(min-width: 800px) 1200px, 100vw"
     width="1200" height="700"
     fetchpriority="high"
     loading="eager"
     decoding="async"
     alt="英雄">

对于图像和容器,我会设置宽度/高度或 长宽比来排除布局跳跃。对于非关键区域,我使用 content-visibility: autocontain-intrinsic-size以便浏览器稍后在不移动布局的情况下渲染视口以外的区域。

/* 保留在折叠上方 */
.hero { aspect-ratio: 12 / 7; }

/* 稍后布局不可见部分 */
.section { content-visibility: auto; contain-intrinsic-size: 1000px; }

专门配置浏览器缓存

重复访问者应从缓存中加载静态资产,因此我直接在服务器级别通过以下方式设置过期时间 .htaccess 或 vHost 中。图像的 TTL 较长,CSS/JS 的 TTL 适中,HTML 的默认值较短,这样可以兼顾及时性和速度。我注重文件版本的一致性,因此尽管 TTL 较长,更新也能立即生效。与 ETags 或 Last-Modified 标头相结合,可以大大减少流量。这样既节省了带宽,又缩短了用户对网站的感知时间。 载入时间.

过期激活
  ExpiresActive 开
  ExpiresByType image/jpg "访问加 1 年" ExpiresByType image/jpeg "访问加 1 年" ExpiresActive On
  ExpiresByType image/jpeg "access plus 1 year" 过期日期
  ExpiresByType image/gif "access plus 1 year" 过期时间
  ExpiresByType image/png "access plus 1 year" 过期时间
  ExpiresByType text/css "访问权限加1个月"
  ExpiresByType application/pdf "访问权限加1个月"
  ExpiresByType text/javascript "access plus 1 month" 过期时间
  ExpiresByType application/x-javascript "访问一个月"
  ExpiresDefault "访问加 2 天"

缓存策略、版本和重新验证

我将长 TTL 与文件名散列结合起来,这样客户端就能缓存相同的时间 (style.9c2a.css),更新会立即生效。对于频繁更改的捆绑包,我设置 Cache-Control: public, max-age=31536000, immutable而 HTML 短 no-cache-策略。对于动态答案,我更喜欢 有条件的申请 通过 ETag最后修改这样,客户就很少重新验证:

页眉设置 Cache-Control "public, max-age=31536000, immutable"
  
  
    页眉设置 Cache-Control "no-cache, no-store, must-revalidate"

对于格式不同的内容(如 WebP 与 JPEG),我会检查 可变: 接受 在 Edge 上设置正确;这样可以防止缓存中出现错误的版本。我通过构建管道保持版本的一致性,这样就不会有资产以不受控制的方式过时。

简化 CSS 和 JavaScript

我在构建过程中对 CSS/JS 进行了本地最小化,并删除了注释、空格和未使用的 选择器.我将重要的样式打包为内嵌式,其余的以异步或延迟文件的方式加载。我将阻塞渲染的脚本移到最后,为其添加延迟/同步,并保持较少的外部库数量。对于框架,我会检查树的晃动和导入范围,这样就不会加载所有我很少使用的东西。在可能的情况下,我会捆绑文件,以减少请求,同时不对后端进行缓存。 衰败.

改进 INP:缓解主线程

为了实现从交互到下一步绘制的低交互,我将长任务分解成小任务,避免布局混乱,并将复杂的处理程序与交互解耦。我使用 延迟 模块,设置被动事件监听器,在空闲时间安排非关键工作:

document.addEventListener('touchstart', onTouch, { passive: true });

const expensiveInit = () => { /* ...*/ };
requestIdleCallback(expensiveInit, { timeout: 1500 });

// 分割长任务
function chunkedWork(items) {
  const batch = items.splice(0, 50);
  // 处理...
  if (items.length) requestAnimationFrame(() => chunkedWork(items));
}

我测量 DevTools 中的冗长任务,删除重复的库,用本地 API 代替 jQuery 工具。我总结 DOM 更新,使用 而不是 顶部/左侧 并尽量减少回流。

删除 WordPress 镇流器

我在生产网站上不需要很多 WP 功能,所以我停用了表情符号、oEmbeds 和部分 REST API,以节省开支。 要求.这样可以缩小头部,减少脚本对 "第一油漆 "的阻塞。我还会检查平回、RSD 链接和 WLW 清单,并将其关闭。如果它们不起作用,我还会关闭回溯和 XML-RPC。通过这种方式,我减少了攻击面,并保持了启动阶段 .

// 关闭表情符号
remove_action( 'wp_head', 'print_emoji_detection_script', 7 );
remove_action( 'wp_print_styles', 'print_emoji_styles' );

// 减少 oEmbeds 和 REST API
remove_action( 'wp_head', 'wp_oembed_add_host_js' );
add_filter('rest_enabled', '_return_false');
add_filter('rest_jsonp_enabled', '_return_false');

驯服第三方脚本

第三方代码往往是最大的刹车片。我对其进行延迟初始化,只包含绝对必要的内容,并且只在互动或征得同意后加载。分析/跟踪即将到来 异步 在 "第一幅画 "之后,我用静态链接取代了社交小部件。对于 iFrame,我使用 加载="lazy"沙盒以限制副作用。YouTube 嵌入会接收一张预览图片,只有在点击时才会加载播放器--这就节省了启动时的多次请求。

无需助手的数据库维护

我通过 phpMyAdmin 删除多余的修订、清空暂存内容并清理垃圾评论,以加快查询速度。 答话.我会检查自动加载选项是否过大,因为它们会出现在每个查询中。在较小的安装中,几条有针对性的 SQL 语句就足以优化表格。我检查 cron 作业是否挂起并整理旧插件留下的 postmeta。定期维护可以防止查询失控,避免后台变得杂乱无章。 有气无力的 会。

系统 Cron 代替 WP Cron

为了确保 cron 作业可靠、高效地运行,我将它们与页面加载分离开来。我停用了 WP-Cron,在安静的时候安排真正的系统工作。

// 在 wp-config.php 中
define('DISABLE_WP_CRON', true);
# crontab -e (每 5 分钟一次)
*/5 * * * * /usr/bin/php -q /path/to/wp/wp-cron.php >/dev/null 2>&1

这就意味着,没有 cron 会阻碍常规请求的响应时间,而且可以安排诸如瞬时清理或网站地图生成等经常性任务。

严格检查主题、插件和字体

我删除了不活动的主题和所有功能重复或很少提供任何益处的扩展,以便 自动装载机 加载更少。对于字体,我将其变体减少到普通/粗体和两种字体样式,将其托管在本地,并激活主文件的预加载。如果确实需要,我会使用 DNS 预取来准备外部资源。对于 YouTube 嵌入文件,我使用缩略图在稍后初始化 iFrames。这样我就能控制渲染路径,并保持启动有效载荷 .

字体:加载行为、子集、回退

网络字体对感知速度有很大影响。我使用 font-display: swap可选的这样文本就能立即显示出来。我严格检查可变字体,并重新设置 Unicode 区域以节省字节数。有针对性地预载最重要的 WOFF2 文件可减少 FOIT。

@font-face {
  font-family: 'Brand';
  src: url('/fonts/brand-regular.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  unicode-range: U+000-5FF; /* latin base set */
}

我在字体堆栈中定义了简洁的系统回退(如 Segoe UI、Roboto、SF Pro、Arial),以尽量减少布局跳跃。关于 调整尺寸 我对度量差异进行了调整,使从回退字体到网页字体的变化几乎看不出来。

服务器、PHP 和协议

没有正确的基础架构,任何优化都会失败,这就是我关注快速固态硬盘的原因。 PHP-版本和 HTTP/2 支持。OPcache、Brotli/Gzip 和 HTTP/2 多路复用可加快传输速度,减少阻塞。如果可能,我会考虑使用 HTTP/3/QUIC,并仔细检查设置和 TLS 配置;这篇简短的文章介绍了 HTTP/3/QUIC 和 HTTP/2。 实施 HTTP/3.负载和压力测试向我展示了页面在负载情况下的反应。这就是我确保堆栈支持应用程序的方法 携带 我的措施是有效的。

托管服务提供商 特点 绩效 支持 性价比
webhoster.de SSD, php 8.*, http/2 ★★★★★ ★★★★★ ★★★★★
竞争对手 1 SSD、PHP 7.*、HTTP/2 ★★★★☆ ★★★★☆ ★★★★☆
竞争对手 2 硬盘、PHP 7.*、无 HTTP/2 ★★★☆☆ ★★★☆☆ ★★★☆☆

优化 PHP-FPM、OPcache 和传输

我设置了 PHP-FPM,这样请求就不会进入队列。 下午, pm.max_childrenpm.max_requests 我对负载进行了调整。OPcache 会获得足够的内存,以避免重新编译。

php.ini / www.conf
opcache.enable=1
opcache.memory_consumption=256
opcache.max_accelerated_files=20000
opcache.validate_timestamps=0

PHP-FPM (示例值)
pm = 动态
pm.max_children = 20
pm.start_servers = 4
pm.min_spare_servers = 2
pm.max_spare_servers = 8
pm.max_requests = 500

在传输层,我会在 Gzip 之前激活 Brotli,保持 Keep-Alive 开启并检查 TLS 恢复。在 HTTP/2 下,我会检查优先级,以便 CSS/字体和 LCP 图像具有优先权。在 HTTP/3 下,我会监控数据包丢失情况并调整节奏。

CDN、缓存头和地理位置

对于国际流量,我使用边缘网络来减少延迟,并使静态资产靠近用户。 交付.我关注干净的缓存键、不同的标题(如 WebP)和一致的版本。我仔细缓存关键的 HTML 页面,有选择性地缓存 API 响应,并积极缓存图片。简要概述 CDN 优化 帮助我避免双重压缩等陷阱。我就是这样将服务器缓存和边缘缓存结合起来并降低成本的。 查看.

边缘的格式、协商和重复数据删除

我用现代格式(WebP、可选的 AVIF)播放图像,并确保 CDN 尊重内容协商。重要的是正确的 接受-变体和缓存键的唯一性。我只压缩一次(服务器 Edge),并在另一端停用标记。对于 HTML,我设置了保守的 TTL 和强大的 ET 标签,资产保持积极缓存。

衡量、关键数字和优先次序

我从明确的性能预算开始,重点关注 LCP、CLS 和 INP,而不是每毫秒的数值 绝缘 需要考虑。现场数据高于实验室值,因此我将真实用户信号与测试运行进行比较。瀑布图显示了阻塞的资产,请求图显示了重复的库和不必要的字体文件。我对每项变更进行单独测量,以便快速识别出倒退。只有当数据持续改善时,我才会更广泛地推广它们。 .

工作方法:干净利落地部署,快速回滚

我将性能检查纳入了部署流程:构建过程会生成版本化的工件,Lighthouse/DevTools 测试会在暂存阶段运行,只有经过检查的捆绑包才会上线。功能标志允许我以可控方式推出有风险的变更,并在必要时立即停用。这样,我就能在开发新功能的同时保持性能稳定。

简要概述:我是如何实施的

我首先优化具有最大杠杆作用的内容:减小图片大小、激活懒加载、内联关键 CSS 部分并屏蔽脚本 调迁.然后,我会确保浏览器和服务器端的缓存策略,整理 WordPress 功能和数据库,删除不必要的插件。我还会检查基础架构、HTTP/2/3、Brotli 和 OPcache,并确保采用版本控制的简洁部署流程。如有必要,我会添加一个 CDN,并规范标头和变量。最后,我会反复检查关键数据,直到 LCP、CLS 和 INP 达到稳定和绿色水平。 地区 撒谎

当前文章