Render an image conditionally in Vue with file loader - image

I'm using Webpack to compile my Vue production bundle and it loads my images properly because they are defined used <img> tags in my component. I want to load an additional image and show it based on a condition. Since the image isn't set initially in an <img> tag Webpack isn't loading it using file-loader. When I call:
event.currentTarget.children[2].innerHTML = "<img src='../assets/imgs/heart.png' />"
This doesn't work because heart.png was never processed by file-loader, while my previous images were. Any ideas on how to force Webpack to process this image without defining it in HTML my component. My other images (that work) look like this : <img src="data:image/png;base64,iVBORw0KGgo...=="> I understand why my image isn't loading (it's defined in a string), buy any suggestions?

Related

Where to put images with SvelteKit

I have been using Svelte for a little while and now I have switched to SvelteKit so I can add multiple pages. I want to add some images to my site but I don't know where to put them. In Svelte I would just put them in public/images but there is no public folder with SvelteKit (I set it up with npm init svelte#next my-app if that matters). Would I put them in static?
Thanks!
I added the images in static/images and referenced them with src="/images/photo.jpg" like #b2m9 said and it works perfectly.
I recommend putting images under src/lib, not static. For example you could make a src/lib/images or src/lib/assets folder and put them there.
The reason is performance:
For files imported from anywhere under src, at compile time Vite adds a hash to the filename. myImage.png might end up as myImage-a89cfcb3.png. The hash is based on the image contents. So if you change the image, it gets a new hash. This enables the server to send a very long cache expiration to the browser, so the browser can cache it forever or until it changes. It's key-based cache expiration, which IMO is the best kind: cached exactly as long as it needs to be. (Whether the server actually sends the right caching headers in the response may depend on which SvelteKit adapter you use and what host you're on.)
By contrast, images under static don't have a hash added to their name. You can use the static directory for things like robots.txt that need to have a specific filename. Since the filename stays unchanged even if its contents change these files by necessity end up having a cache-control value that includes max-age=0, must-revalidate and an etag, which means even if the browser caches the image it still has to make a server round-trip to validate that the cached image is correct. This slows down every image on your site.
Usage:
When putting images under src/lib, you reference them like this:
<script>
import img from '$lib/images/img.png';
</script>
<img src={img} alt="Image" />
I recommend simplifying by adding svelte-preprocess-import-assets to your project, which automates the process of importing images and cleans up your code. You wrote the following and it generates the code above:
<img src="$lib/images/img.png" alt="Image" />
As Sveltekit uses Vitejs, there is a easy solution mentioned in Vitejs official web site (Click Here).
First inside the script tag :
<script>
const imgUrl = new URL('./img.png', import.meta.url).href
</script>
then inside your Image tag just use that variable,
<img src="{imgUrl}" alt="" />
or,
<div class=" h-screen w-full" style="background-image: url('{bgUrl}') ;">
</div>
You can import static images from any relative path.
there is also svelte-image.
"Svelte image is a pre-processor which automates image optimization using sharp.
It parses your img tags, optimizes or inlines them and replaces src accordingly. (External images are not optimized.)
Image component enables lazyloading and serving multiple sizes via srcset.
This package is heavily inspired by gatsby image.
Kudos to #jkdoshi for great video tutorial to Svelte Image."
-https://github.com/matyunya/svelte-image

Linking to image from cutom component in VuePress

I want to display an image in my VuePress markdown file. Normally, I'd go with:
![My Image](./resources/myimg.png)
However, I'd like to create a custom Vue component that will style the images in a specific way. Then, some images would be displayed using the "standard" markdown syntax (like above), and some others using my custom component.
With my custom component, I'd display the images like this:
<MyComponent src="./resources/myimg.png"/>
As you can see, the images are placed alongside my markdowns, in a resources directory. This makes sense for me, because the image is close to the markdown where it gets displayed.
Unfortunately, the image does not get displayed when I use MyComponent. VuePress (webpack?) handles the images during build and places them in some other directory with a different name. The "standard" Markdown image reference works fine, its URL to the image is set up correctly by VuePress. However, MyComponent does not work, because the src parameter is just a string for VuePress and it does not transform it in any way.
I know that one solution would be to place my images in the /vuepress/public folder. However, I would want to keep the same organization as I have now - images alongside documents.
How can I achieve that?
I had the same issue.
I used the answer #papey provides for a Vue question here
Here is one thing he suggests
<template>
<div id="app">
<img :src="require('./assets/logo.png')"/>
</div>
</template>
<script>
export default {
}
</script>
<style lang="css">
</style>

Elimante render-blocking resources

I'm trying to optimalize web for speed and wanna ask about Eliminating render-blocking CSS and JS.
by JS 'm only using async attr. - lets say, throwin' it at plugins like flexslider, lightbox.. but should I also use this with the base scripts like ?:
<script src="https://cdnjs.cloudflare.com/.../4.5.3/js/bootstrap.min.js" async></script>
<script src="js/script.js" async></script>
Whenever i add async on some script and test it, that .js script won't just operate - as if not linked. What am I doing wrong? And is this enough ... ?
-by CSS - tring to impove it like this :
<link rel="preload" href="https://use.fontawesome.com/releases/v5.2.0/css/all.css" media="print" as="style" onload="this.onload=null;this.rel='stylesheet'" integrity="sha384-hWVjflwFxL6sNzntih27bfxkr27PmbbK/iSvJ+a4+0owXq79v+lsFkW54bOGbiDQ" crossorigin="anonymous"><noscript><link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.2.0/css/all.css"></noscript>
This cuts down the time of rendering CSS resources, but again when using it on e.g fontawesome - icons are not loaded as if link was't there...So, is this a good way of rendering CSS please ?
JavaScript
When using async you have to ensure that load order does not affect your implementation.
Async basically says "load everything as quickly as you can, I don't care about load order".
If you haven't accounted for this then the easiest fix is to use defer on your JavaScript instead of async. This basically says "load everything after the HTML has loaded but please keep the order as some scripts depend on others".
This will be slightly slower overall but still fix the JavaScript being render blocking.
You should defer all scripts, except any scripts that are essential for above the fold operations (and then you should inline those scripts in a <script> tag in the <header>, obviously keep this to a minimum).
CSS
Render blocking CSS is anything sitting in an external file that relates to content "above the fold".
To understand this fully you need to understand how the browser render things but in essence anything that is visible without scrolling ("above the fold" content) is delayed if your CSS is in an external file as it needs that information to know how to present and lay things out.
What you need to do is find all the styles that apply to your above the fold content and inline them in a <style> tag in the page <header>. Yet again this needs to be kept to a minimum so you may need to make the above the fold CSS custom rather than using bootstrap....including the whole of bootstrap inline would not be good!
Then all other styles can sit in external style sheets.
This way the second the page's HTML is downloaded it has everything it needs to layout the page without waiting for any other requests.
Font Awesome
Ah fonts for icons. I won't go into why that is a bad practice from an accessibility and performance perspective as I have covered that numerous times before.
Instead I will simply say that for any "above the fold" icons you should instead swap them for inline SVGs. This is for the same reason as inlining your CSS, inline SVGs do not need a network request to render so the second the HTML is loaded your page can be displayed.
just a suggestion, have no way of testing atm but try putting 'async' before the source attribute. also, try adding a copied line with the attribute defer instead of async for wider browser support.

Disable image links if Retina detected

I currently use retina.js to load Retina-optimised images on my website.
It is great, but renders redundant all thumbnail links to larger images (which load with Fancybox).
My question is how can I disable all links to images if Retina is detected? (At least until I have a higher-res camera.)
Regards
Paul
If you want just some images on your page to be excluded from retina.js, you have to add the data-no-retina attribute to the tag, like this:
<img src="yourImage.jpg" data-no-retina />
If you want to disable the links created by Fancybox, you have to modify the Fancybox source itself.

Ajax request gif

I have seen that an animated loading gif loads when a an ajax request is being processed. I was wondering how this was done.
For example, there are a lot of images that are loaded from css file. Can I make a loading gif appear until these images are loaded.
Do you mean smth. like this:
http://api.jquery.com/ajaxStart/
or this: How to show loading spinner in jQuery?
You don't really mean Ajax. The images declared in css are loaded by the browser normally.
You need the load event, try this:
1 - Create an element with id yourDivIdWithLoadingElement in your html page which will be shown until all images has been loaded
<div id="yourDivIdWithLoadingElement:>Loading content...</div>
2 - Add this script in your header:
$(window).load(function () {
$('#yourDivIdWithLoadingElement').hide();
});
I dont know if you are using ASP.NET MVC?
If that is the case you can use an #Ajax.ActionLink and put your loading gif in an img tag specifying the id in your actionlink's AjaxOptions in the LoadingElementId.
It would look somehow like this
#Ajax.ActionLink("MyAction", "MyController", new AjaxOptions(){LoadingElementId = "MyGif"})
It will then hide the img gif until the actionlink is triggered. Sometimes you will need to hide it yourself using css, but as far as I remember that is not the case when you are just using an img tag

Resources