My website is showing messy components until DomContentLoaded.
I would like to show a loading-spinner or hide the content until page is loaded.
I'm using React SSR with UmiJS3.
I would suggest you to use Suspense API from React but it doesn't support ssr right now but they recommend Loadable components which referenced in here
Related
For my own project I would like to fetch HTML code from multiple Vuetify components. Not as a HTML string, but really as a DOM element that can immediately be appended to the body. I want this so that I can use these components in a non Vue environment.
Is there any way I can accomplish this?
I'm not entirely sure what your use case is for this. If you could elaborate on what you're trying to achieve, I could likely give a better answer.
I've had some similar requirement in the past, where I needed to access the entire HTML content of components/sub-components.
How I did this was by rendering the components in an iframe. From there, you can access and modify the mounted iframe DOM.
I can't find the source code on how I did this but perhaps concept/approach could serve as a starting point.
From a cursory internet search, I found this link https://jsfiddle.net/ohznser9/ with a JS Fiddle demonstrating a i-frame component that takes Vue components as a slot.
I'd imagine you could extend this component to add functionality to modify or extract elements from the DOM.
Perhaps you could load the iframe invisibly, grab the DOM elements from that and do what you wish with them
The very unpleasant situation arises when the page loads before some parts (fonts, necessary css files) are loaded.
I see on some sites, they hide some parts before the page components loads.
For example:
I don't want to put a preloader in the page. Is there just a tactic or any other solution for the problem?
These pages use a javascript framework such Angular, React, or Vue.
They use something called a lifecycle hook. I'm most familiar with Vue.js, but there are different ones depending on when they are called/what is loaded.
They more than likely use a before mounted & mounted lifecycle hook which performs actions until an item is fully loaded, then performs different actions.
If you don't use a library, and are looking to - I'd recommend Vue.js ecause you don't have to install/learn node.js to use it on a page, only need a CDN, and the link I used below will show you how to prevent your page elements from being viewed before they are loaded.
https://v3.vuejs.org/api/options-lifecycle-hooks.html
https://angular.io/guide/lifecycle-hooks
https://reactjs.org/docs/state-and-lifecycle.html
I am trying to add a Trustpilot widget to my Gatsby.js website. To make the Widget styling work, it is required to load an external script from Trustpilot CDN.
<script type="text/javascript" src="//widget.trustpilot.com/bootstrap/v5/tp.widget.bootstrap.min.js" async></script>
I have tried multiple ways to add this script to my footer component. The first thing I tried was React Helmet. I added using the following code:
<Helmet>
<script type="text/javascript" src="//widget.trustpilot.com/bootstrap/v5/tp.widget.bootstrap.min.js" async></script>
</Helmet>
The script seems to load and the styling works when I initially load a page. Once I navigate to a different page, the styling goes away. As I reload, it comes back.
I then tried adding the script inside componentDidMount()
componentDidMount() {
var addScript = document.createElement('script');
addScript.setAttribute('src', '//widget.trustpilot.com/bootstrap/v5/tp.widget.bootstrap.min.js');
document.body.appendChild(addScript);
}
But even that yields the same result.
What's going on here? Is the external js script going away? How can I load it correctly so that it stays?
When you navigate away the parent component is being unmounted and Helmet removes the corresponding script tag from the head. To avoid this, place the component above the page component, e.g. using wrapPageElement or wrapRootElement as needed.
Naive scripts that inject code into the DOM are going to be problematic. React has some notes and tips on this in the documentation. Typically I will search to see if the vendor has any documentation on integrating with a single-page app. If not, you might need to do some code spelunking to figure out how to best support the desired functionality within the constraints.
So I'm working on a micro-frontend architecture POC right now, using Web Components to wrap around code from any other framework out there. The goal is to have pieces of the UI be individually deployable to different hosts and simply pulled into the "parent" app (ie, the one that the user navigates to).
I've got most of my architecture working, but right now I'm trying to integrate the Shadow DOM into my work. My current design is to load both the JS and CSS through global static link/script tags, as shown below. Without the Shadow DOM, this works perfectly.
<html>
<head>
<link rel="stylesheet" href="http://micro-fe.com/file.css" />
</head>
<body>
<web-component></web-component>
<script src="http://micro-fe.com/file.js"></script>
</body>
</html>
Once I mount the content inside my Web Component using the Shadow DOM, however, this breaks down. The stylesheet I am loading in the page header is no longer able to touch the content within the Web Component. That is my ultimate goal for using the Shadow DOM, but that means I need a different way of loading my CSS. The goal is to load it from an external stylesheet like it is now, and not have it inlined in a tag. Something like this:
// Code is inside Web Component. "this" is HTMLElement
const shadowRoot = this.attachShadow({ mode: 'open' });
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = 'http://micro-fe.com/file.css';
shadowRoot.appendChild(link);
I haven't tested that yet, but I've read that tags are supposed to work from within the Shadow DOM. This, in theory, will get me my scoped styles in the Web Component.
My final challenge, and the reason I am posting this question, has to do with conditional rendering. My won't always be on the page. Other logic around it will determine when I want that content rendered. So my concern is that I don't want the CSS file to have to be re-loaded each time the component gets rendered.
I'm considering browser caching as a possible solution, but in general I'm wondering if there are any tips that can be provided. I know this is a bit complicated and non-standard, but my ultimate goal is to solve all of these problems and publish a library that does it all out of the box to make it easier for others.
I haven't tested that yet, but I've read that tags are supposed to work from within the Shadow DOM. This, in theory, will get me my scoped styles in the Web Component.
Yes, you can use <link> inside Shadow DOMs.
So my concern is that I don't want the CSS file to have to be re-loaded each time the component gets rendered. I'm considering browser caching as a possible solution, but in general I'm wondering if there are any tips that can be provided.
Yes, thanks to browser caching the CSS file will only be downloaded the first time it is needed.
I've an Angular 2 component, which contains multiple sub-components. For a few of them it's quite expensive to load them and sometimes it is not necessary to load them at all. For example if the user is not scrolling that far.
Anyway, I know how I can lazy load routes, but is there a way of lazy loading a template? Like only if a element is in or close to the Viewport?
There is no way to lazy load templates. What you can do is to lazy load modules. How to manually lazy load a module?
If you use this with ViewContainerRef.createComponent() (see Angular 2 dynamic tabs with user-click chosen components for an example) to dynamically add the components that you only want to show if the users scrolls far enough, it might work (not tried myself yet).
You can segregate or group sub-components to be displayed into smaller components to be loaded together.
To reduce the time to load,
1. try to use smaller templates inline into component file.
2. Use *ngIf directive in your template which can avoid rendering of the template and component instance is not created as such. However, take note that if you're using *ngIf it is better to use only is the DOM is not refreshed fequently, else you may create DOM and use the component by binding it with [hidden] attribute of the DOM