cover image from resulttesting.com
Optimisation is a very popular concept in build websites or apps, and I’d like to think in software in general.
When building and hosting websites( in react ) you might notice that the speed to load up these web pages differ a bit, usually websites load up faster on the localhost than on an external web server, depending on how fast or slow the users internet connection is ( websites on localhost could also be slower ).
As websites are usually available in almost every part of the world, including places with considerably slower connection, we need to help out to give the user a better experience with our website or app.
I explain some concepts you might consider to achieve this experience, in the paragraphs below. However I’d like to say that optimisation just for the case of optimisation in some cases might not be a good idea.
lazy
When a user loads a website ( presumably your website) for the first time and lands on the home page or landing page, every other page loads up too, even if the user has not clicked to open them up, or may never even open them up.
This increases the time it takes the load the website overall, what we might want to do in this case is to load up or ‘request' the web pages after the user has clicked to open them up.
We do that with lazy .
Import React, { lazy} from ‘ react ‘;
import Homepage from ‘./homepage';
const ContactPage = lazy(() => import (‘./contact-page'));
const App = () => (
<Route to = ‘/’ component = { Homepage } >
<Route to = ‘/contact’ component = { ContactPage } >
)
explanation
The contact page( the component we render in the route , once the path ‘/contact matches ) is imported using the lazy function.
This enables us to requests for the contact-page after the user as clicked on the link.
suspense
As our lazy renders webpages almost asynchronously, there can be a moment where our webpage might not be available the exact moment our user clicks on the link to ‘request' for the page.
We use the suspense to handle situations like that efficiently.
Import React, { suspense, lazy } from ‘ react ‘;
import Homepage from ‘./homepage';
const ContactPage = lazy(() => import (‘./contact-page');
const App = () => (
<Route to = ‘/’ component = { Homepage } >
<Suspense fallback = {component we want to render} >
<Route to = ‘/contact’ component = { ContactPage } >
</Suspense>
)
explanation
We wrap the suspense around the routes that ‘route' to pages that lazy renders quasi-asynchronously.
The fallback's value, is the component we would want to render while we are waiting for the webpages to come in. The component we usually want to render would be one that’s a spinner or a loader of some sort.
Error Boundary
Now as asynchronous functions sometimes do, sometimes lazy loading a webpage fails, and we handle that possibility with an error boundary component.
example
class ErrorBoundary extends React.Component {
constructor(){
super();
this.state = {
isError : false
}
}
static getDerivedStateFromError(error){
return { isError : true };
}
componentDidCatch( error, info ) {
console.log( error );
}
render(){
if ( this.state.isError ){
<div> Something went wrong </div>
}
return this.props.children
}
export default ErrorBoundary;
explanation
By using static getDerivedStateFromError we let the component know it’s not an ordinary component but in fact an error boundary component.
The static getDerivedStateFromError takes in a parameter which is the error it catches, this in turns changes the isError property instantiated in our component state to true.
Changing the isError boolean value is the way the component becomes aware of the error.
Depending on the value of the isError we either render a div stating that something went wrong ( if isError is true ) or the children of the error boundary component ( the components that we wrap inside the error boundary component ) if isError is false.
The componentDidCatch takes in 2 parameters, the error and the info. The error is the error message and the info gives info about the error, like which component gave off the error etc.
Example below.
//App.js
Import React, { suspense, lazy } from ‘ react ‘;
Import ErrorBoundary from ‘./error-boundary';
Const ContactPage = lazy{() => import ( ‘./contact-page' ) );
const App = () => {
render(){
<ErrorBoundary>
<Suspense fallback = { component we want to render } >
< Route to = ‘/contact' component = { ContactPage } >
</Suspense >
</ErrorBoundary >
}
The entirety of the piece of component that the error boundary component is wrapped around, would be passed in as the children in the props.
conclusion
We have learnt that optimisation of our websites is a good thing, but sometimes it really isn’t, it is, I think good practice to write the codes and after hosting check if there are any slowdowns or any issues. Then fix it. As too many optimizations can averse effect and actually slow down your website.
Remember , “If it’s not broken, do not fix it “.
Thank you and Happy coding!