标签 博客 下的文章

初体验的问题

作为一个前端新手,我决定用 Astro 框架重构个人博客。听说它的静态生成能力和 Partial Hydration 特性可以让网站又快又省资源,这对我这种追求极简的写作者来说简直完美。本地开发时一切顺利,热更新响应迅速,Markdown 渲染流畅。但当我部署到 Vercel 后,用户反馈点击文章链接需要等待 3-5 秒才能看到内容。整个跳转给我的感觉就是卡卡的 —— 明明用了静态站点生成,为什么会有这个诡异的延迟?

打开 Network 面板重新加载页面,发现:

HTML 文件加载仅需 100ms,但主内容渲染延迟了 2.3s;页面加载时触发了多个;Hydration 事件客户端 ;JS 体积达到 420KB…

然后我大概就知道问题在哪里了。

简单地说你可以理解为,本来一次点击,浏览器从A页面跳转到B页面,无论是A页面的消失还是B页面的逐步呈现,这个过程都没有被忽略。Astro的部分渲染,在B页面被完全加载出来之前都停留在A页面,他需要等待B页面的不同内容加载之后刷新视图,呈现B页面的内容。

另外我发现这个特行可以让你实现类似Android里的共享元素的炫酷效果。

我意识到问题可能与 Astro 的核心特性有关:

1. 过度使用客户端组件

在文章页模板中,我为了实现 “阅读进度条” 功能,错误地使用了client:load指令:

<!-- 错误示范 --> <ReadingProgress client:load />

这导致整个组件在页面加载时立即执行 Hydration,阻塞了主线程。

2. 动态路由的 Hydration 策略

我的文章路由采用动态参数[slug].astro,默认配置下:

// astro.config.mjs(原配置) export default defineConfig({ experimental: { islands: false } });

这导致 Astro 在客户端重新渲染整个页面,而非仅更新必要部分。

3. 资源加载未优化

未压缩的图片平均大小 300KB;未启用 Gzip;第三方字体文件阻塞渲染。

这里图片我是引用的第三方图库,虽然没有加preload,但是速度其实还算可以。不过多张图片引用也会影响速度。

尤其要说一下这个字体,我最开始测试的,google fonts的访问速度怎么会比loli.net要快这么多?难道是国内也有服务器?

后来我发现了问题。

google fonts引用的css,是切割好的字体文件。也就是这个css可以理解为是一个目录,里面有分好包的实际字体文件(目前常用方法),然后这个css会分批引用实际字体文件。给👴🏻整无语了。一整个页面就在那里等它这个字体加载。

系统性优化方案

经过调试,我逐步实施了以下解决方案:

1. 组件 Hydration 策略优化

<!-- 正确写法:仅当滚动到可见区域时Hydrate --> <ReadingProgress client:visible /> <!-- 完全静态组件 --> <ArticleMeta server />

2. 配置调整

3. 资源加载优化

使用astro-imagetools自动压缩图片。其实直接添加懒加载就可以了。

4. 给所有二进制文件添加preload

优化后数据

  • 优化后:首字节时间(TTFB)从 800ms 降至 120ms
  • 最大内容渲染时间(LCP)从 2.8s 降至 700ms
  • 客户端 JS 体积减少至 180KB(js问题不大)

最后

静态站点生成不等于自动高性能

前端性能优化需要系统性思维

Astro 的强大在于合理利用其特性,而非盲目使用

现在,我的博客不仅加载速度提升了,Lighthouse 98 XD。

更重要的是,我学会了如何通过 Chrome DevTools 和 Astro 内置工具进行性能分析。如果你也遇到类似问题,可以参考一下我上面的方案。(避雷Google fonts)

TL;DR

通过vercel第三方库来运行php程序

效果展示

展示不了一点,我发现部署几天后开始变得非常卡,不知道为啥

所以我推荐你每天定时deploy一下,会好很多

一,注册需要的账号

你需要注册以下账号

  • github
  • vercel
  • 一个免费或者你自己搭建的mysql数据库
关于数据库,不推荐使用国内的免费数据库,因为vercel访问太慢了
或许你可以尝试db4free,或者一些免费空间提供的数据库

二,操作步骤

1. 创建git仓库

在github创建一个仓库,注意这个仓库需要是private的,也就是私密的仓库。然后clone到本地。下面为了方便,假设仓库名为blog

2. 下载typecho

下载地址:https://typecho.org/download

3. 把typecho解压到仓库文件夹内

此时文件应该存放在根目录

4. 新建api文件夹,然后在api文件夹下创建index.php文件

其中index.php文件的内容如下

<?php
$file= __DIR__ . '/..'.$_SERVER["PHP_SELF"];

if(file_exists($file))
{
   return false;
}
else
{
    require_once __DIR__ . '/../index.php';
}
#echo $_SERVER["PHP_SELF"];

5. 在仓库中创建vercel.json

内容如下

{
  "functions": {
    "api/index.php": {
      "runtime": "vercel-php@0.7.3"
    }
  },
  "routes": [{ "src": "/(.*)", "dest": "/api/index.php" }]
}

6. 在根目录创建config.inc.php

内容如下

<?php
/**
 * Typecho Blog Platform
 *
 * @copyright  Copyright (c) 2008 Typecho team (http://www.typecho.org)
 * @license    GNU General Public License 2.0
 * @version    $Id$
 */

/** 开启https */
define('__TYPECHO_SECURE__',true);

/** 定义根目录 */
define('__TYPECHO_ROOT_DIR__', dirname(__FILE__));

/** 定义插件目录(相对路径) */
define('__TYPECHO_PLUGIN_DIR__', '/usr/plugins');

/** 定义模板目录(相对路径) */
define('__TYPECHO_THEME_DIR__', '/usr/themes');

/** 后台路径(相对路径) */
define('__TYPECHO_ADMIN_DIR__', '/admin/');

/** 设置包含路径 */
@set_include_path(get_include_path() . PATH_SEPARATOR .
__TYPECHO_ROOT_DIR__ . '/var' . PATH_SEPARATOR .
__TYPECHO_ROOT_DIR__ . __TYPECHO_PLUGIN_DIR__);

/** 载入API支持 */
require_once 'Typecho/Common.php';

/** 程序初始化 */
Typecho_Common::init();

/** 定义数据库参数 */
$db = new Typecho_Db('Pdo_Mysql', 'typecho_');
$db->addServer(array (
  'host' => '数据库地址',
  'user' => '数据库用户',
  'password' => '数据库密码',
  'charset' => 'utf8mb4',
  'port' => '3306',
  'database' => '数据库名',
  'engine' => 'MyISAM',
), Typecho_Db::READ | Typecho_Db::WRITE);
Typecho_Db::set($db);

7. 注释掉会阻挡操作的内容

打开根目录下的install.php文件,注释或者删除773-775行,注释的内容大概如下。

    // if (!$writeable) {
        // $errors[] = _t('上传目录无法写入, 请手动将安装目录下的 %s 目录的权限设置为可写然后继续升级', $uploadDir);
    // }
这里如果没有删除,可能会无法初始化数据库

8. 上传代码,在vercel中编译,注意提前绑定域名

9. 第一次打开会报错

提示Database Query Error。这时你需要在你的域名||vercel提供的免费域名后添加/install.php,然后按照步骤操作。

这里如果你没有执行第7步的操作,可能会报错,建议修改之后重新提交

三,注意事项

  1. 过长的等待时间会触发vercel报错,提示This Serverless Function has timed out. 这时你或许可以考虑更换数据库
  2. 注意看第7点
  3. 一些函数官方说支持,但是会有奇怪的问题
  4. 上传二进制文件和直接修改文件的功能就别想了,在仓库中操作吧
  5. 暂时想不到了