TYPO3 / OwlSlider PageSpeed Insights - Unable to optimize due to deffer - javascript

I have a TYPO3 Page where i need to get a score above 90.
For this in particular i've already set jQuery, OwlCarousel and the initating script to defer.
However, if i keep the Slider away from loading, i get a 97 Score.
If i keep it, it goes down as far as 71.
"Reduce initial response time of the server" comes around if i load it all defer.
As for my understanding, this happens because it loads the HTML and seperatly the JavaScript.
But that will make the Slider load later ofc. because the document gets first loaded.
But if i will load jQuery, OwlCarousel and the init-script without defer the score also will get to 74.
I dont see a solution here, any tipps?
var slider = '.slider-owl-268';
var tnav = true;
var amount = 1;
var dautoplay = false;
amount = parseInt(amount);
var tdots = true;
$(slider).owlCarousel({
items: amount,
lazyLoad:true,
loop: true,
margin: 15,
autoplay: dautoplay,
autoHeight: true,
nav: tnav,
dots: tdots,
fluidSpeed: 1,
responsiveClass: true
});
$( ".owl-prev").html('');
$( ".owl-next").html('');
Edit:
A Tip i might have, atleast Layout Shifting can be eleminated trough setting the Slider visible in min-height with Styles.
It does not solve the defer Problem but at least the user see's no shifting and it gives a few bonus points.
With Cache-TTL and eliminating Layout Shifting i could get a score of 96 without using defer.
I wish i could but atleast i reached my goal. Should i clouse the question #mods?

Related

jquery owl-carousel owl-dots class issue

I get some problem when I use owl-carousel in my Rails project.
when I go back to the cached page of my browsers which is using carousel class, I get too many carousel owl-dot classes in my page,this is my
JS code
function initScrollboxHobby() {
var owl = $(".owl-carousel");
owl.owlCarousel({
// loop: true,
items: 1,
nav: true
});
}
and issue HTML code
How to fix it ?
I guess you are using turboinks and when you go back the page is cached by it and when it loads it reruns the owl carousel init function.
The problem, básically, is that turbolinks doesn't play well with non-idempotent functions https://github.com/turbolinks/turbolinks#making-transformations-idempotent
I've managed to make a workaround for this problem with other js plugins, so it should work for you.
Básically, the idea is:
First, when the user enters the page for the first time, copy the content of the element with class .owl-carousel on itself as a data attribute
carousel = $('.owl-carousel');
carousel.data('originalHtml', carousel.html();
carousel.owlCarousel(....)
Then, when the users goes back, before initializing the carousel, check if it was initialized and cached, in that case, first replace the content with the original and remove classes
carousel = $('.owl-carousel');
if (carousel.hasClass('owl-loaded')) {
carousel.html(carousel.data('originalHTML')).removeClass('owl-theme owl-loaded owl-drag');
}
carousel.owlCarousel(....)
You can mix both steps into one:
$(function() {
const carousel = $('.owl-carousel');
if (carousel.hasClass('owl-loaded')) { //if it has the class then it means it's the cached view
carousel.html(carousel.data('originalHTML')).removeClass('owl-theme owl-loaded owl-drag');
} else { // else it's a fresh load of the page
carousel.data('originalHtml', carousel.html());
}
carousel.owlCarousel(....)
})
It's a little bit hacky, but the only way I found to use plugins that are not prepared to work with turbolinks without going through modifying those plugins.
Another option would be to just disable Turbolinks if you thing you just don't need it.
For arieljuod's help of problem reason and my own trying.
I coded like this now.
var owl = $(".owl-carousel");
var owl_navs = $('.owl-carousel .owl-nav');
var owl_dots = $('.owl-carousel .owl-dots');
var owl_cloned = $('.owl-carousel .owl-stage-outer .owl-stage .cloned');
if(owl.hasClass('owl-loaded'))
{
owl_navs.remove();
owl_dots.remove();
owl_cloned.remove();
}
owl.owlCarousel({
loop: true,
items: 1,
nav: true
});
It's tedious but worked well.
Now,I understanded reason.
When I go back to cached page,because I wrote javascript code in my ERB file,in that way, old HTML code may changed.
And then Turbolinks function will run the JS code in that CHANGED new HTML code,Turbolinks must do that,because when I visit cached page again,it will lose all the event binds.
So the whole carousel items will be messy.

jQuery works and doesn't work when it first loads

I have a rails app that I'm trying to implement some jQuery in.
I have two scripts, one that works on first load, and one that requires a reload. I had a problem with the one that works now where I modified the turbolinks in application.js. Now the same problem is happening to another script.
The one that works:
jQuery(document).ready(function($){
//set animation timing
var animationDelay = 5000,
//loading bar effect
barAnimationDelay = 3800,
barWaiting = barAnimationDelay - 3000, //3000 is the duration of the transition on the loading bar - set in the scss/css file
//letters effect
lettersDelay = 50,
//type effect
typeLettersDelay = 150,
selectionDuration = 500,
typeAnimationDelay = selectionDuration + 800,
//clip effect
revealDuration = 600,
revealAnimationDelay = 1500;
initHeadline();
The one that doesn't work:
jQuery(document).ready(function($){
//if you change this breakpoint in the style.css file (or _layout.scss if you use SASS), don't forget to update this value as well
var MQL = 1170;
//primary navigation slide-in effect
if($(window).width() > MQL) {
var headerHeight = $('.box-header').height();
$(window).on('scroll',
{
previousTop: 0
},
...
...
so on so forth.
Why is this happening? Is there a problem with the CSS or the page in which it's being called?
Turbolinks can cause problems in your Rails app because it tries to save overhead by maintaining assets listed in the <head> element of your page (among other things). When you load a page using a full load (via refresh button), an actual ready event takes place and your scripts work. On the other hand, if you were to visit a page some other way (via link), Turbolinks tries to reuse the <head> element, so there's no ready event fired.
The solution in the past was to simply disable Turbolinks, either entirely, by removing its require line in application.js or by link (data: {no_turbolink: true}). With Rails 4.2.x and 5.x, you can listen for a Turbolinks related event that should work where a normal ready event would have worked before.
From the documentation:
However, because Turbolinks overrides the normal page loading process,
the event that this relies on will not be fired. If you have code that
looks like this
$(document).ready ->
alert "page has loaded!"
you must change your code to do this instead:
$(document).on "turbolinks:load", ->
alert "page has loaded!"
(quote rearranged slightly for clarity)

Slick Carousel Blank

I set up an overlay slick carousel, so when you click on the image a larger carousel appears with the selected image as the initialSlide. However, Slick carousel is adding several blank slides after the initialSlide. The blanks only appear when you click next starting with the third slide. When you click on the previous button the blank slides do not appear. What am I doing wrong?
$("#sync1 .item").on("click", function() {
var index = $(this).attr("data-slick-index");
$(".overlay-carousel-container").css("display", "block");
$("body").css("overflow", "hidden");
$("#overlayCarousel").slick({
slidesToShow: 1,
slidesToScroll: 1,
fade: true,
initialSlide: index,
focusOnSelect: true
});
})
$(".close").on("click", function() {
$(".overlay-carousel-container").css("display","none");
$("body").css("overflow", "inherit");
$("#overlayCarousel").slick("unslick");
$("#executiveOverlay").slick("unslick");
});
The Jquery attr() function returns a string value. When you pass that into the slick constructor function it translates it to a different number.
Adding a simple Number() function to change the index to numeric should solve your problem. Just place the following middle line between the lines I placed it:
var index = $(this).attr("data-slick-index");
index = Number(index);
$(".overlay-carousel-container").css("display", "block");
This answer is for the people who are struggling slick carousal as I also faced a lot of problem with it, even though it seems very easy as mentioned but I found out that it has lots limitation.
Very old
To have exact same look like mentioned it needs CSS(SCSS) which is difficult to do in development which as a new user I realised it quite late. Or you don't get dots and arrows with the same exact look easily.
Several other issues like the one mentioned here and other I found over stack flow.
The best one I resorted to for similar process is the one mentioned here
it's latest
and comes with a simple tutorial as well
Recommended for new beginner developers.

How to set SWIPER start with the first slide?

I have an issue with the swiper (http://www.idangero.us/sliders/swiper/api.php)... I am on page 1 and when I swich to the page 2 I want the slider to start with the first slide. I set mySwiper.swipeTo(0, 0, false); on pagebeforeshow and it doesnt work. the STRANGEST thing is that it works perfectly if I swich to second or third slide (ex mySwiper.swipeTo(1, 0, false) or mySwiper.swipeTo(2, 0, false)) but on the first one (0) it simply doesn't swich. Why is that? I tried every possible thing. It doesn't switch on the first slide, only on others. The only method that works is onpageshow but its ugly because first it shows one slide and after another..
I also tried with mySwiper.swipePrev(); a few times but its blocking on slide 2.. It wont go on the first slide.
UPDATE:
here's the jsfiddle example: http://jsfiddle.net/alecstheone/9VBha/103/
so... if I go to second page and I swipe to the third slide than I right click and go back, than back to page 2 the swiper is still on the slide 3 and it should be on page 1 as I set
mySwiper.swipeTo(0, 1, true);
If I set:
mySwiper.swipeTo(1, 1, true);
or
mySwiper.swipeTo(2, 1, true);
it works... only on 0 it wont...
I also noticed that in the 1.8.0 version of the swiper it works that command, but in the latest (2.6.0) it wont.
const swiper2 = new Swiper('.swiper-container2', {
direction: 'vertical',
slidesPerView: 1,
initialSlide: 2,
});
you can use initialSlide to set first slide
If you look up the method swipeTo() in the library you'll find the following condition:
if (index > (_this.slides.length - 1) || index < 0) return;
Which indicates you can only use this method from index 1.
Why don't you just initialize the plugin without the pageBeforeShow option? It should take the first slide.
UPDATE
Finally got it to work and I also hope the author reads this since this is a terrible library to setup as the configuration parameters go berzerk throughout the whole script.
$(page2).click(function () {
//mySwiper.activeIndex = 0;
//mySwiper.startAutoplay();
//mySwiper.swipeReset();
//mySwiper.reInit(true);
setTimeout(function(){
// to make sure the swiper-wrapper is shown after the animation of $.mobile.changePage()
mySwiper.swipeTo(0);
}, 200);
$.mobile.changePage(page2);
// $("#photo").hide().delay(1000).fadeOut();
// $("#photo").animate({opacity: 0.0}, 1);
});
As you can see, the commented functionality seems straightforward but only brings frustration to the people using this. For me this is a design flaw in naming convention and boolean traps.
I also noticed you set height and width dynamically and I'm sure there "is a way" to let the script calculate these parameters as it uses a polyfill for getComputedStyle(). Or you might try to use CSS3 calc() to take some performance hit out of JS.
Second time I use this library and again I had to use the unminified version to debug the functions and it's parameter setup which doesn't work together very well. Only a set of combinations can make this library work and it's up to the developer to figure this whole bunch out.
Good luck on the script and note that the provided code really helped (very quickly) in understanding the problem.
DEMO
I had the same problem few months after this discussion.
I know it's a ugly way to fix the problem, but its the only way I found :
When you call mySwiper.swipeTo(0), this line below :
if (newPosition === currentPosition) return false;
will return false and not apply the swipe, because newPosition = 0 and currentPosition = 0
so i changed this line on the method to
if (newPosition === currentPosition && newPosition !== 0) return false;
and it works now fine.
Since this does not work
mySwiper.swipeTo(0, 1, false)
you could also force it like
var swiper = new Swiper(
".swiper-container",
slideConfigs
);
swiper.on('beforeInit', function () {
swiper.slideTo(1, 1, false)
swiper.slidePrev(1, false)
})
swiper.init()
And don't forget to add this to your configs
init: false,

Javascript making text slide in from html

I am trying to make a text-slide-in effect on a web page. I am using the javascript slidesjs library because it seemed like the best fit. However, I cannot make it work when triggered by a web click.
I have a live example running at: http://107.22.173.10
Note that when you click the "GOTO" links nothing happens.
The basic code is as follows and it seems the page is supposed to automatically put '#' anchors in to trigger the slides. I can't make this work, or figure out how to debug this.
$(function(){
// Set starting slide to 1
var startSlide = 1;
// Get slide number if it exists
if (window.location.hash) {
startSlide = window.location.hash.replace('#','');
}
// Initialize Slides
$('#slides').slides({
preload: true,
preloadImage: 'img/loading.gif',
generatePagination: true,
//play: 5000,
//pause: 2500,
hoverPause: true,
// Get the starting slide
start: startSlide,
animationComplete: function(current){
// Set the slide number as a hash
window.location.hash = '#' + current;
}
});
});
Does anyone see what's going wrong here?
What is the best way to debug this problem?
Is there a better way or library I should be using?
Any advice is appreciated. Thanks!!
You're not following the example from slidesjs.com. See "Basic HTML structure". You're putting only one element in the #slides_container div, and assign all sorts of weird absolute positioning to it, which of course won't work with the animation code.
Copy paste the example first, then start adding your own tweaks concerning style.

Categories

Resources