You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SvelteKit页面重载时{Math.random()}为何执行两次?

为什么SvelteKit的+page.svelte中Math.random()会执行两次?

这是因为SvelteKit默认采用**服务端渲染(SSR)+ 客户端水化(Hydration)**的渲染模式:

  • 第一次执行:服务端渲染页面时,模板里的{Math.random()}会被执行,用来生成发送给浏览器的HTML内容。
  • 第二次执行:浏览器拿到HTML后,Svelte启动客户端水化流程,此时模板中的表达式会再次执行,用来建立组件的响应式状态并关联DOM。

由于Math.random()每次调用返回值都不同,所以你能明显感知到两次执行的差异。

解决办法

如果只需要生成一次随机值,或者仅在客户端执行,有几种可行方案:

  1. 使用客户端环境判断
    导入SvelteKit提供的browser变量,限制仅在客户端执行:
    <script>
      import { browser } from '$app/environment';
      let randomNum = browser ? Math.random() : 0;
    </script>
    
    <p>{randomNum}</p>
    
  2. 用onMount钩子
    onMount只会在客户端组件挂载后执行,适合依赖DOM的逻辑:
    <script>
      import { onMount } from 'svelte';
      let randomNum;
      onMount(() => {
        randomNum = Math.random();
      });
    </script>
    
    <p>{randomNum ?? 'Loading...'}</p>
    
  3. 在+page.js的load函数中生成
    如果需要服务端生成一次并同步给客户端,可在页面的load函数里生成值,通过props传给组件:
    // +page.js
    export function load() {
      return {
        randomNum: Math.random()
      };
    }
    
    <!-- +page.svelte -->
    <script>
      export let data;
    </script>
    
    <p>{data.randomNum}</p>
    
    这种方式下,服务端生成的值会被序列化后传给客户端,客户端不会重新生成,保证前后结果一致。

内容的提问来源于stack exchange,提问作者Joel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 15:52:04