Next JS : 在 dom 渲染时加载屏幕
Posted
技术标签:
【中文标题】Next JS : 在 dom 渲染时加载屏幕【英文标题】:Next JS : Loading Screen While the dom is rendeing 【发布时间】:2021-09-08 02:29:21 【问题描述】:如何显示我自己的加载程序而不是空白的白屏? 例如,Tweeter 在页面加载时显示徽标,对于 Facebook、google AdSense 等也是如此。 看这个动图,我想在 Next Js 里有这样的东西。
我猜这与 _document.js 有关。 react js 有一个类似的问题(在 index.html 中渲染加载器) 但我不知道如何在下一个 js 中做到这一点。
【问题讨论】:
那可能不是使用 next.js,而是一个 SPA。除此之外,为什么不设置背景图片? 在这些情况下,DOM 渲染通常不是您所等待的。它非常快。通常减慢速度的实际上是获取 JS 本身或从您的服务器获取数据以填充 UI。 @evolutionxbox 你能解释一下使用背景图片的解决方案吗? 【参考方案1】:无需安装任何库
import useRouter from "next/router";
import useState, useEffect from "react";
function MyApp()
const router = useRouter();
const [loading, setLoading] = useState(false);
useEffect(() =>
router.events.on("routeChangeError", (e) => setLoading(false));
router.events.on("routeChangeStart", (e) => setLoading(false));
router.events.on("routeChangeComplete", (e) => setLoading(true));
return () =>
router.events.off("routeChangeError", (e) => setLoading(false));
router.events.off("routeChangeStart", (e) => setLoading(false));
router.events.off("routeChangeComplete", (e) => setLoading(true));
;
, [router.events]);
return <>loading ? "loading..." : <AppComponent /></>;
【讨论】:
【参考方案2】:试试这个逻辑。创建一个状态变量并使用 NextJs 路由器事件。使用路由器事件来控制状态变量,最后使用状态变量来控制加载屏幕和其他 DOM 元素的渲染。
function MyApp()
const [loading, setLoading] = React.useState<boolean>(false);
Router.events.on('routeChangeStart', (url) =>
setLoading(true);
);
Router.events.on('routeChangeComplete', (url) =>
setLoading(false);
);
return(
<>
loading ? (
<PageLoader />
) : (
<AppLayout>
<Component ...pageProps />
</AppLayout>
)
</>
)
【讨论】:
【参考方案3】:你不能。您看到的是 twitch 加载程序向您显示的自定义启动画面。它所做的是将加载过程分成两部分。第一个是标准的——浏览器请求并接收您提供的用于呈现页面的 html 和脚本文件。您无法使用传统的 Web 应用程序绕过此阶段,但是,您可以做些什么来改善用户体验,即尽量减少该时间。一个很好的例子是 index.html 包含内联 css 和 javascript 动画启动屏幕,一旦加载启动实际应用程序。这样,真正的数据交换是在浏览器呈现页面后完成的。这需要您在规划应用程序时做大量工作,但使用现代框架和工具,实现它肯定有更短和更脏的路径。但是,如果您有 SPA,这几乎是您可以去的唯一方法。
附带说明,如果您想加快网站的加载速度(这就是为什么无论如何都需要启动画面的原因),只需运行一些分析,检查优化。服务器端缓存通常会为您提供最佳的投资回报率,但它不会帮助您处理较重的负载(大图像或大量小图像)。 html 的分段是第二好的选择。然后你应该看看导入的库和东西,这些往往会增加一点。最后还有一些选项可以在服务器上压缩数据以限制数据负载。
【讨论】:
【参考方案4】:通常这些是通过一个覆盖所有内容并默认显示的 div 来完成的,您在该 div 中放置的内容取决于您(gif、svg 等)。一旦 window.onload 被调用,只需隐藏 div,它将显示完全渲染的 dom。
这是一个基本示例(我在移动设备上,请原谅我的格式) CSS:
.loadingsScreen
position:absolute;
left:0;
top:0;
width:100%;
height:100%;
background-color: #whatever-color;
z-index: 10; /*just make sure it's the highest on the page*/
JS:
window.onload = function()
$("#loadingScreen").fadeOut(); //just make it hide the overlaying div, I used jQuery in this example but there are many ways to do this
;
【讨论】:
【参考方案5】:实际上这不是 Next.js 提供的“从盒子里”提供的东西,你必须自己实现这些东西,你可以使用一些全局状态(redux/context)来确定你的应用程序是否正在加载某些东西,并渲染loader 基于这个状态。
【讨论】:
【参考方案6】:您可以使用nprogress。它适用于您的所有路线更改过程。
import React from 'react';
import Router from 'next/router';
import App, Container from 'next/app';
import NProgress from 'nprogress';
NProgress.configure( showSpinner: publicRuntimeConfig.NProgressShowSpinner );
Router.onRouteChangeStart = () =>
// console.log('onRouteChangeStart triggered');
NProgress.start();
;
Router.onRouteChangeComplete = () =>
// console.log('onRouteChangeComplete triggered');
NProgress.done();
;
Router.onRouteChangeError = () =>
// console.log('onRouteChangeError triggered');
NProgress.done();
;
export default class MyApp extends App ...
您还需要包含一个样式文件。如果将 css 文件放在静态目录中,则可以按如下方式访问样式: 它适用于您所有更改的路线。
<link rel="stylesheet" type="text/css" href="/static/css/nprogress.css" />
【讨论】:
这与更改路线无关。我问当我刷新页面时,我想在下一个 js (react) 创建 dom 时显示一个加载器以上是关于Next JS : 在 dom 渲染时加载屏幕的主要内容,如果未能解决你的问题,请参考以下文章