-
Notifications
You must be signed in to change notification settings - Fork 5.4k
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
Expo vector icons are not loading up and is producing "3000ms timeout exceeded" loops on Brave Browser #12382
Comments
Heads up!. I tried testing on multiple browsers and it also occurred on Chrome. |
It happens on all browsers, and is not limited to Bare: #5961 (comment) |
it sounds like an issue with expo-font on web, anyone willing to look into this? |
I can confirm it's (Here on master: https://github.com/expo/expo/blob/master/packages/expo-font/src/ExpoFontLoader.web.ts#L92)
There are various solutions, one being as follows:
Why it breaks the icon if the font fails to load, I don't understand. The style should be added to the head, so I don't get why it breaks. |
I managed to fix it by declaring the font on my assets folder and run it as a custom font instead.
It somehow fix the problem but in rare occasion the error still occurs. |
@HeinDiez that doesn't fix the underlying problem, and as you said you'll still see the issue. |
Any update on this? I'm not positive it's because of vector-icons, but I also get the 3000ms timeout exceeded error due to apply(fontfaceobserver/fontfaceobserver.standalone) very randomly and have been trying to find a fix! @byCedric |
It's always because of a font not loading within the allotted time and |
On expo for web, I am importing and waiting for my fonts until loaded == true:
Am I doing something wrong here? @SleeplessByte |
If you read my previous comment (#12382 (comment)) you can see that the issue is actually inside That said, you are loading 14 fonts, which seems very excessive. |
I can definitely cut down on the fonts, but I thought loading all of the vector-icons used throughout the web app upfront might help the issue? Do you know of any way I can simulate/trigger the issue in dev so I can see what the user experiences when this happens? I've never gotten the error myself, I just see it being tracked on Sentry. Thanks for all the help. @SleeplessByte |
The easiest way is to turn on throttle in network (in developer tools) so at least one font takes longer to load than the default timeout of 3000ms. |
Do you know of any fix / hacky workaround to make sure the site doesn't break when this happens? |
Hi @SleeplessByte, is there a way to not use expo-font to load a font? I haven't seen any documentation for it, or maybe I just missed it somewhere. |
Yes, all
loadAsync(fontFamily: string, resource: FontResource) const fontStyle = `@font-face {
font-family: ${fontFamily};
src: url(${resource.uri});
}`; That const ID = 'expo-generated-fonts';
const style: HTMLStyleElement = document.getElementById(ID) ||
document.createElement('style')
// Add the font style to the <style> element
style.appendChild(document.createTextNode(fontStyle));
// Ensure the <style> element is in the head. This will keep it in the head
// if it already is there.
document.head!.appendChild(style); If you want to wait for it to be loaded, you can use new FontObserver(fontFamilyName).load() This defaults to the aforementioned 3 seconds. It's not a bad idea to use and a longer timeout, and retrying when it fails: function reallyLoadFont(fontFamilyName, timeout = 3000 * 3) {
return new FontObserver(fontFamilyName)
.load(undefined, timeout)
.catch(() => {
// oh - no
return reallyLoadFont(fontFamilyName, timeout * 2)
})
} Naturally, you might want to limit the maximum timeout, or amount of times you retry, but this should get you started. |
@SleeplessByte Hey, I totally get it... however is it ok to change a node module package file?... our project is currently run by multiple devs, and updating their side of the code would be such a hassle. the change should be done in this file right? |
I've used |
This issue is stale because it has been open for 60 days with no activity. If there is no activity in the next 7 days, the issue will be closed. |
Not stale, still relevant. |
This issue is stale because it has been open for 60 days with no activity. If there is no activity in the next 7 days, the issue will be closed. |
Not stale, still relevant. |
Not stale, still relevant. |
Any interest in a PR here? Happy to take a stab at it as we are definitely seeing the same |
Might be worth replacing with https://developer.mozilla.org/en-US/docs/Web/API/FontFace/load at this point |
This issue is stale because it has been open for 60 days with no activity. If there is no activity in the next 7 days, the issue will be closed. |
Issue still present |
Thanks @SleeplessByte for giving this an attention. Hopefully we get a fix soon. Maybe I'll look into it and see if I could find a fix. |
I just hit this issue where icons intermittently fail to load and it's much stranger than just a simple server-side or network slow-down. Below is a Wireshark capture from the client. The browser (192.168.1.251) sends a request for
All of this happens within dozens of milliseconds. My code right before the call to
So the font loading started only about 800ms before the request for that font. So I don't see any reason why the client should have canceled the request. This is well before the 3000ms timeout error which happens about 2.5 seconds later:
So the first issue is that the font loader seems to be mysteriously canceling its own request for no obvious reason well before the timeout and with the server trying to send a successful response. At first, I was thinking might be due to scheduling delays, but the seeming canceling of the request well before the timeout seems like a functional issue rather than a timing or scheduling issue. Then, there is another request for In any case, that call doesn't have the TLS Close or RST and succeeds quickly:
I also see the Firefox network panel showing this second request and this time it looks like a healthy response. On the server-side, everything looks normal for both requests:
Nevertheless, those icons never did load in my app, so the second issue is that a successful loading of the icons may still not show them in the app. I'll add some retry loops but I'm worried this will be fruitless because even a successful response didn't load the icons. I think this also exposes the long-standing, systemic issue in Expo (and the JS community in general) that these sorts of issues are incredibly hard to create a standalone reproduction for and might depend on various external factors. This might be a good use case to explore alternative diagnostic capabilities of dynamically-enabled debug logging statements that us users of Expo can enable in our apps to help investigate these sorts of issues (e.g. a log statement when the font loader decides to cancel the request, etc.). |
After hours of fruitless investigation, I've decided to use a workaround of just extracting out the font icons I need into images and using those instead. It's cumbersome and inflexible, but I also noticed that
|
Also seeing this issue. unfortunately vector icons not working on web |
@findhumane you can find all the icons (as SVG and PNG) on http://materialdesignicons.com/, because that's what the Material Community Icons font is. I also read your investigation. It's really not that complex, but I can support your findings with source code, as I've posted before (in this thread). The package used is https://github.com/expo/expo/blob/master/packages/expo-font/src/ExpoFontLoader.web.ts#LL2C27-L2C43 ...and called here: https://github.com/expo/expo/blob/master/packages/expo-font/src/ExpoFontLoader.web.ts#L92 As you can see no arguments are passed. In this case, no timeout is given and it will use the default timeout of 3 seconds, as declared here: https://github.com/bramstein/fontfaceobserver/blob/master/src/observer.js#LL195C51-L195C51 After 3 seconds, it aborts the request. That's really it. You can find previous explorations of the code base here: And the fix: I've been using a patch to retry automatically for the past 2 years and that works well. I recommend you do the same. |
Thanks, great info!
Right, the strange thing though is:
I'm not a fan of introducing arbitrary delays and retries so I will stick to images until this is fixed. I like the idea of switching to Thanks for the icon images link, very useful! |
We can include the "What do you think?" |
As evidenced in a previous comment, this issue is beyond a server-side timeout issue. Moreover, retries and timeouts are not a proper solution for this; even for the cases where they may be a workaround, they simply add latency for the user. Given how hard this issue is to reproduce (and I've long moved on and now simply use images instead), I think the better solution is to switch to Hopefully that will avoid whatever bug lurks in An even cooler solution would be to automagically replace icons with SVGs from the font, thus avoiding loading the entire font TTF/OTF files which are huge (MBs) and most people are just using a few characters from each font, so they're a heavy waste on web. |
My two cents as someone who has faced this and used expo vector icons: if you aren't deep into using I've faced so many issues with this package on Web, so I thought I'd share. It isn't necessary for an icon set to be a single font. The SVG approach works great and doesn't have any of the issues with loaders and assets. If you want to use any of the existing icon sets, you can use SVGr to convert a folder of SVGs into a React Native icon package. I turned Hero Icons and Iconic into React Native SVG packages with this approach. You can see the script I used in those repos to generate your own icon packs if you'd like. It's easy to fork and implement. I know it isn't a solution to this thread, but figured I'd save someone else the time. (I'm in too deep to remove Expo's icons, but I get OP's error everyday on our Sentry on Web, and I wish I could get rid of the package.) |
I'm having this same issue when I try to use icons in React Native on Android (expo) |
# Why Fixes #12382 # How The font observer can time out and throw an uncaught exception, as noted by many bug reporters. There are many cases (e.g., unsupported browsers) where the observer is early-returned, so catching an exception on web is a safe no-op. # Test Plan This is tough to write a new test for since this is mostly a product of network conditions; does this need new test coverage? # Checklist - `[N/A]` Documentation is up to date to reflect these changes (eg: https://docs.expo.dev and README.md). - `[N/A]` Conforms with the [Documentation Writing Style Guide](https://github.com/expo/expo/blob/main/guides/Expo%20Documentation%20Writing%20Style%20Guide.md) - [x] This diff will work correctly for `npx expo prebuild` & EAS Build (eg: updated a module plugin).
Appreciate the work to (hopefully) resolve this, although I think it's worth highlighting a previous, buried comment:
I think an even better long-term solution here would be to have some sort of asset pipeline that sees the icons being used and automatically replaces them with SVGs in the final build. |
Some changes in the following packages that may fix this issue have just been published to npm under
If you're using bare workflow you can upgrade them right away. We kindly ask you for some feedback—even if it works 🙏 They will become available in managed workflow with the next SDK release 👀 Happy Coding! 🎉 |
Does Expo-Font 11.5.0 have any compatibility issues with Expo 49? |
Looks like upgrading to expo-font 11.5.0 or higher causes icons to break on native (rendering incorrect icons), but upgrading seems fine on expo web. |
Summary
Upon closer investigation, it has to do with node_module/fontfaceobserver not loading or failing to load from multiple requests resulting in Expo Vector Icons not showing up.
Managed or bare workflow? If you have
ios/
orandroid/
directories in your project, the answer is bare!bare
What platform(s) does this occur on?
Web
SDK Version (managed workflow only)
No response
Environment
Expo CLI 4.3.2 environment info:
System:
OS: Windows 10 10.0.19042
Binaries:
Node: 12.18.3 - C:\Program Files\nodejs\node.EXE
npm: 6.14.6 - C:\Program Files\nodejs\npm.CMD
IDEs:
Android Studio: Version 4.1.0.0 AI-201.8743.12.41.6858069
npmPackages:
expo: ~40.0.0 => 40.0.1
react: 16.13.1 => 16.13.1
react-dom: 16.13.1 => 16.13.1
react-native: ^0.64.0 => 0.64.0
react-native-web: ^0.15.0 => 0.15.0
Expo Workflow: bare
Reproducible demo or steps to reproduce from a blank project
Refreshing the web browser will either Load the icon or produce an "Error: 3000ms timeout exceeded" loop with a bunch of requests from bundle.js.map. Most likely it will produce the error.
I think it is the same issue with #5935. I am using Brave Browser in debugging.
all Expo Vector Icon would either show up or not at all.
The text was updated successfully, but these errors were encountered: