gatsbyjs / gatsby

The best React-based framework with performance, scalability and security built in.
https://www.gatsbyjs.com
MIT License
55.26k stars 10.31k forks source link

Issues with domready—animation flickering on page load. #3067

Closed piotrfonte closed 4 years ago

piotrfonte commented 6 years ago

I’m having a hard time getting around an issue that I think has to do with domready. Each time I load my site (https://piotrf.pl) the plain keyframe CSS animations are being triggered twice, which causes an awkward flickering: https://s3-us-west-2.amazonaws.com/dropbox.piotrf.pl/Untitled.mov

Note how this flickering occurs only on server, not on hotloaded localhost. Here’s why I think domready might be involved:

screen shot 2017-11-29 at 12 45 03 screen shot 2017-11-29 at 12 44 50

Has anyone encountered a similar issue?

migs540 commented 6 years ago

Yes I've been looking into this for the past two days. I have the same symptoms - keyframes get triggered twice on initial load. What I have noticed so far is:

twice animated

import React from "react" import Link from "gatsby-link" import Img from "gatsby-image" import Navigation from "../components/navigation"

import { rhythm, options } from "../utils/typography" import { injectGlobal, css, keyframes } from "styled-components" import styled from "styled-components"

const swingDown = keyframes 100% { transform: translateX(0%); }

export const AboutContents = styled.div transform: translateX(-100%); -webkit-transform: translateX(-100%); animation: ${swingDown} 1s forwards; animation-fill-mode: forwards; position: relative; z-index: 10; box-shadow: 8px 8px rgba(0, 0, 0, 0.15);

migs540 commented 6 years ago

@piotrf your animation keyframe runs twice when google analytics runs:

Request URL:https://www.google-analytics.com/r/collect?v=1&_v=j66&a=1842669742&t=pageview&_s=1&dl=https%3A%2F%2Fpiotrf.pl%2F&dr=https%3A%2F%2Fgithub.com%2Fgatsbyjs%2Fgatsby%2Fissues%2F3067&dp=%2F&ul=en-gb&de=UTF-8&dt=Piotr%20F.%20%E2%80%94%20Product%20designer%20%26%20front-end%20developer%E2%80%94An%20overall%20full-stack%20UX%20design%20specialist&sd=24-bit&sr=1024x1366&vp=1024x1366&je=0&_u=QACAAEAB~&jid=1921053810&gjid=1402211187&cid=1278082317.1511965245&tid=UA-22031199-1&_gid=784946713.1511965245&_r=1&z=209848835 Request Method:GET Status Code:200 Remote Address:172.217.25.174:443 Referrer Policy:no-referrer-when-downgrade

piotrfonte commented 6 years ago

@migs540 I can confirm that your sample seems to be suffering from the very same issue I’m having. Happens only on the first page load. Once the site’s been cached, it’s ok.

piotrfonte commented 6 years ago

@migs540 I thought it was Google Analytics, then I disabled it but the issue persisted. I now have re-enabled it.

migs540 commented 6 years ago

@piotrf Yes. It was behaving strangely for me which is why I ran up a version of https://github.com/gatsbyjs/gatsby/tree/master/examples/using-gatsby-image at trustingcustomers.com

Keyframes are CSS. So CSS is being run twice? Or part of the DOM is updating triggering CSS again? Not sure how CSS works at the dom / virtual dom level.

Here's the point where the second animation occurs. There's an event load and:

screen shot 2017-11-29 at 10 43 59 pm

KyleAMathews commented 6 years ago

Well this is bad… it sounds like Gatsby is rendering twice perhaps? What happens if you add a console.log to the render function?

Could one of you create a small reproduction site I could look at? E.g. your using-gatsby-image fork @migs540

migs540 commented 6 years ago

@KyleAMathews I created a new repository (because I couldn't work out how to fork just a subsection of gatsbyjs): https://github.com/migs540/debug-animations-using-gatsby-image

That is what is running at http://trustingcustomers.com/

It comes from the original ( https://github.com/gatsbyjs/gatsby/tree/master/examples/using-gatsby-image ) with styled-components added and edits to two files: index.js and blur-up.js - both of these have a one second animation for an enclosing div styled with styled-components.

I haven't added a console.log (don't know where) but am wondering if it has anything to do with manipulating the after initial load? But yes, better to follow the logs / load progress and see what is actually happening.

KyleAMathews commented 6 years ago

Awesome! I should have time in the morning to investigate (if you don't solve it of course while I sleep :-))

migs540 commented 6 years ago

@KyleAMathews we all win when you are awake.

In short: animations are executed twice. Once in index.html then a second time in componentindex.js:

I added console logging and can see the render is triggered just once in js (in component---src-pages-index-js-2d6cb1471a0df592f43f.js):

...E=(0,T.keyframes)(f),x=t.AboutContents=k.default.div(d,E),A=function(t){function n(){return(0,o.default)(this,n),(0,i.default)(this,t.apply(this,arguments))}return(0,u.default)(n,t),n.prototype.render=function(){return console.log("IndexComponent triggered me during render"),e.createElement...

class IndexComponent extends React.Component {
  render() {
    console.log("IndexComponent triggered me during render")

but well before that the animation is triggered (presumably from index.html:

public 3Legs$ grep animation index.html 
.iVIEdg{-webkit-transform:translateX(-100%);-ms-transform:translateX(-100%);transform:translateX(-100%);-webkit-transform:translateX(-100%);-webkit-animation:cWOgti 1s forwards;animation:cWOgti 1s forwards;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;position:relative;z-index:10;box-shadow:8px 8px rgba(0,0,0,0.15);}
.hzuIAT{-webkit-transform:translateX(-100%);-ms-transform:translateX(-100%);transform:translateX(-100%);-webkit-transform:translateX(-100%);-webkit-animation:cWOgti 1s forwards;animation:cWOgti 1s forwards;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;position:relative;z-index:10;box-shadow:8px 8px rgba(0,0,0,0.15);}

Video of behaviour (chrome dev tools) at:

http://trustingcustomers.com/consolelogging.mp4

Note: console logging is not in place in the repo I mention above - and you need to do a gatsby build to see the behaviour (gatsby develop triggers it just once because of the way it serves files locally).

KyleAMathews commented 6 years ago

Thanks for all your research + reproduction @migs540. Only had a brief moment to look at it so far but this is definitely a hydration issue — if you disable JavaScript then it only animates once. So now to see if the hydration problem is generic and needs fixed in core or if it's triggered by certain behaviors in sites.

KyleAMathews commented 6 years ago

The problem with your reproduction site is you have both gatsby-plugin-glamor and gatsby-plugin-styled-components added to the config. This broke the client side hydration causing a complete re-render. When I moved the styled-components stuff into a css file and removed gatsby-plugin-styled-components, things started working as expected.

From 7c26a916063a4d04b856cc76e6a0ac53e7aa3053 Mon Sep 17 00:00:00 2001
From: Kyle Mathews <mathews.kyle@gmail.com>
Date: Sat, 2 Dec 2017 20:00:42 -0800
Subject: [PATCH] Fix

---
 gatsby-config.js    |   1 -
 package.json        |   1 -
 src/pages/index.css |  13 +++
 src/pages/index.js  |  22 +---
 yarn.lock           | 307 ++++++++++++++++++++++++----------------------------
 5 files changed, 159 insertions(+), 185 deletions(-)
 create mode 100644 src/pages/index.css

diff --git a/gatsby-config.js b/gatsby-config.js
index 55dfd29..90c227a 100644
--- a/gatsby-config.js
+++ b/gatsby-config.js
@@ -2,7 +2,6 @@ module.exports = {
   plugins: [
     `gatsby-plugin-glamor`,
     `gatsby-plugin-netlify`,
-`gatsby-plugin-styled-components`,
     `gatsby-transformer-sharp`,
     {
       resolve: `gatsby-source-filesystem`,
diff --git a/package.json b/package.json
index 8167420..48dd74b 100644
--- a/package.json
+++ b/package.json
@@ -15,7 +15,6 @@
     "gatsby-source-filesystem": "^1.5.1",
     "gatsby-transformer-sharp": "^1.6.12",
     "numeral": "^2.0.6",
-    "sharp": "^0.18.4",
     "styled-components": "^2.2.3",
     "typeface-oswald": "^0.0.40",
     "typeface-pt-sans": "^0.0.40",
diff --git a/src/pages/index.css b/src/pages/index.css
new file mode 100644
index 0000000..90f40cd
--- /dev/null
+++ b/src/pages/index.css
@@ -0,0 +1,13 @@
+@keyframes swingDown {
+  100% { transform: translateX(0%); }
+}
+
+.about-div {
+  transform: translateX(-100%);
+  -webkit-transform: translateX(-100%);
+  animation: swingDown 1s forwards;
+  animation-fill-mode: forwards;
+  position: relative;
+  z-index: 10;
+  box-shadow: 8px 8px rgba(0, 0, 0, 0.15);
+}
diff --git a/src/pages/index.js b/src/pages/index.js
index be96fba..2fd39d1 100644
--- a/src/pages/index.js
+++ b/src/pages/index.js
@@ -2,30 +2,16 @@ import React from "react"
 import Link from "gatsby-link"
 import Img from "gatsby-image"
 import Navigation from "../components/navigation"
+import "./index.css"

 import { rhythm, options } from "../utils/typography"
-import { injectGlobal, css, keyframes } from "styled-components"
-import styled from "styled-components"
-
-const swingDown = keyframes`
-  100% { transform: translateX(0%); }
-`
-
-export const AboutContents = styled.div`
-  transform: translateX(-100%);
-  -webkit-transform: translateX(-100%);
-  animation: ${swingDown} 1s forwards;
-  animation-fill-mode: forwards;
-  position: relative;
-  z-index: 10;
-  box-shadow: 8px 8px rgba(0, 0, 0, 0.15);
-`

 class IndexComponent extends React.Component {
   render() {
+    console.log("rendering")
     return (
       <div>
-        <AboutContents>
+        <div className="about-div">
           <Img
             css={{ top: 0, left: 0, right: 0, zIndex: -1 }}
             style={{ position: `absolute` }}
@@ -128,7 +114,7 @@ class IndexComponent extends React.Component {
               </a>
             </p>
           </div>
-        </AboutContents>
+        </div>
       </div>
     )
   }
migs540 commented 6 years ago

OK @KyleAMathews - I suspected it had something to do with how i was using styled-components and can see what you've done here. However, I'd like to use styled-components with gatsby. Is it possible to do the same here and drop the glamor plugin (keeping styled-components)? I tried that a short time ago and it failed (but it was only a quick test).

Is it a case of either glamor or styled-components? Or just styled-components?

I'm a big fan of @mxstbr 's styled components and would love to be able to use it on gatsby to render once.

piotrfonte commented 6 years ago

Is that a general gatsby vs. styled-components issue? Asking as I don’t use glamor, yet have the same problem. Unsure what I can do to help, here’s my config if that hint at anything. Otherwise I can create a simple repo you could work with. Let me know @KyleAMathews.

gatsby-config.js


module.exports = {
  siteMetadata: {
    siteUrl: `https://piotrf.pl`,
    title: `piotrf.pl-v2 (2017)`
  },
  plugins: [
    `gatsby-plugin-react-helmet`,
    `gatsby-plugin-sharp`,
    `gatsby-plugin-styled-components`,
    `gatsby-plugin-react-next`,
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `pages`,
        path: `${__dirname}/src/pages`
      }
    },
    {
      resolve: `gatsby-plugin-google-analytics`,
      options: {
        trackingId: "something"
      }
    },
    {
      resolve: `gatsby-plugin-sitemap`
    },
    {
      resolve: "gatsby-transformer-remark",
      options: {
        plugins: [
          {
            resolve: `gatsby-remark-images`,
            options: {
              maxWidth: 1000,
              linkImagesToOriginal: false
            }
          },
          {
            resolve: "gatsby-remark-external-links",
            options: {
              target: "_self",
              rel: "nofollow"
            }
          },
          `gatsby-transformer-sharp`,
          `gatsby-remark-autolink-headers`,
          `gatsby-remark-copy-linked-files`
        ]
      }
    },
    `gatsby-plugin-netlify` // must come in last
  ]
};
piotrfonte commented 6 years ago

@KyleAMathews, I have now create a simple site/repo that you can have a look at: https://priceless-minsky-70fda7.netlify.com/ that gets deployed from https://github.com/piotrf/gatsby-test — any help in solving this flickering mystery much is appreciated.

sergical commented 6 years ago

@KyleAMathews and everyone, resurfacing this as I am having the same issues with my personal site: https://416serg.me/

Plugins I use:

plugins: [
    'gatsby-plugin-react-helmet',
    `gatsby-transformer-sharp`,
    `gatsby-plugin-netlify`,
    {
      resolve: 'gatsby-source-filesystem',
      options: {
        name: 'posts',
        path: `${__dirname}/content/${config.blogPostDir}`
      }
    },
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `src`,
        path: `${__dirname}/src/`,
      },
    },
    {
      resolve: 'gatsby-transformer-remark',
      options: {
        plugins: [
          {
            resolve: 'gatsby-remark-images',
            options: {
              maxWidth: 690
            }
          },
          {
            resolve: 'gatsby-remark-responsive-iframe'
          },
          'gatsby-remark-prismjs',
          'gatsby-remark-copy-linked-files',
          'gatsby-remark-autolink-headers'
        ]
      }
    },
    {
      resolve: 'gatsby-plugin-google-analytics',
      options: {
        trackingId: config.googleAnalyticsID
      }
    },
    {
      resolve: 'gatsby-plugin-nprogress',
      options: {
        color: config.themeColor
      }
    },
    'gatsby-plugin-sharp',
    `gatsby-transformer-sharp`,
    'gatsby-plugin-catch-links',
    'gatsby-plugin-twitter',
    'gatsby-plugin-sitemap',
    {
      resolve: 'gatsby-plugin-manifest',
      options: {
        name: config.siteTitle,
        short_name: config.siteTitle,
        description: config.siteDescription,
        start_url: config.pathPrefix,
        background_color: config.backgroundColor,
        theme_color: config.themeColor,
        display: 'minimal-ui',
        icons: [
          {
            src: '/logos/logo-192x192.png',
            sizes: '192x192',
            type: 'image/png'
          },
          {
            src: '/logos/logo-512x512.png',
            sizes: '512x512',
            type: 'image/png'
          }
        ]
      }
    },
    'gatsby-plugin-offline',
    {
      resolve: 'gatsby-plugin-feed',
      options: {
        setup(ref) {
          const ret = ref.query.site.siteMetadata.rssMetadata;
          ret.allMarkdownRemark = ref.query.allMarkdownRemark;
          ret.generator = 'GatsbyJS Material Starter';
          return ret;
        },
        query: `
        {
          site {
            siteMetadata {
              rssMetadata {
                site_url
                feed_url
                title
                description
                image_url
                author
                copyright
              }
            }
          }
        }
      `,
        feeds: [
          {
            serialize(ctx) {
              const rssMetadata = ctx.query.site.siteMetadata.rssMetadata;
              return ctx.query.allMarkdownRemark.edges.map(edge => ({
                categories: edge.node.frontmatter.tags,
                date: edge.node.frontmatter.date,
                title: edge.node.frontmatter.title,
                description: edge.node.excerpt,
                author: rssMetadata.author,
                url: rssMetadata.site_url + edge.node.fields.slug,
                guid: rssMetadata.site_url + edge.node.fields.slug,
                custom_elements: [{ 'content:encoded': edge.node.html }]
              }));
            },
            query: `
            {
              allMarkdownRemark(
                limit: 1000,
                sort: { order: DESC, fields: [frontmatter___date] },
              ) {
                edges {
                  node {
                    excerpt
                    html
                    timeToRead
                    fields { slug }
                    frontmatter {
                      title
                      cover
                      date
                      category
                      tags
                    }
                  }
                }
              }
            }
          `,
            output: config.siteRss
          }
        ]
      }
    }
  ]
pie6k commented 6 years ago

I'm still having this issue, too when using styled-components.

KyleAMathews commented 6 years ago

@pie6k are you using gatsby-plugin-styled-components?

pie6k commented 6 years ago

Yes, I think my issue is related to using it.

m-allanson commented 6 years ago

Maybe this is a rehydration issue?

I took a screen recording of Chrome's animation inspector running on @piotrf's repro site: https://www.dropbox.com/s/h8nsguy5p8dzonl/issue-3067-animation-flicker.mov?dl=0

It shows the animations running twice. The class names on the animated items change between the first animation and the second animation. In the second animation, hovering the highlighted divs will highlight them in the page. For the first animation that doesn't happen, as the divs no longer exist.

Could the styled components plugin be generating different classnames during the SSR phase and the browser phase? This might then cause React to re-render the page using the new class names, which is retriggering the animations?

m-allanson commented 6 years ago

Should gatsby-plugin-styled-components be using the Styled Components babel plugin? https://www.styled-components.com/docs/tooling#serverside-rendering

malekjaroslav commented 6 years ago

I have the same problem

markelog commented 6 years ago

@KyleAMathews is there any way to use styled components with the current state of things?

KyleAMathews commented 6 years ago

@markelog Lots of people are using styled-components successfully — what problems are you seeing?

markelog commented 6 years ago

Exact same issue described in the ticket - page is rerendered and assets are redownloaded :/.

I suppose it’s not that directly noticeable if you don’t have animation, but it’s there

Regards, Oleg

On 25 Mar 2018, at 23:10, Kyle Mathews notifications@github.com wrote:

@markelog Lots of people are using styled-components successfully — what problems are you seeing?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

KyleAMathews commented 6 years ago

It does sound like several people are having trouble with gatsby-plugin-styled-components — @m-allanson's guess that it has something to do with the babel plugin not being included seems plausible.

@markelog would you like to try adding the SC babel plugin to the gatsby plugin to see if that fixes things?

You can setup a development environment using the instructions here https://www.gatsbyjs.org/docs/how-to-contribute/

You'd add the SC babel plugin like we do for Glamor https://github.com/gatsbyjs/gatsby/blob/958b76de9f779f32406bcc7dffca6e2312155c43/packages/gatsby-plugin-glamor/src/gatsby-node.js#L12

markelog commented 6 years ago

Can’t promise I will be productive, since I usually limited with my time. But I will do my best :)

Regards, Oleg

On 26 Mar 2018, at 00:31, Kyle Mathews notifications@github.com wrote:

It does sound like several people are having trouble with gatsby-plugin-styled-components — @m-allanson's guess that it has something to do with the babel plugin not being included seems plausible.

@markelog would you like to try adding the SC babel plugin to the gatsby plugin to see if that fixes things?

You can setup a development environment using the instructions here https://www.gatsbyjs.org/docs/how-to-contribute/

You'd add the SC babel plugin like we do for Glamor https://github.com/gatsbyjs/gatsby/blob/958b76de9f779f32406bcc7dffca6e2312155c43/packages/gatsby-plugin-glamor/src/gatsby-node.js#L12

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

KyleAMathews commented 6 years ago

Actually... lemme just fix this. The plugin is really widely used and it'll only take me a sec to add the babel plugin. Thanks for offering!

KyleAMathews commented 6 years ago

Put up the PR https://github.com/gatsbyjs/gatsby/pull/4722

Once the tests pass & I release it, you'll just need to upgrade to the latest gatsby-plugin-styled-components and install babel-plugin-styled-components into your project.

markelog commented 6 years ago

Nice! Thank you :)

Regards, Oleg

On 27 Mar 2018, at 01:06, Kyle Mathews notifications@github.com wrote:

Put up the PR #4722

Once the tests pass & I release it, you'll just need to upgrade to the latest gatsby-plugin-styled-components and install babel-plugin-styled-components into your project.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

piotrfonte commented 6 years ago

Thanks for the effort @KyleAMathews. This did not do the trick for me. Stuff still flickers: https://priceless-minsky-70fda7.netlify.com/ Here’s the source, if anyone wants to help out nailing this down: https://github.com/piotrf/gatsby-test

markelog commented 6 years ago

I can confirm that with version 2.0.11 of gatsby-plugin-styled-components issue still persist

KyleAMathews commented 6 years ago

Did y'all install babel-plugin-styled-components into your project? We only use the babel plugin if you add it as otherwise it'd break sites.

piotrfonte commented 6 years ago

Yes, I did. Just now. Same.

piotrfonte commented 6 years ago

Here’s my test playground: https://priceless-minsky-70fda7.netlify.com/

markelog commented 6 years ago

Yes, I did. Just now. Same.

Yep

KyleAMathews commented 6 years ago

Hey y'all, @tsriram just added a build option which lets you disable uglify which means it'll be possible to see the errors React shows when there's a mismatch between the server rendering and client render which should help y'all narrow down where problems are cropping up https://github.com/gatsbyjs/gatsby/pull/4755

Upgrade to the latest gatsby and gatsby-cli and then run gatsby build --no-uglify.

breadadams commented 6 years ago

We're suffering from the same issue on this project. Will give your latest comments a go and report back @KyleAMathews.

Note the 2nd appearance of the bottom-left text as it triggers a "reload":

apr-22-2018 21-12-28

m-allanson commented 6 years ago

@breadadams is your project using gatsby-styled components too?

breadadams commented 6 years ago

Yeah @m-allanson, also installed babel-plugin-styled-components, and no explicit babel config for the project is set/created.

I've just updated gatsby to @latest & deployed the results of build --no-uglify here, @KyleAMathews.

We've also got a few other gatsby plugins installed (ie. gatsby-plugin-offline, gatsby-plugin-manifest, etc). However just done a test-run removing all plugins except gatsby-plugin-react-helmet & gatsby-plugin-styled-components and the issue is still present.

KyleAMathews commented 6 years ago

So there's nothing in the console?

breadadams commented 6 years ago

Would appear so @KyleAMatthews, all I saw were some service worker & A-frame related messages that are present in our other build too.

On 26 Apr 2018, at 07:45, Kyle Mathews notifications@github.com wrote:

So there's nothing in the console?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

JoaoTMDias commented 6 years ago

I'm also facing the same issue. So using only css keyframes (not styled components) temporarily fixes the issue?

m-allanson commented 6 years ago

@piotrf I tried looking into this again, using the repo you posted earlier. Running gatsby develop I see some errors in the browser console. Any chance you could fix those up?

Or if anyone has source for a simple demo site that replicates this problem and uses babel-plugin-styled-components then please post it here.

breadadams commented 6 years ago

@m-allanson the repo for the project I'm linking to is currently over on GitLab - hope that helps 🙂

(It's still in baby steps, recently born from the starter - as you'll be able to tell from the package.json 🙈)

m-allanson commented 6 years ago

Thanks @breadadams, that does help!

I've created a test version of your site - stripping out the bits that aren't related to this issue.

Repo: https://github.com/m-allanson/test-gatsby-animation Live URL: http://festive-hermann-722eab.netlify.com/

This looks like the server generated classnames are different from the browser rendered classnames. You can see this by running the site with or without JS enabled.

With JS - notice animation being retriggered just after the page loads:

withjs

Without JS - the animation runs smoothly:

withoutjs

The With JS demo it looks like the page loads with the server generated classnames, then they get changed by the client, causing the animations to restart. In the Without JS demo, only the server generated classnames are being used and the animation just runs once.

If anyone can work out why there's a difference between the server and client side classnames, that should hopefully solve this issue.

breadadams commented 6 years ago

Awesome @m-allanson!! Looking thru the src for gatsby-plugin-styled-components I noticed something possibly related. The config is returned twice based on a conditional, once with ssr: true and the other without:

https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-styled-components/src/gatsby-node.js

m-allanson commented 6 years ago

If you wanted to try some debugging, you could copy the plugin source as a local plugin and play around with it.

For a more in-depth setup checkout the instructions for using gatsby-dev.

breadadams commented 6 years ago

Thanks, will do. Here's a possible related issue I've come across: https://github.com/zeit/next.js/issues/3706

KyleAMathews commented 6 years ago

@breadadams the reason it's returned twice is we added support for the babel plugin recently and to avoid having to do a major release due to a breaking change, we check if the plugin is installed before adding it. If you haven't added the babel plugin, that could be the problem.

JoaoTMDias commented 6 years ago

Installing babel-plugin-styled-components did it for me! Thanks!