What the difference between "import components globally" and "dynamically" in Javascript? - performance

Below are two different ways to import Antd components, I'm not sure which one's performance will be better in a huge project?
My project was set up with Vue3 and Antd. At the beginning, I import needed components globally in main.ts. So that I can use these anywhere and dont't need import again and again. Below are examples.
main.ts
import { Button, Input, Layout, Menu, Space } from 'ant-design-vue';
import 'ant-design-vue/dist/antd.variable.min.css';
app.use(Input).use(Button).use(Layout).use(Menu).use(Space);
user.vue
<Button>do something</Button>
It's easy to use but my concern is that even if I access to a specific route which has only one component, the browser will load all components sources. Maybe it takes a long time if the network performance is poor. So, I try to import specific components dynamically in views. Below are examples.
user1.vue
// user.vue
import { Menu } from 'ant-design-vue';
user2.vue
// user.vue
import { Menu } from 'ant-design-vue';
Umm... It solved the above issue, but I found that every time I access to different routes which has same component, browser load it every time.
For example, when I access to user1 route, browser loaded Menu component. Then, I access to user2 route, browser loaded it again.
I'm not sure why, or what something I make wrong?
I would really appreciate it, if someone can explain it or tell me how to let users see our views as fast as we can.

Related

There are any difference in performance having a dictionary object of images?

I want to manage all static resources in my React Native project in the best and mantainable way.
I'm using Image component, and all of this is for passing the local reference of the image, like <Image source={imageReference} />, where imageReference can be get in the next two ways.
I have this:
import mailIcon from '../../../assets/icons/mail.png';
import passwordIcon from '../../../assets/icons/password.png';
import mainLogo from '../../../assets/brand/main-logo.png';
but also have this:
index.js in the assets folder
export const brand = {
mainLogo: require('./brand/main-logo.png'),
logoHorBlanco: require('./brand/logo-hor-blanco.png'),
};
export const icons = {
checked: require('./icons/checked.png'),
unchecked: require('./icons/unchecked.png'),
};
SomeComponent.js in somewhere
import { brand } from '../../assets';
The first way allow me to import only the images that I needed, but is dificult to mantain the paths. The second way, is exported from the assets folder, so when I need an images I just import the right object and use the image that I need with brand.mainLogo (for example).
So I want to know:
If there are differences in performance between the two options.
When im importing the brand object for example, are (in some way) imported (or required, or cached, or something) all images in that object, o just the one that I call with brand.mainLogo.
Thanks.

How can I configure create-react-app to export CSS into two different files

I'm working a project that will dynamically allow the user to change themes, and uses reactstrap and styled-components under the hood. We want to configure all of the variables via SASS, which is working fine. In order to make those variables available to styled-components, we have been using sass-extract-loader to create theme objects.
This all works great when we statically choose one of the themes, but I haven't been able to get it working dynamically reliably. I have two issues:
1) In development, it works fine to switch the theme once. If I change it again, my non-styled-components (i.e., raw reactstrap components) are styled with the second theme. I believe this is because the second theme is loading and overriding the original CSS.
2) In production, I get the same mix as #1 by default (i.e., because all of the CSS files are being put together into a single bundle, reactstrap components are styled one way, while styled-components "honors" the theme).
I believe the best option for us is to have the themes in two separate CSS files, and to toggle "alternate" rels on them. I just don't know how to configure CRA not to put all of the CSS into a single main bundle, and let me manually add links to alternate stylesheets. If I can split them out into separate files, I believe I can just add tags and dynamically swap the rel="alternate" property.
There may well be better ways to accomplish this. My understanding is that the easiest way to control the Bootstrap themes is via SASS variables, and I'd like to make sure those variables don't have to be re-defined when using them in styled-components.
If you want to apply styles conditionally, you can import your stylesheets in your index.js file and make it available to all your components through the context API. First of all we import the CSS files into index.js.
import themeA from './css/themeA.css';
import themeB from './css/themeB.css';
However, by using it this way, you cannot have element selectors in both CSS files, because they would be globally applied from both files. However, you could import an extra stylesheet that complements the selected theme, in which you define the element selectors.
By using CSS modules, you avoid the need for element selectors. You may want to read this article if you are unfamiliar with CSS modules: https://javascriptplayground.com/css-modules-webpack-react/
If you still need to apply element selectors in one theme, you can do so, but they will also get applied in your other theme this way.
import './css/default.css';
This example below is a modified version from the React documentation: https://reactjs.org/docs/context.html
In this example, we draw a button that changes the global theme when
it its clicked. There are three parts in this example that are crucial
to understand if you want to use React its context API.
1. Creating a Context.
Creating a Context is being done by assigning the return value of React.createContext(yourValue) to a variable. This variable can then be used to use the Provider or Consumer component inside your React components.
const ThemeContext = React.createContext();
2. Providing a value by passing it to your Provider component as prop. Now your value is accessible to all your components.
class App extends React.Component {
swapTheme() {
this.setState({ withThemeA: !this.state.withThemeA });
}
render() {
const theme = this.state.withThemeA ? themeA : themeB;
return (
<ThemeContext.Provider value={theme}>
<ThemedButton onClick={this.swapTheme} />
</ThemeContext.Provider>
);
}
}
3. Listening to updates with the Consumer component.
To listen for changes, you need to use the Consumer component. The passed function receives the theme as an argument so it can be assigned to the className prop of the button element.
class ThemedButton extends React.Component {
render() {
return <ThemeContext.Consumer>
{theme => <button className={theme.Button}}>click me</button>}
</ThemeContext.Consumer>;
}
}

Joomla Terminology: view, layout, task and component development

I'm a developer and I am very confident with MVC pattern and have already developed a lot of webapp from scratch using php framework like symfony or yii.
I'm a little bit confused about joomla mvc and terminology and after googling a lot, read joomla book extensions guide, read on joomla website my doubt are still there.
What is confusing for me is the component mvc structure and how I have to set up "my way of think" about joomla mvc, for doing the things in the joomla way.
In particular I am used to reasoning in terms of controller/action (like in symfony and yii framework)
So the final list of all my webapp url will be
controller1/action1
controller1/action2
controller1/action3
controller2/action1
controller2/action2
Each controller's action will decide what view to render and what layout to use for showing the view.
In particular in these frameworks, the definition of a layout is exactly the mean of a layout. And the view is the "core part" of the page.
So I can have a view with a list of users and I can put this view inside a mobile layout or a desktop layout, or to build a view for mobile and put it only in the mobile layout and so on.
The final result about directory structure in my webapp is something similar to the following:
controllers/
controller1
controller2
controller3
models/
modelForTableA
modelForTableB
views/
controller1/
viewForAction1
viewForAction2
layouts/
mobileLayout.php
desktopLayout.php
and for me is very clear to understand.
So finally my questions are:
how would be the directory structure in joomla?
what are in joomla the definition of view, layout and task?
I need to clarify that I do not need an explaination about MVC works in general, but if I would achieve the same result as before, how I have to organize my code and my work?
Suppose that I want to build a component with the following "url"
userController/addUser
userController/editUser
userController/listUsers
userController/viewUserDetail
anotherController/addOperation
anotherController/editOperation
anotherController/myNonCrudOperation
Thank you very much
Routing in Joomla is slightly different. The SEF URLs are built from menu items, which in turn point to a View/Layout combination.
This turns things around: a controller is not bound to a specific View/Layout.
Let's make an example of the flow with the addUser functionality you mentioned as an example; I'll be referring to these files (but you'll have plenty more):
/controllers/user.php
/models/user.php
/views/useradd/view.html.php
/views/useradd/tmpl/default.php
/views/useradd/tmpl/default.xml
/controller.php
/router.php
As you can see the layouts are inside each view's tmpl folder.
router.php
Let's start from this last file: router.php defines our custom SEF rules so, after Joomla passes the call to our component (usually with the params
?option=com_componentname) we can takeover and interpret the URL as we wish. It is a bit hard to get started with but does provide the most flexibility and power. We don't really need to implement it at all for this simple example: so back to our registration now.
First step: show the "new user" form.
You would typically bind this to a menu item, pointing to the /views/useradd/tmpl/default.php; the /views/useradd/tmpl/default.xml contains the definition of the layout so it's available in the menu manager. Very often there is only one layout per view.
Control is passed to the view /views/useradd/view.html.php , and the view will then load an instance of its own model (automatically chosen based on the view name, you can load other models of course) to gather any initialization data.
The view then renders the layout, and presents it to the user.
The layout's responsibility includes generating a form with an appropriate action (endpoint) and security tokens if appropriate:
<form action="index.php?option=com_mycomponent">
<input type="hidden" task="user.save">
<?php echo JHtml::_('form.token');?>
as you see it doesn't really matter if you want to use <input or params on the url, and you can most often mix them.
Form interaction
For autocompletion the form may need to invoke some backend controller methods, i.e. the method emailAvailable() in the /controllers/user.php
It does not make sense to have such functionality indexed, so we'll invoke the method directly with a non-SEF url:
index.php?option=com_ourcomponent&task=user.emailAvailable
followed by any other parameter. This will work in both get and post.
The controller /controllers/user.php's emailAvailable() method will return a json structure and then invoke exit() as we don't want the CMS to kick in at all. An alternative solution is to add the param &format=json in the call.
{"email":"johndoe#example.com", "available":true}
Saving the data
When the user submits the form, processing is first handled by the controller since a task is specified. (see above task=user.save). Joomla will invoke the method save() in the controller /controllers/user.php.
This time, however, our controller is responsible for returning information to the user. After processing the data, it may choose to re-render the registration form showing an error, or a thank you page. In either case the controller simply sets the redirect, letting Joomla handle the rendering when appropriate.
$this->setRedirect(JRoute::_('index.php?option=com_yourcomponent&view=useradd', false));
More control
Each time a controller task is not specified, the display() method of the main controller is invoked. You can add custom logic there.
Joomla fires several events during a view rendering; these can be intercepted by a system plugin or - if you add in the calls - other kinds of plugins as well. You may even create your own types of plugins. Do not try to instantiate a view manually from a controller, as this may inhibit plugin firing.
Small insight,
1) Directory Structure
controllers/
controller1
controller2
controller3
models/
modelForTableA
modelForTableB
views/
layout1
2) View and layout and task
check this answer
3) More routing techniques with SEF.
Hope it helps.
solved with this. I cannot delete this question because there already exists other answer.
Could any moderator close or delete this? Thank you
https://joomla.stackexchange.com/questions/18774/joomla-terminology-view-layout-task-and-component-development/18799#18799

ReactJS, React-Router Getting previous path

I am trying to make a single page application in which I have 3 components : Index, BluePage and GreenPage
I'm trying to use React and React router to switch through them. The layout is as follows:
This view is supposed to be like a sliding page and can be better visualized like this following diagram:
In order to do these transitions, I am currently using ReactCSSTransitionGroup and CSS classes, however it is becoming difficult as the direction the page must animate depends on the page that was being viewed before.
For example, if the BluePage was in view, and the user pressed the "back", button, the Index should move into view from the right.
On the other hand, if GreenPage was originally in view, the Index should move into view from the left.
The Question
How can I use React Router to send the existing path to the next component, so I can animate the components properly?
Should I continue to use ReactCSSTransitionGroup or should I handle animations in the componentWillMount and componentWillUnmount callbacks?
If so, how does adding CSS classes to objects after initial rendering work?
I apologize if these questions seem somewhat novice - I am still a beginner to ReactJS. Thanks for all the help!
If any clarification is necessary, let me know.
I would recommend you to check react-swipeable-views.
In this component, you just need to add all of your views (components) as children of the SwipeableView component. The currently active view is defined by index prop of the SwipeableView. You switch the view with buttons, you simply need to create a state in the main component (App, for example) and update this state in onClick handler. It would look like this:
class MainComponent extends Component {
state = {
index: 0,
}
onBlueButtonClick() {
this.setState({ index: 1 });
}
render() {
return (
<div>
<div onClick={() => this.onBlueButtonClick()}>Click me!<div />
<SwipeableView index={this.state.index}>
<BlueView />
<GreenView />
<RedView />
<SwipeableView />
</div>
);
}
}
Hope it helps! ;)
EDIT: I have added a button in the example to explain how to use this component when there is no swipe effect. This is a React component and not a React Native, so it was made to work on a website, therefore without a swipe. I use it in one of my projects. Here's a GIF of it.
What I would suggest you is tu use swiper.js. Why?
performant (desktop, mobile)
no jquery needed
huge api, with very usefull features for your use case
change slide programmatically: swiper.slideTo(2) or swiper.nextSlide())
Hash/History Navigation: sync between hash and slides
you can disable touch gestures
etc..
Setup
npm install swiper --save
Import
const Swiper = require('swiper');
or
import Swiper from 'swiper';
Usage
see demos with example

Use anchor tag to link to same page using react router hashlocation

Trying to link to the same page with anchor tag but as i am using react router HashLocation as below, router catches it preventing the anchor to work as normal in addition of producing error of "No route matches path".
Router.run(routes, Router.HashLocation, (Root) => { React.render(<Root/>, document.body); });
Same Problem has been asked in the link below with some hint of using "HistoryLocation" but i want to stick with "HashLocation" and those link do not provide concrete answer, thus need help:
1) How to use normal anchor links with react-router
2) Using React-Router to link within a page
I wonder if there are some kind of filter in router to exclude some hash so that i can use default same page anchor linking.
The whole point of using the HashLocation router is to use the # to handle routing, it's a bit of a hack to allow client side navigation, but in fact it's a Single Page Application.
You can't have more than one # in your url, it makes no sense for browsers to have multiple ones. With that in mind, I think you should handle the "in page" navigation (but in fact your whole site is the "in page navigation") yourself, maybe simply using some jQuery (or pure javascript) code to scroll to the specified DOM id maybe on some hook after react-router transition.
Try something like this.
componentDidUpdate() { if ((this.props.index == this.props.selected)) React.findDOMNode(this).scrollIntoView(); }

Resources