Astro3.0更新速览 - Shiina's Blog

Astro3.0更新速览

2023 年 8 月 30 日 - 00:32:46 发布
4.4K 字 15分钟
本作品采用 CC BY-NC-SA 4.0 进行许可。
本文距离首次发布已经过去了 212 天,请注意文章的时效性!

Astro3.0更新速览

参考博客地址:https://astro.build/blog/astro-3/

前言

后天就要回学校了,这一个暑假基本都是在小黑屋当苦力,想着不能一直不产出点什么技术分享,刚好就在昨天 Astro 发布了 3.0 版本,很多特色还是让我眼前一亮的,现在我们就一个一个一个一个一个一个的体验一下.jpg

View Transition

首先是最具有特色的视图过度动画 API,这个被写在了博客的开头

文档 API 如下:https://docs.astro.build/zh-cn/guides/view-transitions/

其提供了一个轻量级的客户端路由,其允许页面之间实现自定义过渡效果

看着感觉就像是 SPA 页面那样,因为路由跳转也不会触发浏览器跳转

该组件被要求放在 <head> 标签内来控制。

实现 SPA

以前个人是从来没想过在 Astro 这种多页面框架下实现 SPA 模式,因为他本来就是面向 MPA 实现的。但是这个 API 的诞生把以前觉得不可能的事情变成了可能,所以现在让我们来根据文档来试着在 Astro 内实现 SPA 路由。

在这里读者也可以自行尝试直接将一个 <ViewTransition /> 组件放入 head 标签内就可以体验了,但是强烈建议新建一个项目去尝试,而不是去升级旧项目的版本然后来测试,毕竟现在 (2023.08.31) 还不是很稳定,现阶段是睡一觉醒来能刷三个 bug fixs 版本号的阶段(((

此处笔者使用了 Astro 的标准模板进行了测试

页面看起来大概是这样,顶部的是路由部分,点击的时候会在客户端进行跳转,同时浏览器发出页面请求:

此时似乎没有动画效果,我们只需要添加一串模板命令:transition:animate 并在其后面指定动画类型即可(需要在支持document.startViewTransition的浏览器上使用)。

可选指令可以前往这里查看:https://docs.astro.build/zh-cn/guides/view-transitions/#%E5%86%85%E7%BD%AE%E5%8A%A8%E7%94%BB%E6%8C%87%E4%BB%A4

在开发环境下看不出来 astro 到底是怎么局部更新页面的,所以后面笔者尝试了打包后进行切换,发现是直接对整个页面进行了请求与更换

放一张打包后的网络请求截图:

单个组件的过渡

参考这里查看对单个组件自定义过度:https://docs.astro.build/zh-cn/guides/view-transitions/#%E5%86%85%E7%BD%AE%E5%8A%A8%E7%94%BB%E6%8C%87%E4%BB%A4

对组件/元素进行状态维持

通过 transition:persist 指令进行处理,其底层采用 replaceWith 实现

底层浅析

动画实现由 document.startViewTransition 强力驱动:https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API

目前该 API 在 Firefox、Safari还没有得到支持、Opera 还在实验阶段;手机则只有 Chrome、三星浏览器、Android Webview得到了支持(资料来源于此处

ViewTransition组件源码如下:https://github.com/withastro/astro/blob/main/packages/astro/components/ViewTransitions.astro

在这里就大概说明一下这个组件对于浏览器做了什么事情:

  • 判断浏览器是否支持 核心动画 API 或 引入的核心 <ViewTransition /> 的指令是否为 animate
  • 监听 dom 的所有事件,当点击时进行如下判断:
    • 如果是a标签是锚点或者同源与同query参数则不执行任何动作
    • 执行跳转动作
      • 先请求目标的完整html,假如请求失败则直接使用 MPA 模式跳转
      • 检测是否支持动画 api,支持的话就走 api,否则直接走更新 DOM 部分
        • DOMParser 转换新 html
        • 遍历所有样式标签,检查是否有标签不能被替换
        • 走新旧 dom patch:html 属性继承、head 标签替换;检查所有需要保持状态的元素,使用 replaceWith 替换;锚点跳转特殊处理
        • 触发 astro:after-swap 事件
      • 等待新的 css 请求完成
      • 执行新页面的 script
      • 触发 astro:page-load 事件
    • 更改 history 路径
  • 监听浏览器回退事件
    • 假如页面没有启用 transition 则调用 location.reload 方法
    • 假如浏览器 history.state 为空则不执行任何动作
    • 执行跳转动作*
  • 监听所有a标签的 ['mouseenter', 'touchstart', 'focus'] 事件,进行预请求(作用暂时未知)

个人阅读源码总结的流程与 官方 写的还是差不多的,如果觉得这里写的比较复杂也可以直接看官方解析

图像控制

这个功能在 3.0 版本中终于处于稳定状态了,目前 Astro 推荐使用图像的方式如下:

---
// Import the <Image /> component
import { Image } from "astro:assets"
// Import a reference to the image itself
import myImage from "../assets/penguin.png"
---

<Image src={myImage} alt="A very cool penguin!" />

使用 Astro 内置 Image 组件的优势:

  • 自动检测优化图像
  • 添加推断高度宽度,防止布局偏移影响页面性能

布局偏移优化这个点个人是比较喜欢的,省去了自己需要手写宽高的不便,这对于拥有大量图片的页面是一个很好的优化。

其次是一些其他方面的改进:

  • 支持 Vercel 内置图像服务
  • 将图像优化库改为 sharp
  • 支持优化远程图像

sharp 是一个比较知名的 nodejs 图像优化库了,笔者在这里对其他方面的改进了解不多,就不做过多讨论。

Astro组件高速渲染

大概看了一下,官方写的是 3.0 的渲染速度比 2.9 快了大约 30%,在复杂情况下能快 75%

此处笔者将用自己的一个项目进行测试,使用 2.9.73.0.3 进行对比

由于这一部分的优化是对于 astro 组件进行的优化,在构建客户端文件的时候只对 .astro 文件编译进行了优化(个人观点)

以下是使用了 2.9.7 版本构建客户端文件的时间

以下是使用了 3.0.3 版本构建客户端文件的时间

项目大概有 183 个 astro 组件,可以看到提升了大约 1 秒左右的时间,当然这部分速度也取决于组件复杂程度,笔者在这里就不做过多讨论了

SSR & Serverless 功能增强

笔者没有学习过 SSR 优化与 Serverless 相关内容,且此部分大多与 Vercel 有关,就不做解读了。

热重载实现(React & Preact)

如果以前你在页面中引入过框架组件,那么你一定知道他是不支持告诉热重载的,每保存一次react文件整个页面就都需要重刷新一次。

在 Astro 3.0 成功支持了 React & Preact & Solid.js 的 hmr 实现。

但是笔者在尝试迁移项目到 3.0.3 的时候发现所有的 react 组件都出了问题,所有不得不放弃。

大概看了一下是React的引入需要进行处理,得采用 import * as React from 'react' 这种兼容性最好的方式为其提供命名空间

打包文件输出优化

这里浅浅过一下官方的博客内容:

  • html 压缩
  • astro class 类名注入方式改变,让 css 具有更好的可读性
  • 对小的css模块进行内联处理

总结

整体上还是挺让人眼前一亮的,当然在 bug 修复上还是有很长的路要走。ViewTransition 实现 SPA 感觉是目前多页面框架下一个突破,让人眼前一亮。希望 astro 能在未来带来更好的网站构建体验与更优质的性能。

个人信息
avatar
Shiinafan
文章
37
标签
52
归档
4
导航