Optimize page load of multiple pages - reactjs

I've a multiple page site. I created a single component enclosing all the texts/para/images. I've refered this component to all the multiple pages. I used a class name to hide/show the content to the respective pages via css. Problem is that the page load is slow. Since all contents are hidden using css they are still loaded making my site slow. Any help on this is much appreciated. Thanks

There are multiple things you can check.
Check the internet connectivity, I hope you have good internet connectivity to load the
page.
As you say there are multiple page with single component, check if you can move those into sub-component.
I am not sure how you're hiding those components use css property display:none if those are light weight.
you can use something like this:
<style type="text/css">
.hidden { display:none; }
</style>
render: function() {
return (
<div className={this.props.shouldHide ? 'hidden' : ''}>
This will be hidden if you set <tt>props.shouldHide</tt>
to something truthy.
</div>
);
}
// or in more modern JS and stateless react
const Example = props => <div className={props.shouldHide}/>Hello</div>
source

Related

SvelteKit loading indicator when a page load time threshold is exceeded

I am using SvelteKit for a website that is mainly server-side rendered pages. The client-side navigation on SvelteKit works beautifully and is super snappy. However, sometimes, when the backend server is called in the route load() function, the response is not instant and maybe several seconds because of the database long-tail latency.
What would be the best way to create a loading indicator that is only displayed if the loading time is not instant (sub 200ms)? I am aware of the generic navigating pattern, but I specifically hope to create a loading indicator that is not triggered unless the page load is not instant.
Sveltekit has a store variable called "navigating" which literally indicates if the client is in-between loading pages. From the Sveltekit docs:
navigating is a readable store. When navigating starts, its value is { from, to }, where from and to both mirror the page store value. When
navigating finishes, its value reverts to null.
Note, that if your page is pre-rendered, it should be "instant" and thus not show a loading indicator. If not, this "navigating" variable will be not null for as long as it takes for your content to be fetched and/or rendered. If you wanted to, you could make the "Spinner" component show nothing...until after 200ms (using a setTimout timer)...which it sounds like you do want.
Here's a sample implementation from a wrapper component I have used in the past (pardon the tailwindcss syntax...I copied and pasted it). You can customize this idea in __layout.svelte or wrap components or entire "pages" with this {#if $navigating} logic:
<script>
// USE THIS:
import { navigating } from '$app/stores'
// Example spinner/loading component is visible (when $navigating != null):
import Spinner from '$lib/design/Spinner.svelte'
...
</script>
<main class="py-4">
<div class="pagePaddingMain flex-col">
{#if title}
<h1 class="text-4xl text-center text-cText pb-4 sm:text-5xl">{title}</h1>
{/if}
{#if $navigating} <!-- LOOK HERE -->
<div class="m-8">
<Spinner />
<h1 class="ext-3xl text-center text-cText">Fetching {title}...</h1>
</div>
{:else}
<slot />
{/if}
</div>
</main>
That's it. Good luck!

React : best way to inject Component in dynamically loaded HTML?

I'm new on React (I more at ease w/ jQuery or AngularJS). I have a special case and I don't find a good way to resolve it...
My app contains an area which is like a "document viewer". It loads an HTML content from the backend (via API, using Fetch) and inject it in the "viewer" component. The HTML content loaded looks like an "university report" (it's just a formatted text, only <span> and <p> with class="..." attributes, nothing more).
Ex : <p>Lorem ispum <span>some text</span> loreb bis <span>ipsum</span></p> ...
I load the content, and inject it this way in the render() of my component <Viewer> :
<div dangerouslySetInnerHTML={ getFreshlyLoadedHTML() } />
Easy, it works just fine !
But... Now, I want to inject some "interactive" components in the loaded HTML. For example, some button to give a feedback etc. The API must decide where to place the component between the words/nodes of the formatted text (HTML).
Ex :
<p> Lorem ispum <span>some text</span>
loreb bis <span>ipsum</span>
<MyFeedbackButton paragraph="1.3"/>
</p><p>Other Lorem Ipsum<p><span>...</span>
There, I'm stucked because I cannot use dangerouslySetInnerHTML if there are components inside the loaded HTML...
First attempt : I've tried modifying the API, and instead of sending the HTML in a string to the app, I send a custom JSON structure that represents almost the final JSX structure that I want. Then, in my react page, the render function only have to parse the JSON and build the JSX (here, a JsFiddle example if it's not clear : https://jsfiddle.net/damienfa/69z2wepo/34536/ )
It works, but I can't believe it's the good way...
I see a major problem : all the HTML node (span, p...) that I build from the render function are referenced by reactJs, is it really necessary ? Mostly, there are "dead" nodes (I mean, dom node that won't never changed, this is static formatted text).
Just take a look a all those "data-reactid" on nodes that never will be interactive...
What would be your advice on that case ?
What about my attempt with a JSON-structure sent by the API ?
Is there a way to say to react "do not reference that element" ?
Do you clearly see a better solution to my problem ?
Your current workflow is not very secure and subject to many potential errors and open doors, especially concerning code injection ...
The overload due to react tracking the nodes is not an issue, React could track 10 000 nodes and not have a problem (well actually on many of my apps React has more than 100 000 nodes to care about and it still rurns perfectly).
I see different solutions here:
If there are only 3 or 4 possibilities of dynamic components and order, you might have components like "templates" to which you would simple send text arguments. This is the safest and easiest option.
If it doesn't suit your use-case but the JSON file can contain only a limited set of components, the components should be located in your main app, and then rendered with custom props from the JSON. Actually given the structure of data you could consider using xml instead of json and build a xml tree that you would parse and render. Only components from your white list would be rendered and it would limit drastically the potentials security issues. If needs quite some work on the XML parser though.
If the JSON file can contain many many different and unpredictable components or if the behaviour of those components is largely dynamic and independant of your app, you might as well consider using an iframe, with its own JS and HTML, so that this part of the code is isolated from the rest.
Try using an inline anonymous function within the inner content from within React using JSX. It works! Just be careful about how you wire up the data so there isn't a route where a user can inject HTML from an input or text field.
<div className="html-navigation-button">{(() =>
{
const CreateMarkup = ( sNavItemName :string ) => {
return {__html: sNavItemName };
}
var sTextToAddHtmlTo = props.nextNavItem.name.toString();
sTextToAddHtmlTo = sTextToAddHtmlTo.replace( "/", "/<wbr>" );
return (
<div dangerouslySetInnerHTML={CreateMarkup( sTextToAddHtmlTo )} >
</div>
);
})()}
</div>
I didn't override the React internals of 'render()', but only used a React Component with props wiring to pass down data to it for rendering.
I added the hook for 'dangerouslySetInnerHTML' deep within the return content of the React Component so there would be no easy way to intercept and manipulate it.
As such, there is no 100% guarantee on safety, but that's where adding good security to web services, databases, and use of CORS and CORB would be helpful to lock down security risks.

ng-srcset images initially not displaying in IE11 intermittently

The page loads without any of the images displaying on IE11 only, but refreshes them accordingly when we resize the browser intermittently (1/3 loads). We cannot replicate this with any of the other browsers. srcset works fine by itself with static content.
Here is a Plunker example of it not working in IE11.
Or quick and easy, the actual img html we're using:
<img data-ng-srcset="{{::image.url}}, {{::image.url2x}}" alt="{{::image.name}}"/>
The images or surrounding divs do not have any transitions, shadows or opacity applied.
The html renders fine with angular passing over and rewriting the srcset attribute correctly. The images just do not appear, only the alt tag. Wondering if this could be a call stack issue due to the intermittence of it, maybe a race condition with Picturefill loading before angular finishes a digest or something.
Cheers in advance!
A work around if you use PictureFill in a loop and in a specific case (not on all images of your application), is calling a function that launch PictureFill directly from HTML, after last item loaded (this is not the best practice but fix the IE11 problem) :
<picture><!-- Your image --></picture>
<span ng-if="$last">
{{ controllerAlias.launchPictureFill() }}
</span>
Came across this as a solution: http://tech.endeepak.com/blog/2014/05/03/waiting-for-angularjs-digest-cycle/
var waitForRenderAndDoSomething = function() {
if($http.pendingRequests.length > 0) {
$timeout(waitForRenderAndDoSomething); // Wait for all templates to be loaded
} else {
$window.picturefill();
}
}
$timeout(waitForRenderAndDoSomething);
The only issue that the blog post describes is here, so if anyone has anything better please let me know:
The $http.pendingRequests supposed to be used for debugging purpose only. If angular team decides to remove this, you can implement the same using http interceptors as suggested in this link.

Best approach to change background image in AngularJs at runtime

I want to create generic feature that allows me to change background image of any section. After going through options provided I found these two approaches. Want to choose best approach to change image because on single page I want multiple times change background facility. It will be available to four to five sections.
Approach
Using Directive check this stack overflow link.
Also there is another approach of angular scope variables that we can updates at runtime.
<div ng-style="{'background-image': 'url(/images/' + backgroundImageUrl + ')'}"></div>
Required Usage ( With respect of Directive )
<body>
<section backgroundImage url="{{backgroundImageUrl1}}">
...
</section>
<section backgroundImage url="{{backgroundImageUrl2}}">
...
</section>
<section backgroundImage url="{{backgroundImageUrl3}}">
...
</section>
<section backgroundImage url="{{backgroundImageUrl4}}">
...
</section>
</body>
As shown above I am going to update background-image attribute for each section. If these property is set inside CSS file, it will reduce time to load images i.e. If we directly add inline css styling in HTML, all images will loaded on DOM load. It will make extra request to server to get images and load them in DOM. I wanted to follow strategy that will reduce loading time in my SPA(Single Page Application).
I think going with <div ng-style="{'background-image': 'url(/images/' + backgroundImageUrl + ')'}"></div> should be more effective.
You dont introduce another layer of complexity, directives create scopes, which are watched and digested, also directives must be compiled in the begining.
Using symple ng-style together with some specific url from controllers property shoudl only do request for that particular active image. Because of that i think it should be the optimal solution.

backbone js add printing region dynamically

I have a requirement to print the View model data using Print Button.
Currently i have a div and assigning my view content to it. This div has been already added in backbone region. In my javascript function, i am just setting the viewmodel content to the printdiv and it working with out any issue.
But the content which i have added for printing is getting appended in the browser HTML also, I dont want to show that in my browser. I tried setting visible hidden and display none to my printingdiv. but then printing is not working since the content is not visible
CSHTML:
<div id="printdiv"/>
JS:
Myapp.printdiv.show(viewData.view);
window.print();
Init.JS
Myapp.addRegions({
printdiv: '#printdiv',
});
Please help me to resolve this issue
Thanks
The best way to handle this sort of problem is with a print-specific stylesheet. This article explains how to do that in detail, but the short version is that you define your non-print styles as normal, then use CSS code like the following to override print-specific styles:
#printdiv {
display: none
}
#media print {
#printdiv {
display: block;
}
}

Resources