VUE.JS - How to improve performance when loading a static image - javascript

I have a simple application in Vue.js and I have a component that loads 1 image and 2 texts on the screen, very simple.
However I noticed that every time the image takes a few milliseconds to load than the texts, giving an impression of slowness.
One more piece of information, sometimes it loads quickly and sometimes it takes a while to load. Does this have to do with my machine's performance?
Is there a way for me to optimize this image loading so that it doesn't show the customer this loading?
**Dispenser.vue**
<template>
<div>
<gui-action1 :imageName="this.imageName" :title="this.title" :message="this.message" :showLoader="false">
</gui-action1>
</div>
</template>
<script>
import Action1 from '../../Guidance/Action1.vue'
export default {
data(){
return{
optionSelected: this.$route.params.optionSelected,
imageName: 'Organization_Image_Interaction_WaitCountReal',
title: 'Ainda não finalizamos',
message: 'Aguarde a contagem das notas'
}
},
components: {
'gui-action1': Action1
},
created(){
setTimeout( () => this.$router.push({ path: "/withdraw/finishing"}), 4000);
}
}
</script>
<style >
#media screen and (max-width: 1280px) {
}
</style>
**Action.vue (Component)**
<template>
<div class="guidance">
<div class="guidance-title" >
{{title}}
</div>
<div class="guidance-image" >
<img :src="require('../../../static/' +`${imageName}`+ '.svg')">
</div>
<div class="guidance-message" >
{{message}}
</div>
<div v-bind:class="{ 'loader': showLoader }" ></div>
</div>
</template>
<script>
export default {
props: ['imageName', 'title', 'message', 'showLoader'],
data(){
return{
imageNameDefault: 'Organization_Image_Interaction_WaitCountReal'
}
}
}
</script>
<style>
#media screen and (max-width: 1280px) {
.guidance{
position: relative;
top: 70px;
left: 30px;
}
.guidance-image{
position: relative;
top:200px;
left: 220px;
}
.guidance-title{
position: relative;
top:140px;
left: -40px;
font-size: 55px;
color: white;
text-align: center;
}
.guidance-message{
position: absolute;
width: 100%;
top:650px;
left: -40px;
font-size: 55px;
color: white;
text-align: center;
}
.loader {
border: 7px solid #f3f3f3; /* Light grey */
border-top: 7px solid #386083; /* Blue */
border-radius: 50%;
width: 130px;
height: 130px;
animation: spin 1.5s linear infinite;
position: relative;
left: 518px;
top: -80px;
opacity: 60%;
}
#keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
}
</style>

You could use cloudinary-vue for some super simple but performant image loading.
It could allow for some simple image placeholder while loading with only
<cld-image
public-id="sample"
loading="lazy">
<cld-placeholder
type="vectorize">
</cld-placeholder>
</cld-image>
Here is a Gatsby.js (React) demo but it show pretty clearly how it works with Cloudinary: https://using-gatsby-image.gatsbyjs.org/blur-up/ (click on Blur up, Traced SVG etc on top of the page).
Ofc, Cloudinary will also resize it to your screen accordingly, may format it into .webp or even .avif (beta), serve it from a cool CDN and do can do a lot of plenty other stuff. Cannot recommend it enough tbh. Check their documentation and give it a try, it's free so you don't have much to lose.
There is a LOT to webperf (too much for a simple answer here), and here is probably one of the best article (redacted each year) about this topic, you will get an exhaustive list of things to implement if you want a blazing fast website: https://www.smashingmagazine.com/2021/01/front-end-performance-2021-free-pdf-checklist/

Related

Maintain responsive image height

I am attempting to create a CTA component at the top of my react application, that contains the navbar and the CTA text. After successfully completing the component, I am noticing a minor bug that I would like to resolve. I am only providing my image with a width of 100% and no defined height. This causes the divs beneath the image to flicker upwards until the image has fully loaded. I know not providing the image with a defined height is causing it because the bug goes away when I provide the image with a random height. I am wondering if there is a way to provide the image with a responsive height that would behave in a similar way to just providing my image with 100% width.
my css code is as follows:
body {
margin: 0;
padding: 0;
}
.container {
position: relative;
}
.container .container-background {
opacity: 0.25;
}
.container-background-img {
width: 100%;
position: relative;
}
.container .content {
position: relative;
z-index: 1;
}
.app-outer {
max-width: 1170px;
margin: 0 auto;
position: relative;
padding: 0rem 1rem;
}
#media only screen and (max-width: 1170px) {
.container-background-img {
height: 656px;
object-fit: cover;
}
}
#media only screen and (max-width: 768px) {
.container-background-img {
height: 653px;
object-fit: cover;
}
}
/* CODE ADDED */
#navbar {
position: absolute;
top: 0;
left: 0;
right: 0;
}
#content {
position: absolute;
top: 20%;
}
my jsx code is as follows:
import React from "react";
import "./styles.css";
export default function App() {
return (
<>
<div className="container">
<div className="container-background">
<img
id="rob"
src="https://i.imgur.com/iyFtMNA.jpg"
alt="bg"
className="container-background-img"
/>
</div>
<div id="content" className="content">
I am the CTA
</div>
<div id="navbar">
<div
style={{
backgroundColor: "white",
height: 100,
width: "100%",
display: "flex",
justifyContent: "center",
alignItems: "center"
}}
>
I am the navbar
</div>
</div>
</div>
<div>I am beneath the cta</div>
</>
);
}
the following link I have provided contains a code sandbox: https://codesandbox.io/s/issue-react-forked-4lsdm?file=/src/App.js:0-868
Please Note: *** within the code sandbox the issue is not very apparent, but within my react application it is much more noticeable
As you mentioned, the issue is not really clear to see from your sandbox code.
I am not sure this would fix your issue but instead of using image tag try setting your CTA component to have background-image() instead.
Make sure to add other background css attributes too such as
background-repeat: no-repeat;
background-size: cover;
background-posistion: center;
padding-bottom: 60%;
Make sure to add padding-bottom: 60% (Your image seems to have a 3:2(w:h) ratio);
Hopefully, this works for you!

Zoom Background Image with CSS or JavaScript

I would like to scale the background image of my div over time, so that it looks like it is zooming in and out (without hovering the mouse over - I'm just looking for the animation to start automatically). But, no matter what I try, the background animation just looks choppy.
If I set the div to scale, then the transition is smooth, but it scales the entire div, not just the background image. For additional information, I am running the most recent version of Chrome, and have tried on both Windows and OS. You can see an example here: https://jsfiddle.net/sdqv19a0/
<div class="site-main-banner">
<div class="caption">
<!-- Bootstrap -->
<div class="container">
<div class="row">
<div class="col-xs-12">
<!-- figure -->
<figure> <img src="images/signature.png" alt="signature"> </figure>
<!-- H1 Heading -->
<h1 class="typewrite" data-period="2000" data-type='[ "Purposeful design", "Data-driven marketing", "Dynamic branding", "I love it all." ]'> <span class="wrap"></span> </h1>
<!-- H2 Heading -->
<h2>graphic designer • web designer • analytical marketer</h2>
<div class="clearfix"> </div>
<!-- Button -->
view my portfolio
</div>
</div>
</div>
</div>
CSS:
.site-main-banner {
float:left;
width:100%;
background:url(https://preview.ibb.co/m8kxST/static_banner_new.jpg) no-repeat center center;
background-attachment:fixed;
background-size:cover;
margin: 0;
padding: 0;
display: block;
clear: both;
position: relative;
text-align:center;
overflow: hidden;
animation: shrink 5s infinite alternate steps(60);
}
#keyframes shrink {
0% {
background-size: 110% 110%;
}
100% {
background-size: 100% 100%;
}
}
.site-main-banner a.theme-btn {
color: #FFFFFF;
border:#FFFFFF solid 1px;
background:none;
box-shadow:none;
}
.site-main-banner a.theme-btn:hover {
color: #bc6ca7;
border:#FFFFFF solid 1px;
background:#FFFFFF;
box-shadow:none;
}
.site-main-banner .caption {
position: relative;
float: left;
top: 50%;
left: 50%;
transform: translate(-50%);
padding:300px 0;
}
.site-main-banner figure {
float:left;
width:100%;
text-align:center;
padding:0 0 15px 0;
}
Suggestions? I am open to a js solution, as well, just am not as comfortable with javascript. Thanks!
Separate your background into its own element behind the main banner so you can apply keyframe animations transforming the scale of the background individually instead.
body, html {
margin: 0;
padding: 0;
}
.site-space-background {
position: fixed; height: 100%; width: 100%;
background: #1A1939 no-repeat center center;
background-image: url(https://preview.ibb.co/m8kxST/static_banner_new.jpg);
background-attachment: fixed;
background-size: cover;
animation: shrink 5s infinite alternate steps(60);
}
#keyframes shrink {
0% {
transform: scale(1.2)
}
100% {
transform: scale(1.0)
}
}
<div class="site-space-background"></div>
<div class="site-main-banner">
<!-- The rest -->
</div>
I would use the css transform property in combination with a pseudo element.
.site-main-banner {
position: relative;
overflow: hidden;
}
.site-main-banner:after {
content: “”;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: -1;
background-image: url(...);
// put your animation here
}
I can’t really send you a fully working example as I’m currently on my phone in the subway but I hope you get the idea.
Try using the transform: scale([values]); in your animation.
Using transform element is good for applying scales animation.
Look at this Jsfiddle. I tweaked some of your code (not that much since I only edited your css animation).

set class in css or hover over 2 overlapping divs

Is it possible to give the hover-icon a class, so that the icon is the triggerinfo? The image is in gray when i hover it, it gets colored but I wan't to hover a text when is colored, when I going over the little icon. Is there a way overlapping the div with the triggerinfo class over the image, but not leaving the hover of the image. Like hover the div that is not visible and not leaving the hover effect colored ?
Thanks !
If it helps I can share the link to my website, but only as message not for the public post. It gets more visual, and I think better to understand what I mean.
jQuery(document).ready(function() {
jQuery(".triggerinfo").mouseleave(function() {
jQuery(this).next(".info").hide();
});
jQuery(".triggerinfo").hover(function() {
jQuery(this).next(".info").toggle("fade");
});
});
.info {
display: none;
padding: 10px;
background: #fff;
position: absolute;
box-sizing: border-box;
z-index: 1;
}
.triggerinfo {
display: inline-felx;
opacity: 0.1;
position: absolute;
margin-top: -50px;
margin-left: 30px;
z-index: 3;
}
.uk-overlay-icon:before {
content: "\f0c9";
position: absolute;
top: 90%;
left: 10%;
width: 30px;
height: 30px;
margin-top: -15px;
margin-left: -15px;
font-size: 30px;
line-height: 1;
font-family: FontAwesome;
text-align: center;
color: #f69c00;
}
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div data-uk-filter="dsgf" data-grid-prepared="true" style="position: absolute; box-sizing: border-box; padding-left: 10px; padding-bottom: 10px; top: 0px; left: 0px; opacity: 1;">
<div class="uk-panel">
<div class="uk-panel-teaser">
<figure class="uk-overlay uk-overlay-hover ">
<img src="/wp-content/uploads/bilder/projekte/dsf.jpg" class="uk-overlay-grayscale" alt="dfsg">
<div class="uk-overlay-panel uk-overlay-icon uk-overlay-fade"></div>
<a class="uk-position-cover" href="/wp-content/plugins/widgetkit/cache/nuding-35281426b204ba8667e05928e60e8a11.jpg" data-lightbox-type="image" data-uk-lightbox="{group:'.wk-1b2a'}" title="dsfg"></a>
</figure>
</div>
<div>
<div class="triggerinfo">
sdf
</div>
<div class="info">
<h5>dsfg</h5>
</div>
</div>
</div>
</div>
The Fiddlejsfiddle.net/e8qd8gvf/3/ works now as it should on my site. Now the thing is: on hover the img get colored and it appears a little icon in the bottom left coner, the trigger that is now under the img should be this little icon, because the icon is from the css definition in uk-overlay-icon (from the font awesome)
I dont now how to set the info class on this icon.
Or I was trying put an div with the info class over the img at the position of the icon and than trigger it, but than the colored effekt dont show when I trigger it, so I thought there must be a way to trigger the div on hover and not lose the colored effect, so the trigger div would trigger the Info and musst trigger the hover from the img at the same time
PS: Sorry for the long css !
The <figure> element is intended to mark up diagrams, illustrations, photos, code examples and similar content, "that can be moved away from the main flow of the document without affecting the document’s meaning" (http://w3c.github.io/html-reference/figure.html).
Your way of using it seems to be against this specification.
It's your own responsibility to code according to specification and best practices.
I just opted with your provided example: https://jsfiddle.net/e8qd8gvf/4/
I moved the uk-overlay-icon outside of the figure, added the toggle-info class and put the info box inside it.
All that was left was adding some CSS:
.uk-position-cover { cursor: default; }
.uk-panel-teaser { position: relative; }
.toggle-info {
display: none;
cursor: pointer;
position: absolute; bottom: 20px; left: 20px;
width: 30px; height: 30px;
}
.toggle-info > .info {
width: 150px; height: 150px;
border: 2px solid red;
position: absolute; bottom: -20px; left: 10px;
transform: translateY(100%);
}
.toggle-info, .info { display: inline-block !important; }
.toggle-info.hidden, .info.hidden { display: none !important; }
as well as changing your JS to:
jQuery(document).ready(function() {
jQuery(".uk-overlay").hover(
function() {
jQuery(this).next(".toggle-info").removeClass("hidden");
},
function() {
jQuery(this).next(".toggle-info").addClass("hidden");
}
);
jQuery(".toggle-info").hover(
function() {
jQuery(this)
.removeClass("hidden")
.children(".info").removeClass("hidden");
},
function() {
jQuery(this)
.addClass("hidden")
.children(".info").addClass("hidden");
}
);
});
 
My solution is only showing you a way to accomplish things and is by far not "nice". You need to adapt it yourself and to specifications.

How to fix an image compared with another one in CSS?

http://tree-leaves.comuf.com/
In this website, I want to fix the leaves position just over the branchs of the tree in spite of resizing the window.
For this, I used percentage in the CSS positioning, but when I resize the window, I can see that the leaves aren't perfectly aligned with the branchs.
How can I do to position the leaves with more precision, knowing that the tree and the leaves change their dimensions when we resize the window ?
HTML code :
<pre>
<div id="leaves">
<img src="images/leaf1.svg" id="l_1">
<img src="images/leaf1.svg" id="l_2">
<img src="images/leaf1.svg" id="l_3">
</div>
<div id="content">
<img src="images/tree.svg" id="tree">
</div>
</pre>
CSS code :
#content {
float: left;
width: 100%;
text-align: center;
background: linear-gradient(to bottom, transparent 0%,transparent 85%,#893700 85%,#893700 100%);
}
#tree {
width: 80%;
left: 10%;
z-index: 10;
}
#leaves {
background-color: red;
}
#leaves img {
width: 5%;
}
#l_1 {
margin: 0;
margin-bottom: -4%;
margin-left:5.7%;
transform: rotate(-35deg);
}
#l_2 {
margin: 0;
margin-bottom: 0%;
margin-left: 12.9%;
}
#l_3 {
margin: 0;
margin-bottom: -4%;
margin-left: 7%;
transform: rotate(-5deg);
}
What you can try is using viewport units, such as vw. I have played around seems working good, i.e. for first leaf on the left:
#f_1 {
margin-bottom: -4vw;
margin-left: 5.7vw;
transform: rotate(-35deg);
}
You can just use browser Web Inspector/Developer Tools to adjust the values for each leaf, and save it when you're happy with them all. Obviously, you can also do it on the branches too.
http://caniuse.com/#feat=viewport-units

Adding a card flip animation to this JS card game?

I am playing around with this card game and I want to add a card flip animation.
I have googled for an answer, but most solutions refer to jquery (which I don't want to implement just for 1 animation) or CSS3 (I liked this example). Not much luck there.
The js game uses the following (from cardgamecore.js):
playingCard.redrawCardImage() Forces a card to redraw
playingCard.showFace(bool: face) Sets the card to be either face up or face down, and redraws if needed. true = face up, false = face down.
playingCard.prototype.redrawCardImage = function () {
// Set or change the image showing on the card face
if( !this.faceImage || !this.cardSet.backImage ) { return; }
// Bug in Firefox - alt attributes do not change unless they are made _before_ an SRC change
this.cardImage.setAttribute('alt',this.wayup?(this.cardSet.cardNames[this.number-1]+' '+this.suit):this.cardSet.cardWord);
this.cardImage.src = this.wayup ? this.faceImage : this.cardSet.backImage;
};
playingCard.prototype.showFace = function (oWhich) {
// Used to flip a card over
if( this.redrawNewImage != oWhich ) {
this.wayup = oWhich;
this.redrawCardImage();
}
};
So when a card shows its back then playingCard.showFace = false. When you click on it, playingCard.showFace = trueand the image is redrawn. At this point the card should have a nice flip animation.
But how to do this?
What you want to google search is "css 3 flip animation"
http://davidwalsh.name/demo/css-flip.php
I was doing a card game as well...
First you could write you card like this:
<div class='card' >
<div class='faces'>
<div class='face front'> Hello</div>
<div class='face back'>Goodbye</div>
</div>
</div>
Both faces are accounted for in your html the css will only display one though:
.card {
-webkit-perspective: 800;
width: 50%;
height: 300px;
position: relative;
margin: 3px;
float:left; /*if you want more than one card in a line*/
}
.card .faces.flipped {
-webkit-transform: rotatey(-180deg); /* this style will help the card to rotate */
}
.card .faces {
width: 100%;
height: 100%;
-webkit-transform-style: preserve-3d; /* This is a 3d transformation */
-webkit-transition: 0.5s;/*the animation last 0.5secs*/
}
.card .faces .face {
width: 100%;
height: 100%;
position: absolute;
-webkit-backface-visibility: hidden ; /*hides the back of the card until transform*/
z-index: 2;
font-family: Georgia;
font-size: 3em;
text-align: center;
line-height: 200px;
}
.card .faces .front {
position: absolute;
z-index: 1;
background: black;
color: white;
cursor: pointer;
}
.card .faces .back {
-webkit-transform: rotatey(-180deg); /*allows the flip to the back of the card*/
background-image: url("image.jpg"); /*background image for the back if you want*/
background-size:100%;
color:white;
border:1px solid black;
}
The only thing left to do is add the 'flipped' class. So maybe instead of redrawing.
$(".card").on('click',function(){
$(this).children('.faces').toggleClass('flipped');
});
Here's a FIDDLE
Contacted the author of the script and he told me it is not possible in the current script without re-writing most of the code. So this question can be closed. All thanks for trying to help me.

Categories