【Svelte】+layout.ts 会执行几次?
如果存在多个层级的 +layout.ts
文件,那么,顶层的 routes/+layout.ts
将会执行几次?
This is a great question that touches on a core concept of SvelteKit’s data loading and routing!
The simple answer is: it’s neither “once” nor “every navigating” in a simple sense, but rather “potentially every navigating, but intelligently cached and executed where it makes most sense.”
Let’s break it down:
-
Initial Page Load (Server-Side Execution):
- When a user first visits your website (or does a hard refresh), the browser makes a request to the server.
- SvelteKit, running on the server, will execute the
load
function inroutes/+layout.ts
(along with any other relevant+layout.ts
and+page.ts
files for the initial route). - The data returned by these
load
functions is used to render the initial HTML on the server, which is then sent to the client. - So, on the very first load, it executes on the server.
-
Client-Side Navigations (Browser-Side Execution):
- Once the SvelteKit app has loaded in the browser (and “hydrated”), subsequent navigations (e.g., clicking a
<a href="...">
link to another page within your app) are handled client-side. - When you navigate to a different page, SvelteKit’s client-side router intercepts the request.
- It will then execute the
load
function inroutes/+layout.ts
(if it’s still part of the active route hierarchy) on the client-side (in the user’s browser). - The data is fetched, and the UI is updated dynamically without a full page refresh.
- Once the SvelteKit app has loaded in the browser (and “hydrated”), subsequent navigations (e.g., clicking a
Why “potentially every navigating, but intelligently cached”?
- It runs for each navigation: If you navigate from
/
to/about
to/contact
, and+layout.ts
is the top-level layout for all these pages, itsload
function will be evaluated during each of those client-side navigations. - Intelligent Caching and Dependencies: This is the crucial part. SvelteKit’s
load
functions are smart:- A
load
function will not re-run unnecessarily if its “dependencies” haven’t changed. By default,load
functions implicitly depend on the current URL’spathname
andsearchParams
. - You can explicitly define dependencies using
depends()
:// routes/+layout.ts export async function load({ url, fetch, depends }) {depends('data:user'); // If this tag is invalidated, the load function rerunsconst response = await fetch('/api/user');const user = await response.json();return { user, path: url.pathname }; }
- If you navigate between two child routes, and the parent
+layout.ts
’sload
function only depends on data that hasn’t changed (or data whosedepends
tag hasn’t beeninvalidate
d), SvelteKit might use a cached result or not fully re-execute the function’s body. - However, since
url.pathname
is a common implicit dependency, navigating to a different page will generally cause it to re-evaluate, even if it reuses some cached data within the function.
- A
In summary:
- First page load: Executes once on the server.
- Subsequent client-side navigations: Executes on the client-side for each navigation where it’s part of the route hierarchy, but with SvelteKit’s dependency tracking and caching to optimize performance.
So, if you put code with side effects or expensive computations in your +layout.ts
, be aware that it will run on both the server (once per initial load) and potentially multiple times on the client (during navigations). If something must only run on the server, use +layout.server.ts
.