I'm developing HTML5 banner ads for Google AdWords with CSS-animations. Since an ad can only have 30 seconds of animations, the content of the different stages in the animation are often not seen by the users.
Is there a way to find out the viewport of the (cross domain) parent window, so that I can start the animations in my ad's CSS/JS code when it's actually visible to the user ?
Thanks for help!
There are two ways how you can solve your problem.
For the first, you need to edit the code of your cross-domain parent window. If you can't do that, this wont work (which I guess will be the case for you). You would need to add event listeners and use Window.postMessage.
The other way is by using the Intersection Observer API. It's exactly the thing you want and designed for exactly your case, but it's currently not very well supported. For compatibility list check out the link or caniuse.
You could implement this with a simple fallback, if it's not available.
Related
I have a single page using CSS columns that reflows on load.
Even when I remove all IMGs and iFrames, so it is fetching no
external resources, it reflows.
I can't figure out what is causing the reflow/repaint. Any CSS exports
out there able to figure this one out?
https://github.com/treenotation/dumbdown/issues/8
There's too much content in document.
The browser will gradually display the content, that is, the content involved in rendering will gradually increase, which affects the layout calculation.
You can add the "loading state" style. When window.onload Event trigger, change the style to "load complete".
Or 'Masonry Layout'.
Reason for the reflow is: a huge amount of content but NO strategy to handle with. Indeed there are many things you can avoid/do/change ...
REASON WHY - just to base the answer ...
The reflow is caused by the mechanic: at first the text (html code) has been downloaded and rendered. But there are still a lot of elements (most over images but youtube videos and iframes as well) which are still on download. As the browser don't know the size of that elements he does not keep the place for that elements.
Now: after the download and rendering of every element has finished the browser injects the element to the content and all off the following content is pushed down and in your case to next column ... reflow.
STRATEGY: MULTIPLE ACTIONS
To your question: there is not only one reason which causes multiple and long downloads. So far there is no simple single answer and even NOT A SINGLE SOLUTION. Your needed strategy will be to optimize the page by a multiple bundle of actions. But I believe doing that you can reduce it to an acceptable amount ... and maybe there is a chance.
THINGS YOU CAN DO
1. Change layout
If you change the layout to an actual web technique. That means don't use columns (flowing left to right) to a style which prepares the pageflow from up to down. Than you can asynchron load the needed elements when the user scrolls down. The technique is named Infinite scrolling: How to do an infinite scroll in plain Javascript
But I assume as the special layout has charm this won't be an option for you!?
2. Images which are not shown - remove not needed elements from download
On your page I found images which are downloaded but which are not shown on the page. (Example: 3.png with INCREDIBILE USELESS 659KB). Remove such elements from your content.
3. Reduce not needed size of elements
Additional a lot of shown images on your page have an incredibly large file size which is not needed.
Example: devices.png
image-size: 692x285px - real size
layout-size: 287x118px - needed size
file-size-download: 110kb
file-size-needed: 4kb - if (lossless) optimized
And think about: many little file downloads add up to a big amount ... and you have a lot of downloads! If you calculate: 10 images your way: 1.1 MB can be done with 40KBs
Additional:
if you you need higher solutions use srcset attributes ...
sometimes that is a practical problem with the knowledge of the editors: than teach them how to lossless reduce images and advise them the sizes to use for the images in the layout
4. Use faster server for images
It seems the download rate from your server is not the fastest one. That's normal by most providers. As you have a lot of images ... think about to load images from a faster server - if possible. Example: the pure download service from AWS (Amazon Web Service) is incredibly fast. As you just need a bucket for downloading that is not as expensive ... try it out.
5. Use placeholders for elements
As you have a lot of elements I think you maybe cannot avoid the later injection which causes the reflow. But you can use placeholders for your element so the needed place is reserved and the reflow still does not happen for this element.
Just define the html structure and possible sizes in your layout. That additional helps the editors as they know what image size they can use. Then size the placeholders with CSS and initiate an ajax image download by JS.
In case of later download now the users maybe see a placeholder at the beginning but no reflow. You can do that with few lines of code. I attach an example at the end of the posting.
NOTE: You can do this with (youtube-)videos or iframes in a similar way ;-)
6. Use vanilla instead of jQuery
As I saw has the download of jQuery an incredible impact to your download time. Really. (That's the reason why I assume your server is a slower one.) Have a look to the download time of your elements. It is one of the elements which needs the most times and blocks your elements from rendering.
jQuery is an old dog. Modern web techniques use vanilla JS ... and as I see there are no complicated things on your page you cannot realize in vanilla. So the recommendation is to remove it from you page (if possible) and you will earn a huge speed advantage.
7. Use CDNs for download when possible
Downloading frameworks and fonts from own server makes pages slow and blocks time for the page download of other elements. Use a CDN instead.
As I have seen your fonts are loaded from a CDN? But jQuery still comes from your server. If you don't want to change to vanilla chose to load it from CDN.
8. Check if Youtube can be loaded more simple
Youtube is loaded by several actions to your page. In this case I AM NOT SURE as I still did not work with youtube for a longer time. But I believe (not sure if I am right) that there is a more direct way to include youtube videos to a page. Maybe you would like to check it.
But nevertheless: work with placeholders for the video players as well. That are almost just few additional lines off css.
9. Optimizing user experience: thinking about a preloader
Reflow is not new phenomenon to webpages. Up to now a lot of pages uses preloaders to generate a better user experience. Today's technique is ajax load...
I don't know if the described techniques will avoid the reflow completely. As there are many elements the download time cannot be set to zero. But optimizing the page will reduce it dramatically. If there still remains a little bit ... maybe you like to think about the older technique. Using a nice and maybe well designed preloader symbol indeed can upgrade the user experience. Maybe on mobile views with medium data speed there is no other chance...?
But that is just to think about an additional possibility ...
[update]
10. Combine placeholder with infinite scroll
If you are using placeholders you can/should combine it with technique infinite scroll.
Means: all media (particularly images but maybe videos and iframes as well) are prepositioned by sized placeholders. That works immediately so there should be no more reflow as needed. Then load media assynchron by AJAX based on their position on their screen. Images which are in view are loaded immediately.
As you don't have so many media elements on starting viewport (most are still below the screen view) that should work as if it is a page with a 'normal number' of pictures/medias.
All others are loading afterwards when scrolling the page the media comes in view like on a 'infinite scroll page'. (Note: that works if the file size off the images is not to large, - so optimizing the images has still to be done.)
That has the additional advantage that thake makes sure that the images are loaded in the sequence they are needed ... which safes a lot of time.
Could be done in javascript:
Place images/media by placeholder technique
On window.onload check which images/media are in the viewport. Don't forget images which are only partly seen.
On window.onscroll check if image(s) comes to viewport and load image
Note: I am not quite sure if there are anchor links on your page to the single articles. I believe not. But if you still use them the starting viewport can be anywhere on the page when the user call an article. In that case window.onscroll has not only to work scrolling down but scrolling up to.
I am not quite sure if there is a ready script avaiable. But I would wonder if not. Otherwise it would not be to tricky to do that on your own. That would have the charm that such scripts mostly have less and cleaner code than preworked scripts ...
[end update]
... ... ...
I am not quite sure if the described issues are complete. Mostly there are found more possibilities to optimize a page when you start with the process. But as I had a nearer look to your page that are the most important chances.
EXAMPLE LAZY IMAGE LOAD WITH PLACEHOLDER EFFECT
Just EASY AND SIMPLIFIED example for lazy image load. Please adapt to your need.
// new html for image
<img class="placeholder-size" src="path/placeholder.jpg" data-lazy-url="https://url-to-your/imag.png" alt="Image Description">
// css
.placeholder-size {
width: 200px;
height: 100px;
}
// js for lazy load
// older code but works, please actualize if needed
window.onload = function(){
var lazyImages = document.querySelectorAll('[data-lazy-url]');
for (var i in lazyImages) if (lazyImages.hasOwnProperty(i)) {
var imgUrl = lazyImages[i].getAttribute('data-lazy-url');
lazyImages[i].src=imgUrl;
};
};
I want to know what disabling CSSOM View Scroll Coordinates flag in chrome://flags does and how can i replicate this behavior using code in my ReactJS app.
Additional information :
It seems after Chrome 85 update, ag-grid RTL support breaks and the grid is not able to scroll the content and sometimes the cells becomes white, i had to dig very deep into the past questions and try a lot of far fetched solutions to find what i have.
I found out that disabling CSSOM View Scroll Coordinates in chrome://flags will fix the bug!~ but the problem is i don't want to force my users and teach them to do this just so my app works, so i thought what ever disabling CSSOM View Scroll Coordinates does, maybe i can replicate it using css code or some other code
I have already reported this issue in ag-grid's git-hub but i'm still waiting for them to offer a solution in the mean time if i can get this to work only using code, it would be great as i have a lot of users which are not able to use my app just because of this simple bug ..
Thank you.
I'm designing an extension for Google Chrome, and I'd really like to earn a little cash from it (if possible) so I'm not eager to post the code in its entirety. I hope this isn't a prohibitive limitation for my question.
I'm injecting a content script into all websites as part of my extension, and part of the content script includes a touch-sensitive overlay; it's an invisible HTML div that's been assigned a swipe listener. The idea is to add swiping functionality to every website on which the script is run.
I'm having issues, though, with the overlay seeming to "die" on certain pages, especially after scrolling down the page. It registers swipes flawlessly all across google.com- scrolling or otherwise- but, for example, seems to die on engadget.com after scrolling down the page a bit. (After scrolling a bit more, it often starts registering swipes again.) Doing something like opening the console (F12) also causes it to start registering swipes, and refreshing the page (to the same place the object was before) lets it start registering again.
The HTML/JavaScript I'm utilizing for the overlay is this:
$("/<div class = \"touch_sensitive_overlay\" style = \"top:40%;opacity:1;position:fixed;height:247px;z-index:99999;width:50%;left:50%;border:2px solid black;\"></div>").prependTo('body');"
I'm using the jQuery Mobile library to register the swipes.
Any helpful insights would be profoundly appreciated.
Update:
A solution was proposed by Sumurai8, and was successfully implemented. The document was listened to for scrolling, and- whenever scrolling occurred- the overlay was removed from the injected HTML, then immediately re-injected. In this way, the overlay is continuously "active," and responds to input on all websites. Thanks for the good thinking, Sumurai8.
You could try to have a small script that does 'something' with the overlay when any element is scrolled. E.g. $('*').on('scroll', function() { $('#overlay').css( {'top': '0'} ); } ); and see if that fixes the problem. While in itself it doesn't do anything, it might make Chrome render your overlay again.
As you said in the comments, removing the overlay and re-appending it will force Chrome to render it again too.
I want to place a div above an iframe with flash content (for example like a youtube video).
I do not have access to the content in the iframe, so I can't modify something in there.
I've tried a lot of things (z-index... everything).
But nothing works. I am only asking because I really can't find a solution :(
The problem is that the iframe contains the flash content.
I can't really help with a tested solution I'm afraid, as I don't have any flash files to test creating an answer with, but I can tell you why this is happening.
Flash is a browser plugin, which means flash movies are never really part of the HTML document. Instead what happens is the area of the page is reserved for the plugin to run in, which is then invoked and runs 'on top' of the page. Therefore setting z-index on other elements will never actually solve the problem, no matter what combination you try.
However, there is a 'magic' parameter / attribute you can set on the elements themselves that the plugin recognises, called "wmode". If you set this parameter / attribute to 'transparent', the Flash plugin allows some HTML elements to show through, giving the illusion that they are on top of the Flash movie.
If you're able to contact the owner of the iframe to set the wmode parameter to transparent, I'd suggest doing that. If this is a youtube or vimeo embed, see if there's any documentation or options on adding the parameter yourself.
Failing that there's not a lot you can do, as even JavaScript won't be your friend here (you can't modify the contents of a frame with JS for security reasons)
EDIT:
Just remembered, if there's a way of you using HTML5 video instead of Flash, that would help. HTML5 videos are rendered as part of the Document Object Model, and therefore are controllable through the z-index property.
Neal
I use display advertising on my site and I noticed certain expandable ads (ads that expand when you roll over them) changes some of the elements on my page by adding the code "visibility: hidden" as inline CSS. This results in text boxes and other content disappearing when the ad loads. Other than simply disabling the offending ad (not a good solution since I never know what other ads might be causing problems or not), is there a way to block ads from injecting CSS instructions into my site like this? Any advice appreciated!
It's likely the flash add is using the ExternalInterface feature in flash to pipe javascript to your page:
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/external/ExternalInterface.html
The easiest way to make sure this doesn't happen is to set allowScriptAccess to false on your object tag where the ad is embedded:
http://kb2.adobe.com/cps/164/tn_16494.html
If you need the functionality that require allowScriptAccess (navigateToUrl comes to mind) then things get a little bit more complicated :-)