Using image urls vs importing images locally - reactjs

Is it generally better performing to use an image by referencing it with an url or by downloading it, saving it to some directory, and then importing it in a component?
Eg
<img src="images.google.com/example.png" />
vs
import Example from './static/example.png';
<img src={Example} />

Since React doesn't have any means of loading or serving image data, this question is inherently about other tooling, like Webpack.
Storing images locally and loading them via webpack has the benefit of being able to process them with your Webpack loaders, which enables things like inlining them (via base64 resource URLs) when they're small enough and fingerprinting them. You'll still want to deploy those final assets somewhere that gets wrapped in a CDN, though.
Referencing remote images via string URL alone has the advantage of not having sizeable binary images bloating your SCM repository, not needing to import each image explicitly (remember, there are no glob imports in Webpack), and reducing your webpack build times.
I suspect most React apps are going to end up using both, usually in different use cases. I always use local images for logos and app assets for example, whereas I'll reference external files for any user-uploaded content or larger JPG/PNG assets.

CDNs are usually preferred for delivering static files such as images. Due to the fact that the Google Cloud CDN caches your files through its edge servers, your visitors will have their static content delivered to them from the closest point of presence instead of originating from the same server your application is running from.
Having your static content served and cached in multiple geographical locations around the world ensures an optimal content delivery time.
Developing locally however, you may notice that having your static content locally is faster. This is normal, because you're fetching an image over the internet vs from your local hard drive. However, once your app will be deployed and running (say from Canada), visitor A who is from Eastern Europe may be experiencing slower delivery times than visitor B who is from the States. Because you are serving a global customer base from one geographical location, your visitors from the a completely different timezone will receive an unfair treatment in the time it takes for their content to be delivered.
In another perspective, why not both? Have your application serve static content from a CDN but also have your static content on the same application folder and gracefully fall to the local one if the CDN fails.
TL;DR
Serve your images from a CDN ( url ) if you have a large customer base for optimization.

Related

How to load JSON data (that will generate dynamic UI) from a 10 MB static file in React (CRA) - place in public/ or src/ or from backend API?

Situation:
React code generates a base UI
It has to use data from a JSON file (generated by another script that I can manage) to load different UI elements like text boxes and dropdowns dynamically
Options I've considered:
Place it in src/ folder and import it (e.g., import data from '../data.json';)
Place it in public/ folder
I've seen Using the Public folder (CRA Docs) and couldn't find this scenario in the use cases mentioned
Load it dynamically via an XHR request (from backend API)
Right now, the UI functions independently. I'll have to create a backend API server exclusively for serving this JSON file.
Is there any other option that is useful here?
Other points that may be relevant:
Although it's static, there may be changes to the JSON file from time to time (say, every week or month)
The size may increase gradually in the future, but not by a huge margin (say, to 100 MB or so - it'll still be around 10-20 MB)
I'm using CRA and npm run build to create the build. I have never configured webpack manually before. I don't know much about it.
The size is actually 7 MB now. Minified size is 1.9 MB.

What is the difference between `next export` and just using React?

So I get the difference between next build && next export and next build && next start from here.
In short, next build && next export generates a fully static app which does not require a server to host, whereas next build && next start starts a server which renders and serves content.
My question is then, how is next build && next export different from just using React? Seems both approaches generate static files (html, css, js). If I want to optimize SEO, is next export better than using react?
There are many ways to create a React web app. And there are many types of them as well.
Client-Side Rendering
Noticeable toolchain: Create React App
Everything is done on the client side. You send a blank HTML file and various JS bundles to the browser. And the browser parses the bundle and renders contents on the HTML and presents it to the users.
It takes less effort to set up so it best suits small projects.
This is properly what you were referring to when you said: "just using React".
Server-Side Rendering
Noticeable Toolchain: Next.js
Most of the works is done on the server-side. When a user requests to view a page, the server generates the need HTML file dynamically with static contents in it. Then, it sends the file to the user together with JS bundles for interactive content. The browser then attaches those JS to the HTML and present it to the users.
It requires far more effort to set up compared to Create React App. It best suits mid to large projects.
Static Site Generator (Prerender)
Noticeable Toolchain: Gatsby
Similar to Next.js, but instead of generating the HTML dynamically. It generates ALL OF THEM at build time and just sends it to users upon being requested.
This property has the best performance overall. But it can become a nightmare when the site is growing bigger and have hundreds of pages. Building a large, static Gatsby site takes ages to complete.
p.s. Next.js is also capable of generating static sites, but why don't you pick the right tool which is designed and optimized for generating a static site in the first place?
Answering my own question after I tried the following:
Launch a create-next-app then do next build && next export
Launch a create-react-app then do yarn build
Compare out/index.html in the next app and build/index.html in the react app
I found out that out/index.html actually contains all the static contents, whereas build/index.html contains nothing but <script> elements in its <body>. Everything including paragraphs (<p> elements) are later generated (or hydrated) when opened in the browser.
So in conclusion, even though both Next and React can be used to generate static site (SSG), Next is still better for SEO purposes since the contents are already in the html file.
Next.js can be used as static side builder (in the case you are referencing) which means it will generate all of you html at the time of build and along provide some performance features.
React(if not used on server) will always just have 1 HTML page which then loads of all your App(or chunks if you are code splitting) when the client requests it.
If you are not familiar about the concept read more on Static side building.
For SEO purposes using Next.js with either static or server side rendering would be the best approach since everything is prebuilt and easily accessible by robots(Although Google bot should already read javascript apps as well).

What is the reason behind having data URI instead of path for images less than 10kb in React?

In the Create React App documentation inside the Adding Images, Fonts, and Files section, they say :
importing images that
are less than 10,000 bytes returns a data URI instead of a path. This
applies to the following file extensions: bmp, gif, jpg, jpeg, and
png.
The reason for them is :
To reduce the number of requests to the server
But is it specific to how React works (updating the DOM for example) or it's a wide spread practice in web development in order to reduce load times?
This is not a practice that's particular to React. Whether something gets rendered via React or by ordinary HTML, if an image is rendered using a data URI, if the data URI exists in the code already (either bundled inside the JS or hard-coded into the HTML), no additional requests to the server will have to be made.
In contrast, if you have something like src="theImage.png", that'll result in a request to the server to download the image.
it's a wide spread practice in web development in order to reduce load times?
Yes.
If, for example, the web server was using HTTP 1.1, and you had, say, 25 images with srcs pointing to different files, the sheer number of separate requests could present a problem - regardless of whether React was being used or not.
(HTTP/2 mitigates this problem at least somewhat - see here)

Single Page Application Slow to Load all Files

I have been using Asp.Net Core MVC to load views and their content for several years. However, the trend seems to be pushing us strongly towards Single Page Applications (SPA). From my understanding, all html files are downloaded directly to the client. From now on we don't need to make requests to a server anymore in order to receive HTML, CSS, etc. because the routing of Vue (if configured properly) will serve the appropriate components.
All of this makes a lot of sense to me and seems like a good option. The thing I don't understand or am worried about is the loading time. Wouldn't it be extremly slow to download all files the first time when the website is called?

Grails Asset Pipeline: URLs within static assets

In Grails Asset Pipeline, I am serving HTML, js, CSS, and image files.
In an HTML asset, if I need to supply a src for an image, how should I write that URL to take into account:
that assets might be served from a different base URL, as specified by grails.assets.url
that assets might be served from the Grails server (in dev mode), but under a potentially variable app context
I can think of the following solutions:
always use relative paths between assets.
The problem with this is that if I ever move an asset, then all of its relative links must change.
Another possible issue would be that, if I somehow made Asset Pipeline route proprietary assets to my own static server, and thrid-party assets to public CDNs (e.g., https://ajax.googleapis.com/ajax/libs for angularjs, jquery, etc.), then any static relative URLs wouldn't work.
I assume that I shouldn't ever directly reference js and/or css files outside of Asset Pipeline manifests, so, unless that's wrong, then this problem shouldn't occur for those file types, but, if there's a CDN for common images (does such a thing exist?), then static relative URLs in html files wouldn't work in img src attributes.
angularjs & a javascript variable set via a gsp
Use angularjs in the html file to read a javascript variable that contains the base URL. Set the base URL in a gsp that is referenced by every page.
The problems with this are:
that a separate request for the gsp is necessary (though it should be able to be cached for a long time). Is it possible to compile a gsp at build-time into a js file, and copy the result as an asset, so that it could be included in the Asset Pipeline static bundle rather than served from my Grails server?
that browser cycles are used processing the angularjs code
that certain third-party javascript libraries don't play well with angularjs, so it might be complex to get them working with this setup
from what I know, url() calls in css would still have to be relative, since angularjs wouldn't be able to influence them. Maybe I could use one of the css wrapper languages, like less, but this option is getting much more complicated than option 1...
Are there any other viable options?
Are there any other cons and/or gotchas to either option that I've mentioned above?
I'm using the current version of Asset Pipeline (2.2.5), and the latest version of Grails 2.x (2.5.0).

Resources