Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for Server Components #493

Open
alvarlagerlof opened this issue Nov 9, 2022 · 7 comments
Open

Support for Server Components #493

alvarlagerlof opened this issue Nov 9, 2022 · 7 comments

Comments

@alvarlagerlof
Copy link

alvarlagerlof commented Nov 9, 2022

Is your feature request related to a problem? Please describe.
Currently, I have to "use client"; in a wrapper around <SyntaxHighlighter> like this. If this component supported server components, I could ship significantly less code, and allow it to render in SSR mode. Currently, this dependency is taking up by far most of my bandwidth. Since in my case, the code does not change when running on the client, it should not need to include everything there.

Describe the solution you'd like
<SyntaxHighlighter> to support React Server components.

Describe alternatives you've considered
Currently shipping it as a client component, which does work, but is not ideal.

Additional context
None.

@williamlmao
Copy link

+1 here.

I also tried a client component with the Light build, but the light build gives me a hydration error. Full build is fine.

@yensubldg
Copy link

Too problem

@tubbo
Copy link

tubbo commented Dec 27, 2022

I got an error as well when I attempted to

import Syntax from 'react-syntax-highlighter'

However, I was able to get rid of the error without needing to use client by changing that import to:

import Syntax from 'react-syntax-highlighter/dist/esm/default-highlight'

This is because, although the default highlight.js implementation is exported from the index.js manifest, it also includes many other implementations which do not seem to have support for server components.

Highlight.js doesn't balk, though, so this works for me in both dev and prod builds...

Screen Shot 2022-12-27 at 11 47 41 AM

Original bundle size:

Screen Shot 2022-12-27 at 11 48 59 AM

Current bundle size:

Screen Shot 2022-12-27 at 11 49 21 AM

I think the quick fix solution here is to configure an "exports" in the package.json so one can do this:

import Syntax from 'react-syntax-highlighter/default-highlight'

For the long-term, it would definitely be better to update the module index.js so that it either only exports the "default" implementation (the one for highlight.js), or all of the named exports are explicit and it doesn't export default anymore. I like the ability to choose the implementation easily, but I feel like it's bringing in a lot more JS code than any consumer of this library actually wants. So it might be better, overall, to make the library easier to tree-shake and only include the code that the consumer wants to use on their app.

@alvarlagerlof
Copy link
Author

@tubbo Do you know how to do that when using prism?

@AbdBarho
Copy link

@alvarlagerlof I found a hack that solves the problem partially.

import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
import { useEffect, useState } from "react";

const md = `# Hi`;

const RMD = () => {
  const [style, setStyle] = useState({});

  useEffect(() => {
    import("react-syntax-highlighter/dist/esm/styles/prism/okaidia").then(
      (mod) => setStyle(mod.default)
    );
  }, []);

  return <SyntaxHighlighter style={style}>{md}</SyntaxHighlighter>;
};

Works with server rendering, I am not using the app from next, I am still on the old pages thingy, but I assume this should also work in the new version.

This does not solve the problem completely, the javascript bundle is still huge, but at least all html elements are there on first render.

@alvarlagerlof
Copy link
Author

alvarlagerlof commented Jan 20, 2023

@alvarlagerlof I found a hack that solves the problem partially.

import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
import { useEffect, useState } from "react";

const md = `# Hi`;

const RMD = () => {
  const [style, setStyle] = useState({});

  useEffect(() => {
    import("react-syntax-highlighter/dist/esm/styles/prism/okaidia").then(
      (mod) => setStyle(mod.default)
    );
  }, []);

  return <SyntaxHighlighter style={style}>{md}</SyntaxHighlighter>;
};

Works with server rendering, I am not using the app from next, I am still on the old pages thingy, but I assume this should also work in the new version.

This does not solve the problem completely, the javascript bundle is still huge, but at least all html elements are there on first render.

This "works" with server rendering because it's not doing any styles while rendering on the server. Not a solution to me, and will cause a longer LCP.

@AbdBarho
Copy link

I managed to "optimise" this by changing the style import to the cjs bundle.

import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
import { useEffect, useState } from "react";

import okida from 'react-syntax-highlighter/dist/cjs/styles/prism/okaidia';

const md = `# Hi`;

const RMD = () => {
  return <SyntaxHighlighter style={okida}>{md}</SyntaxHighlighter>;
};

if I run next export, I can see in the resulting html file that everything is there, even the styles.

results
<pre><pre style="color:#f8f8f2;background:#272822;text-shadow:0 1px rgba(0, 0, 0, 0.3);font-family:Consolas, Monaco, &#x27;Andale Mono&#x27;, &#x27;Ubuntu Mono&#x27;, monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none;padding:1em;margin:.5em 0;overflow:auto;border-radius:0.3em"><code class="language-cpp" style="color:#f8f8f2;background:none;text-shadow:0 1px rgba(0, 0, 0, 0.3);font-family:Consolas, Monaco, &#x27;Andale Mono&#x27;, &#x27;Ubuntu Mono&#x27;, monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none"><span>std</span><span class="token double-colon" style="color:#f8f8f2">::</span><span>vector</span><span class="token" style="color:#f8f8f2">&lt;</span><span class="token" style="color:#66d9ef">float</span><span class="token" style="color:#f8f8f2">&gt;</span><span> </span><span class="token" style="color:#e6db74">sumOverAxes</span><span class="token" style="color:#f8f8f2">(</span><span>std</span><span class="token double-colon" style="color:#f8f8f2">::</span><span>vector</span><span class="token" style="color:#f8f8f2">&lt;</span><span class="token" style="color:#66d9ef">float</span><span class="token" style="color:#f8f8f2">&gt;</span><span class="token" style="color:#f8f8f2">&amp;</span><span> points</span><span class="token" style="color:#f8f8f2">)</span><span class="token" style="color:#f8f8f2">{</span><span>
</span><span>    </span><span class="token" style="color:#8292a2">// &quot;points&quot; contains [xyzxyzxyzxyz...]</span><span>
</span><span>    std</span><span class="token double-colon" style="color:#f8f8f2">::</span><span>vector</span><span class="token" style="color:#f8f8f2">&lt;</span><span class="token" style="color:#66d9ef">float</span><span class="token" style="color:#f8f8f2">&gt;</span><span> </span><span class="token" style="color:#e6db74">sum</span><span class="token" style="color:#f8f8f2">(</span><span class="token" style="color:#ae81ff">3</span><span class="token" style="color:#f8f8f2">,</span><span> </span><span class="token" style="color:#ae81ff">0.0f</span><span class="token" style="color:#f8f8f2">)</span><span class="token" style="color:#f8f8f2">;</span><span>
</span>
<span>    </span><span class="token macro directive-hash" style="color:#f92672">#</span><span class="token macro directive" style="color:#66d9ef">pragma</span><span class="token macro" style="color:#f92672"> </span><span class="token macro expression" style="color:#f92672">omp parallel </span><span class="token macro expression" style="color:#66d9ef">for</span><span>
</span><span>    </span><span class="token" style="color:#66d9ef">for</span><span class="token" style="color:#f8f8f2">(</span><span>size_t axis </span><span class="token" style="color:#f8f8f2">=</span><span> </span><span class="token" style="color:#ae81ff">0</span><span class="token" style="color:#f8f8f2">;</span><span> axis </span><span class="token" style="color:#f8f8f2">&lt;</span><span> </span><span class="token" style="color:#ae81ff">3</span><span class="token" style="color:#f8f8f2">;</span><span> axis</span><span class="token" style="color:#f8f8f2">++</span><span class="token" style="color:#f8f8f2">)</span><span> </span><span class="token" style="color:#f8f8f2">{</span><span>
</span><span>        </span><span class="token" style="color:#66d9ef">for</span><span class="token" style="color:#f8f8f2">(</span><span>size_t i </span><span class="token" style="color:#f8f8f2">=</span><span> axis</span><span class="token" style="color:#f8f8f2">;</span><span> i </span><span class="token" style="color:#f8f8f2">&lt;</span><span> points</span><span class="token" style="color:#f8f8f2">.</span><span class="token" style="color:#e6db74">size</span><span class="token" style="color:#f8f8f2">(</span><span class="token" style="color:#f8f8f2">)</span><span class="token" style="color:#f8f8f2">;</span><span> i</span><span class="token" style="color:#f8f8f2">+=</span><span class="token" style="color:#ae81ff">3</span><span class="token" style="color:#f8f8f2">)</span><span> </span><span class="token" style="color:#f8f8f2">{</span><span>
</span><span>        ​    sum</span><span class="token" style="color:#f8f8f2">[</span><span>axis</span><span class="token" style="color:#f8f8f2">]</span><span> </span><span class="token" style="color:#f8f8f2">+=</span><span> points</span><span class="token" style="color:#f8f8f2">[</span><span>i</span><span class="token" style="color:#f8f8f2">]</span><span class="token" style="color:#f8f8f2">;</span><span>
</span><span>        </span><span class="token" style="color:#f8f8f2">}</span><span>
</span><span>    </span><span class="token" style="color:#f8f8f2">}</span><span>
</span><span>    </span><span class="token" style="color:#66d9ef">return</span><span> sum</span><span class="token" style="color:#f8f8f2">;</span><span>
</span><span></span><span class="token" style="color:#f8f8f2">}</span></code></pre></pre>

which renders to the following: (colors missing, probably github blocking styles because of xss)

std::vector<float> sumOverAxes(std::vector<float>& points){
    // "points" contains [xyzxyzxyzxyz...]
    std::vector<float> sum(3, 0.0f);

    #pragma omp parallel for
    for(size_t axis = 0; axis < 3; axis++) {
        for(size_t i = axis; i < points.size(); i+=3) {
        ​    sum[axis] += points[i];
        }
    }
    return sum;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants