1779 字
9 分钟
swup赤石实录
2024/12/21
2024/12/22

起因#

书接上回,当我研究怎么修好计数不更新时,我尝试各种了各种引入svelte模块的方式

相关知识

Islands architecture#

Astro helped pioneer and popularize a new frontend architecture pattern called Islands Architecture. Islands architecture works by rendering the majority of your page to fast, static HTML with smaller “islands” of JavaScript added when interactivity or personalization is needed on the page (an image carousel, for example). This avoids the monolithic JavaScript payloads that slow down the responsiveness of many other, modern JavaScript web frameworks.

What is an island?#

In Astro, an island is an enhanced UI component on an otherwise static page of HTML.

A client island is an interactive JavaScript UI component that is hydrated separately from the rest of the page, while a server island is a UI component that server-renders its dynamic content separately from the rest of the page.

Both islands run expensive or slower processes independently, on a per-component basis, for optimized page loads.

By default, Astro will automatically render every UI component to just HTML & CSS, stripping out all client-side JavaScript automatically.

<!-- src/pages/index.astro -->

<MyReactComponent />

This may sound strict, but this behavior is what keeps Astro websites fast by default and protects developers from accidentally sending unnecessary or unwanted JavaScript that might slow down their website.

Turning any static UI component into an interactive island requires only a client:* directive. Astro then automatically builds and bundles your client-side JavaScript for optimized performance.

<!-- src/pages/index.astro -->

<!-- This component is now interactive on the page!     The rest of your website remains static. -->
<MyReactComponent client:load />

With islands, client-side JavaScript is only loaded for the explicit interactive components that you mark using client:* directives.

And because interaction is configured at the component-level, you can handle different loading priorities for each component based on its usage. For example, client:idle tells a component to load when the browser becomes idle, and client:visible tells a component to load only once it enters the viewport.

——引自astro Docs

因此我尝试了各种各样的client:*,事实上什么作用都没有,那么我就只好继续读代码找到底逻辑是怎么运作的

经过#

我通过不断翻代码找到了这个玩意,有请我们今天的主角——

swup
/
swup
Waiting for api.github.com...
00K
0K
0K
Waiting...

让我们读一读readme

Overview#

Swup adds page transitions to server-rendered websites. It manages the complete page load lifecycle and smoothly animates between the current and next page. In addition, it offers many other quality-of-life improvements like caching, smart preloading, native browser history and enhanced accessibility.

Make your site feel like a snappy single-page app — without any of the complexity.

原来是你小子掌管着我的页面刷新啊,那赶快丢进ai问问怎么不要让它来接管1

ai啪的一下给出来一堆信息,一点卵用没有,全是一些子虚乌有的方法

看来只能硬着头皮上了

打开docs让我康康👀用法

经过一阵紧张刺激的阅读后我看到了这个[data-swup-ignore-script]

好似天降甘霖,我马上就把它写进去试试

试试就逝世

不能说是效果显著吧,只能说是毫无波兰

怎么辦?

只有殺bushi(

虽然很想把电脑切了但是还是得看代码

之后看了个爽#

经过一阵青年大学习,我终于认识到其实没有被swup接管才是原因2,为什么呢,因为被包在<main></main>里的<footer />是可以正常刷新的,但是直接把另一个<footer />塞进去会使整个页面错乱,要不然主题作者为什么不删掉后面一个而是用block lg:hiddenhidden lg:block做移动端适配于是我就看了一下指导swup接管另一个<footer />的刷新,于是我就看到这个

Options#

Swup has several options that can be passed in during initialization.

Defaults#

These are the default options. See below for details on each option.

const swup = new Swup({
  animateHistoryBrowsing: false,
  animationSelector: '[class*="transition-"]',
  animationScope: 'html',
  cache: true,
  containers: ['#swup'],
  hooks: {},
  ignoreVisit: (url, { el } = {}) => el?.closest('[data-no-swup]'),
  linkSelector: 'a[href]',
  linkToSelf: 'scroll',
  native: false,
  plugins: [],
  resolveUrl: (url) => url,
  requestHeaders: {
    'X-Requested-With': 'swup',
    'Accept': 'text/html, application/xhtml+xml'
  },
  skipPopStateHandling: (event) => event.state?.source !== 'swup',
  timeout: 0
});

和对应的astro.config.js

swup({
  theme: false,
  animationClass: "transition-swup-", // see https://swup.js.org/options/#animationselector
  // the default value `transition-` cause transition delay
  // when the Tailwind class `transition-all` is used
  containers: ["main", "#toc"],
  smoothScrolling: true,
  cache: true,
  preload: true,
  accessibility: true,
  updateHead: true,
  updateBodyClass: false,
  globalInstance: true,
}),

这里的container就是指示需要接管的container的

因此我就试着加进去footer

然而事实上并没有任何作用,我加进去的container除了搞崩swup使得彻底不用担心不刷新之外就是根本起不到作用3

于是我只能找找别的方法

swup有hook的机制用于在特定时刻运行指定代码

相关知识

Hooks#

Lifecycle hooks allow triggering custom code at each step of the page transition process. Read on to learn about registering handlers or jump straight to the list of available hooks.

List of hooks#

The following hooks are exposed by swup and can be listened to. Refer to the lifecycle diagram for a visual overview of when the most important hooks are called. Install the Debug Plugin to log triggered hooks to the browser console as they are happening.

Hook nameDescription
animation:outCurrent content starts animating out. Class.is-animating is added.
animation:outSwup waits for CSS animations to finish before replacing the content.
animation:outCurrent content finishes animating out. Content is not yet replaced.
animation:inNew content starts animating in. Class.is-animating is removed.
animation:inSwup waits for CSS animations to finish before finishing the visit.
animation:inNew content finishes animating out.
animationPage will load at once without animations, e.g. on history navigation.
cachePage is saved to the cache.
cacheThe cache is cleared completely.
contentThe old content of the page is replaced by the new content.
contentThe scroll position is reset after replacing the content.
enableSwup instance is created.
disableSwup instance isdisabled.
fetchFetch request is rejected because of a server error.
fetchFetch request is sent.
fetchFetch request has timed out.
historyHistory navigation is started: back/forward button was pressed.
linkLink is clicked.
linkLink is clicked that leads to the current page.
linkLink is clicked that jumps to an anchor on the current page.
linkLink is clicked that opens to a new tab.
pagePage is loaded from cache or via fetch request.
pageNew content is visible after replacing the content.
scrollScroll to the top of the page.
scrollScroll to an anchor on the current page.
visitVisit started: transition to a new page begins.
visitVisit ended: all content is replaced, animations have finished.
visitVisit aborted: a new link was clicked before the current transition has finished.

——引自swup blog

经过我的一番尝试,我发现可以在page:view时添加一段代码,于是我开始查找有什么方法可以刷新内容

询问ai,其告诉我可以通过更改element的属性来使其被刷新,然并卵

事实上刷新请求应该全部被swup接管了,所以根本不会变

最后还真让我找到了一个非常好的方法来强制刷新网页。那就是——————

自己手动刷!

没错,就是手动去改html

于是这依托答辩就诞生了

const specificElement = document.getElementById('counter'); //奇异搞笑之手动更新
if (specificElement) {
    specificElement.innerHTML = "Loading..."
}
try {
    // fetch the data for the current page
    const response = await fetch(
        `https://example.com/api/pageViews?path=${encodedPath}`,
        {
            method: 'GET',
            headers: {
            'Content-Type': 'application/json',
            },
        },
    )

    // Gracefully handle the error scenario.
    // Default to "1" as the current user is seeing the page
    if (!response.ok) {
        pageViews = 1
    } else {
        const { count } = await response.json()
        // Optimistically, show the new page view count
        pageViews = Number(count) + 1
    }

    if (specificElement) {
        specificElement.innerHTML = `Seen 👀 by ${pageViews} human(s)`
    }
} catch (err) {
    // Default to "1" as the current user is seeing the page
    pageViews = 1
}

移动端模式下刷新网页,访问计数被刷新了,总算结束了

后记#

感觉没用的知识又增加了,还是不知道怎么面对线代和高数,🐔

后后记#

突然发现这样就可以干掉一个位置的<PageViewCounter client:only="svelte" />,然后就可以合并计数更新代码到svelte里面4,这样就解决获取计数与更新计数不同步的奇异搞笑问题了 这依托史突然优美不少,绷

Footnotes#

  1. 这个时候我还不知道原来是没被接管导致的,笑嘻了

  2. 现在才知道,晚了哈哈,你已经浪费了生命中宝贵的3小时

  3. 如果有哪位大佬知道可以告诉我,虽然估计没什么人会看就是

  4. 因为少了一个<PageViewCounter client:only="svelte" />打开页面时就不会调用两次代码

swup赤石实录
https://blog.kodatemitsuru.com/posts/2024/12/21/swup赤石实录/
作者
Kodate Mitsuru
发布于
2024/12/21
许可协议
CC BY-NC-SA 4.0