UX in E-Commerce: Web vs. Mobile

robusta_Blog Posts-19 (1)

There is no argument about how e-commerce has integrated itself in our lives in the recent couple of years. Online shoppers now have access to e-commerce websites through different platforms; laptops, tablets and smartphones. Although it’s the same shop, where the user goes through the same journey, the experience quite varies between bigger and smaller devices and how your users interact with them.

In this post, we are going to explore this user journey and the differences in interactions between a 14-inch laptop and a 4-inch smartphone. This inspection will only include comparison between the view of the website from a desktop view and mobile browser view (responsive version).

The journey

The e-commerce website visitors aren’t all the same when it comes to familiarity level with the shop. Some are frequent visitors, beginners or first-timers. Thus, every user will take a different path. For example: a frequent user will probably go through a much faster checkout experience, since their info is already saved in the system, rather than a new user that still needs to provide their payment and shipping info.

However, we will go through some of the main screens that most of the users will probably go through which are

  • Home page
  • Category page
  • Product page
  • Cart
  • Search
  • Search result
  • Checkout
  • Post-checkout & Account

Home page (1/8)

Similar to shop window display, you showcase products, discounts and offers in this page. Users should be able to tell if they can buy what they want just from skimming through this page, otherwise they will abandon the website for another alternative.

Web view:

Web view - Source: walmart.com
Source: walmart.com

 

Walmart focuses on listing ads, offers and campaigns in the home page. This makes the page look more lively and active which is a great attention grabber for the shopper.

Mobile view:

01-home-mob101-home-mob1

Source: walmart.com
Source: walmart.com

Similar to the web, ads and offers can be found but in a much more compact design using the slider to make it more usable for the users holding their phone and using their fingers to interact with the screen. A common practice is to list all the shop categories in the home page of the mobile view for accessibility and exposure to display as much information as possible in a such a limited space.

Category page (2/8)

This page includes listing of all the products related to a specific group. Users would make use of this page if they are hesitant about which product to buy and/or would like to view multiple options or if they just came to browse without a specific destination or purpose in mind.

Web view:

Source: nordstrom.com

Source: nordstrom.com
Source: nordstrom.com

Nordstrom helps their users decide on the product they want much faster by guiding them, using big and flashy imagery indicating subcategories. Once the user clicks on a certain subcategory, they are redirected to a clean display of products side by side, as well as all the relative information they need to view.

Mobile view:

05-category-mob1

Source: nordstrom.com
Source: nordstrom.com

Due to limited visual space, the subcategory filter is replaced with a button that opens a list of all the subcategories, followed by products display identical to the web view.

Product Page (3/8)

Web view:

Source: gilt.com

Source: gilt.com
Source: gilt.com

Product images are the closer the shopper will get to the actual product. Using clean and high-quality images enhances the experiences tremendously. That’s why Gilt web design capitalizes on product images without excluding relative information like price, color options, quantity and product specifications details.

Mobile view:

09-product-mob1

Source: gilt.com
Source: gilt.com

The information included in this view is identical to the web design; however, all elements are resized, aligned and placed accordingly to provide readability and usability on mobile.

Cart (4/8)

Web view:

11-cart-web1

Source: sears.com
Source: sears.com

Source: sears.com

Sears makes use of the big screen by including a lot of details regarding the shipment and offers, as well as the product information.

Mobile view:

Source: sears.com
Source: sears.com

Unlike the web design, the limited space forced the design to include only the product information. The only consistent principle in both web and mobile views is making the “checkout” button the most prominent visual element.

Lessons Learned

There are no differences in the content present in both web version and mobile version of the websites. The only difference is how it is presented. Web users interact with a bigger space using a mouse or a touchpad, while a mobile user has access to small screen and is able to navigate using only hand gestures. That difference in interaction requires different types of design elements to ensure usability on either platforms.

The journey isn’t over yet. We will be exploring the rest of the screens in part 2. Stay tuned!

Install Secured Redis on Ubuntu Server 14.04, 16.04 LTS

Secure Redis Server

Redis is a secondary database that is useful for session storage as well as performing background jobs like sending emails, user notifications,..etc.

In this blog post you will learn how to install a stable & secured version of redis by the following steps:

1. Install stable version of Redis

To install Redis, first make sure the tcl package is installed.

sudo aptitude install build-essential tcl8.5

1.1 Check for the latest version of Redis and grab it into your /tmp directory.

cd /tmp wget
http://download.redis.io/releases/redis-stable.tar.gz

Now extract it.

tar xzf redis-stable.tar.gz

Then configure it and install it.

1.2 Installing the server

In the same directory you extracted the redis stable version, write in your terminal

cd redis-stable
make
make test
sudo make install

Then configure an instance and add it to your boot sequence

cd utils
sudo ./install_server.sh

Now test your installation:

sudo service redis_6379 start

Check it through its command line interface:

redis-cli

You now have Redis installed and running. The prompt will look like this:

redis 127.0.0.1:6379>

Type in ping, and the prompt should look like this:

redis 127.0.0.1:6379> ping
PONG

To set Redis to automatically start at boot, run:

sudo update-rc.d redis_6379 defaults

2. Secure the installed Redis

2.1 Binding to localhost

By default, Redis server is only accessible from localhost. However, if you followed the tutorial to set up a Redis master server, you updated the configuration file to allow connections from anywhere. This is not as secure as binding to localhost.

Open the Redis configuration file for editing:

sudo vim /etc/redis/6379.conf

Locate this line and make sure it is uncommented (remove the # if it exists):

# bind 127.0.0.1

2.2 Configuring Redis password

Configuring a Redis password enables one of its two built-in security feature – the auth command, which requires clients to authenticate to access the database. The password is configured directly in Redis’s configuration file, /etc/redis/6379.conf, which you should still have open from the previous step.

Scroll to the SECURITY section and look for a commented directive that reads:

# requirepass foobared

Uncomment it by removing the #, and change foobared to a very strong and very long value. Instead of foobared, make a more complex password using one of sha algorithm types like:

$: echo -n "yournormalstring" | openssl sha1
f44f60738a2ecbc060a7fe974371997137ac4e69

Store this key just in case. Then alter your redis conf file to be:

requirepass f44f60738a2ecbc060a7fe974371997137ac4e69

After setting the password, save the file, and restart Redis:

sudo service redis-server restart

To test that the password works, access the Redis command line and try to write ping, you will get this (error) NOAUTH Authentication required. Do not panic, it is normal as in the next example, until you get the OK acknowledgment:

$: redis-cli
redis 127.0.0.1:6379> ping
(error) NOAUTH Authentication required.
redis 127.0.0.1:6379> auth f44f60738a2ecbc060a7fe974371997137ac4e69
OK

N.B. Do not forget to alter your applications to use the new password accordingly.

Enjoy using a secure redis!

Troubleshoot

In case of any misbehaviour, you can remove the password from the conf file and shutdown redis manually, but you need to make the following:

  1. Comment the require password line in the redis conf file.
  2. Go to the redis console
$: redis-cli
redis 127.0.0.1:6379> auth f44f60738a2ecbc060a7fe974371997137ac4e69
OK
redis 127.0.0.1:6379> shutdown
redis 127.0.0.1:6379> quit
  1. start the redis service, and it is now without a password
sudo service redis_6379 start

 

Developer Communities: All You Need to Know

robusta_Blog Posts-12

What are Developer Communities?

Developer communities are places where we can

  • Share and brag about our work
  • Ask questions and find help
  • Follow for news
  • Make new connections and meet new people in the development field

They’re all about “finding solutions” and building up new experience, closer aligned with a community of practice than a community of any other type.

Communities you have to be following

In our field, there are A LOT of online communities that focus solely on development like

We also have other channels that are superiorly active like

  • Facebook tech groups/pages
  • Reddit tech subreddits
  • Google developer groups
  • Twitter

Huge companies and enterprises building products for the developers to use started to realize the importance of actively participating in the community through seeking the developers themselves. A new role has emerged called “Developer Evangelism,” where a developer evangelist is someone participating in the community in a way that makes him advertise for a product while making it sound exciting to others and without being intrusive.

You can find developer evangelists all around you. They are the people you follow on Twitter for news, who write tutorials on their blogs telling you how to do something. Think of them as social and brand influencers of all things technical development. Examples are countless and include

In Egypt, most of the tech communities are driven by individuals and not by companies or organizations. The role of developer evangelism hasn’t really matured enough yet. Instead, big companies who build ready-to-use “solutions” (like Oracle and Microsoft) advocate these solutions to other companies; not to developers

We have a big chance of taking the lead in the tech communities through focusing on the “Individuals.”

Why you should actively participate in developer communities

Developers in general show interest in participating in tech communities because it’s a way to create new connections. Connections are important because they mean

  • New technical knowledge
  • New job opportunities

How you can start contributing to the community TODAY

 Before you start contributing, there’s a set of skills you need to know that you have to work on along the way

  •  Be extremely eager to learn
  •  Be an excellent communicator through verbal and written communication
  •  Enrich your technical competence in your areas of interest
  •  Be an excellent listener and have the capacity to discuss anything

There are mainly 2 channels you should be focusing on…

 1. Online communities

   These will massively help you grow your technical knowledge and will show you how others discuss things and communicate with each other. Most importantly, they will highlight your weaknesses and allow you to work on them at your leisure.

 2. Offline/Local communities

  These are where you start having impact on others, sharing as well as always learning along the way. You start to advocate and give advice.Take care that you should be open to all opinions even those that trigger you and those you think are worthless though.

Benefits of having a leading role in local communities

  •  Your technical knowledge will grow significantly.
  •  You become more confident in the work you do and start enjoying it more and more.
  •  People start to idolize you as an expert (careful about that).
  •  You build relationships with other developers, entrepreneurs, and companies. Your connections grow beyond what you ever thought they could.
  •  You dedicate sometime everyday to reject the job offers you are getting via LinkedIn and emails 🙂

Benefits that the organization you belong to gains

  • With the growth of your technical knowledge, your organization is directly affected by the quality of the work that you perform.
  • Customers will have more confidence in your organization’s work.
  • Your organization starts attracting more customers.
  • Your organization starts attracting candidates who are eager to learn because they want to work with “YOU”.

Where you should start first

 1. Online

  • Participate in online discussions like Stackoverflow, Reddit, Github
  • Build something that you know will benefit other developers.
  • Write down articles on your personal blog, organization blog, Medium, WordPress giving your personal insights and ideas on a particular problem
  • Check local communities like Facebook tech groups and help others whenever you can through comments and answering questions whenever possible.

 2. Offline

  • Check for student activities and offer your services as a mentor/speaker at universities.
  • Offer to help those who are trying to give back to the community either through organization or through metorship/speaking (RailsGirls Cairo)
  • Find and attend local meetups and show your will to participate in organization and speaking. If none is available, start building your own community with the help of your friends and colleagues.

Bro tips

  • A good advocate is someone who is technically superior. Keep reading and learning and trying. Question your work and methods. Seek excellence.
  • Be kind to others around you. Their age, color, gender, religion or technical capabilities should never matter. As long as they are not toxic, you should stand at the same distance from all.
  • Listen carefully and don’t underestimate anyone. You would be surprised by the ideas and the work of the people you frankly think they aren’t as good as you.
  • Always be humble.
  • Give without waiting for a return. Good deeds pay off in ways you cannot imagine.
  • It’s a long-term investment that takes time. Be PATIENT and always enjoy the ride.

Improving The UX of E-Commerce Websites Without The Big Bucks

UX_Nada

In the past few years, online shopping is becoming much more established with offline businesses realizing the importance of having to be online as well as many users especially millennials turn to online shopping as their primary destination with the help of smart phones. E-Commerce conversion rates have been increasing across different devices; desktops and mobiles (smartinsight). Even though more and more people are shopping online successfully, the user experience of most websites is not up to par.

Baymard.com: The dots are color-coded in accordance with their usability performance, with red dots indicating “poor” usability, yellow representing “acceptable,” and green “good.” The benchmark average is denoted with a back circle.
Baymard.com: The dots are color-coded in accordance with their usability performance, with red dots indicating “poor” usability, yellow representing “acceptable,” and green “good.” The benchmark average is denoted with a back circle.

User experience (UX) is “a person’s perceptions and responses that result from the use or anticipated use of a product, system or service” (ISO 9241-210). Your users should be able to fully understand what you offer and how to get it. On an E-Commerce website, it might seem obvious that it sells laptops but they can’t find the right or enough information they need to actually buy the laptop they wanted.

Better understanding of your audience leads to less frustrating design which in turn leads to higher conversion rate. Therefore, performing a user experience evaluation, every now and then, is essential.

What is UX Evaluation?

User experience evaluation denotes using different types of methods and tools to assess how well the users can learn and interact with the product or website. In case of an E-Commerce website, it is when the user is able to navigate the shop, find the product they desired and successfully checkout.

There are many different methods that can be used to perform a UX evaluation that yields quantitative and qualitative results. A lab user testing is an example of a quantitative method that involves recruiting real users, assigning them to perform tasks on the website and observing their behaviour to document the results in the form of metrics.
Examples of qualitative methods are cognitive walk-through and heuristic evaluation which relies on thorough inspection of the website by an expert and assessing how well the users perceive the design.

Cognitive Walk-through

A cognitive walk-through is an approach used to evaluate the usability of the website from the perspective of first-time user with a specific intention.

The evaluation starts with the assessor defining a user task(s) then inspecting how the user would execute these tasks on the website. For example, a college student wants to buy a new laptop to use for studying. One of the scenarios to perform that task on an E-Commerce website would be as follows.

  1. User visits E-Commerce website through direct URL then scans homepage for “laptop” or “electronics”. He finds a “laptops” link in the header and clicks it.
  2. User visits the category page with many laptops on display and option to filter and sort products.
  3. User visits different product pages then clicks “add to cart” on the laptop he liked.
  4. User is content with his choice and wants to checkout. He visits the cart and clicks on the “checkout” button.
  5. User goes through the checkout process.

Throughout that scenario, the assessor asks the following four questions per each new step:

  • Will the user try and achieve the right outcome? The user was able to find the laptop he wants and successfully select it and proceed to checkout.
  • Will the user notice that the correct action is available to them? The “add to cart” button or the “checkout” button was easy to find.
  • Will the user associate the correct action with the outcome they expect to achieve? Whenever the user clicks on a link or button, they were redirected to the right page.
  • If the correct action is performed; will the user see that progress is being made towards their intended outcome? The user able to keep up with the checkout process.

By answering these questions through every step of the scenario, the assessor can point out the flaws in the experience design. One of the benefits of this method is that it is a considerably cost efficient compared to other methods.

Heuristic Evaluation

Another means of user experience evaluation is conduction of heuristic evaluation. A set of heuristics is chosen and the website is reviewed to assess how the design is violating these heuristics. One of the frequently used sets of heuristics used is Jakob Nielsen and Rolf Molich’s 10 Usability Heuristics for User Interface Design.

Nielsen defined each of the following heuristics in detail so we will be discussing them from an E-Commerce point of view.

  1. Visibility of system status

Users should always be able to tell what is going on at any point in time. They can identify what page they are viewing. If the website is loading, it should say so.

Pages in amazon have clear title indicating what you should be expecting.
Pages in amazon have clear title indicating what you should be expecting.
  1. Match between system and the real world

The most iconic application of this heuristic is using the cart icon on the “Add to Cart” buttons. Users are already familiar with their real-life surroundings so they relate faster to your interface if you use the same elements.

2-1 2-2

Cart icon, cart icon everywhere
Cart icon, cart icon everywhere
  1. User control and freedom

People don’t like to feel stuck or helpless. User should be able to undo or redo any significant action on the website.

Walmart notifies me of deleting an item from the cart and provides me with a clear “undo delete” action.
Walmart notifies me of deleting an item from the cart and provides me with a clear “undo delete” action.
  1. Consistency and standards

Consistency creates a sense of comfort where the user is confident about the identity of every element in the design. An example of that can be represented in the fact that all buttons should look similar and no other element should look like a button. Consistency isn’t only about in-website consistency but also in using design elements that are familiar within your industry.

4-2

Both Walmart and Amazon are using the common terminology “Department” used even in physical stores.
Both Walmart and Amazon are using the common terminology “Department” used even in physical stores.
  1. Error prevention

The design should keeping error-prone actions to a minimum. If you are asking the user to enter their credit card number, the field should be designed to accept only 14 numbers.

Thanks Walmart for the heads up. No time wasted when I try to create an account and then you tell me that password isn’t valid.
Thanks Walmart for the heads up. No time wasted when I try to create an account and then you tell me that password isn’t valid.
  1. Recognition rather than recall

The human brain is limited to process few items at a time but there are too many information that you need to convey. That’s why recognizing something is easier than exerting the mental effort to try and understand it.

Walmart grocery shopping cart includes product images with quantity always displayed right next to the products which makes it easier to review what I added rather than remembering it.
Walmart grocery shopping cart includes product images with quantity always displayed right next to the products which makes it easier to review what I added rather than remembering it.
  1. Flexibility and efficiency of use

The efficiency of an E-Commerce website is mostly about how easily the users can find the products they want. Having a sensible and familiar navigation and categorization makes the experience much smoother. You’d expect to find mobile accessories within the same category as mobile phones. Then, there is also the efficiency of the checkout process which is how the design incorporates the other heuristics.

Souq.com checkout progress bar indicates how easy the checkout can be and how much I have progressed.
Souq.com checkout progress bar indicates how easy the checkout can be and how much I have progressed.
  1. Aesthetic and minimalist design

Less clutter makes your products stand out which helps the user focus better on what is really important. In addition to having your products photographed in a very good and clear way, minimalistic display doesn’t overwhelm the user to the point of leaving the website.

8-1

Ebay came a long way with their redesign even if it’s not the most visually rich design but took into consideration how crucial aesthetic is.
Ebay came a long way with their redesign even if it’s not the most visually rich design but took into consideration how crucial aesthetic is.
  1. Help users recognize, diagnose and recover from errors

Users don’t want to deal with problems so if something goes wrong that they can’t handle, they’d probably give up on your website. Always offer the reason for the problem and how to solve it in a clear and understandable language.

Clear instructions from Amazon to why I can’t add the product to the cart and how to fix this problem.
Clear instructions from Amazon to why I can’t add the product to the cart and how to fix this problem.
  1. Help and documentation

Your users will always need help, not because of the lack of good design but maybe because of unforeseen accidents or they might have a concern that is not addressed. Similar to a real-life store, where you can ask a shop assistant for help, having an online and available customer support boosts the efficiency of your platform experience.

10-1

Souq.com offers customer support phone number. On the other hand Walmart offers a help page with FAQ.
Souq.com offers customer support phone number. On the other hand Walmart offers a help page with FAQ.

Once the assessor evaluates the violations to these heuristics, he assigns a severity rating to it. The higher the severity is, the more the violation affects the experience negatively. This helps to organise usability problems and decide on the priorities of fixing them.

The Takeaway
As your main source of conversion is your users, the evaluation should be based on their behaviour and perception. While some methods are costly more than others, there are methods that are efficient with less effort. Performing a user experience evaluation before, during and after designing your E-Commerce website surely brings out potential usability problems to light so that you can treat them head-on eliminating the risk of losing customers and consequently money and definitely contributes to better conversion and an increase in sales.

Android RTL Support

Abouraya blogpost1200-06

The majority of mobile apps are designed LTR (Left to Right), that is because the vast majority of the world languages are written from Left to Right and only a small number of languages are written from Right to Left such as Arabic. Most of mobile developers never worry about this issue since most of the apps are not intended to target users from regions using languages written from Right to Left also because it was not as easy as it is now to support both directions. As the competition started heating up, it became important to globalize the apps and provide localized versions in order to reach more users and improve app downloads. Moreover,  the rise of mobile apps development in these Arabic-speaking countries made it crucial to provide RTL support.

It is very easy to provide localized versions for different LTR languages in android apps by just providing another strings.xml file under values-XX folder where XX is the language code which contains all the translations for the strings used in this app.

Android 4.2(API 17) released in 2013 has provided full Native support for RTL layouts; it has become very easy to take advantage of this feature and all you need are just few simple changes in your code.

How to start:

First of all, in your Manifest.xml file, you need to declare under the <application> element android:supportsRtl=”true”

Use Start and End layout properties instead of Left and Right, respectively. In LTR layouts, start means left and end means right; however, in RTL start means right and end means left.

Examples for these properties are Padding, Margin, TextView Drawables, Gravity, LayoutGravity, and layout alignments.

In case you need a custom layout in for RTL, just provide the layout with the same name under ldrtl qualifier

Drawables:

Usually the icons you are using are direction independent, so you will not need alternative drawable for RTL; however, there are some cases where you will have to, for example, the back button.

Normally for LTR this is how it looks like:

Screen Shot 2017-02-13 at 10.26.39 PM

If you use the same button for RTL this is how it will look like:

Screen Shot 2017-02-13 at 10.26.54 PM

While what you need is this:

Screen Shot 2017-02-13 at 10.49.45 PM

You can achieve this by mirroring the icon using an external tool and add the new icon with the same name in drawable-ldrtl folder, or just use the forward navigation button and change it’s name in “drawable-ldrtl” folder

In case your minimum SDK is 19, you can use android:autoMirrored=”true” attribute in vector drawables where as the name implies will automatically mirror the icon vertically in case the direction is RTL

Text appearance:

For more control over the text appearance, you can use these attributes

android:textAlignment — attribute for setting the alignment of a component’s text.

android:textDirection — attribute for setting the direction of a component’s text.

Use gravity for textAlignment which is default for the root view. The gravity determines the alignment, ALIGN_NORMAL, ALIGN_CENTER, or ALIGN_OPPOSITE, which are relative to each paragraph’s text direction

Use locale for textDirection which makes the paragraph direction is coming from the system Locale.

To apply these attributes you can add it each textview or globally by adding it to main AppTheme in styles.xml

<item name="android:textAlignment">gravity</item>
<item name="android:textDirection">locale</item>

To know about the variations of textAlignment and textDirection attributes check

https://developer.android.com/reference/android/R.attr.html#textAlignment

https://developer.android.com/reference/android/R.attr.html#textDirection

Application Language Preference:

All the mentioned-above is sufficient to provide RTL layout and in case the app is supposed to follow the device’s language then nothing more is needed. However, in case the user is supposed to be able to choose a specific language, then few more lines of code are needed.

To change the Locale of the application programmatically use the following

String langCode=”ar”;
getContext().getApplicationContext().getResources().updateConfiguration(changeLanguage(code)),
getResources().getDisplayMetrics());
public static Configuration changeLanguage(String code) {
  Locale locale = new Locale(code);
  Locale.setDefault(locale);
  Configuration config = new Configuration();
  config.locale = locale;
  return config;
}

Then restart the activity to apply the changes

startActivity(getIntent());
finish();

However, if the user changed the language of the device, the app will be affected, and in order to prevent that use configChanges attribute under each <activity> element in the Manifest and list Locale and layoutDirection as the changes you would like to handle manually.

android:configChanges=”locale|layoutDirection”

This prevents the application from recreating the activity then override onConfigurationChanged in the activity

@Override
public void onConfigurationChanged(Configuration newConfig) {
  super.onConfigurationChanged(newConfig);
…
…
}

Then you can reapply the user’s configuration for the app again in onConfigurationChanged

getContext().getApplicationContext().getResources().updateConfiguration(
changeLanguage(Session.getLanguage()), getResources().getDisplayMetrics());

Fallback to LTR:

It is possible to force a certain layout direction using android:layoutDirection, it can be useful, for example, when using a ViewPager and TabLayout, the default sliding animation is LTR when doesn’t change in RTL. So a possible solution is to keep the android:layoutDirection=”ltr” and reverse the tabs orders and fragments programmatically. You can check at runtime if the layout is RTL using this method in TextUtils getLayoutDirectionFromLocale .

Another example  is the phone number field, numbers direction are always LTR which means it does not change with language direction, so a possible solution is to use Left and Right instead of Start and End or use android:layoutDirection=”ltr” for the parent view.

Screen Shot 2017-03-13 at 11.21.45 AM

Hopefully these tips could help you with your developing any application in Arabic. Please don’t hesitate to comment below if you have any questions regarding RTL support in android or anything regarding android development in general. Finally please refer to the official android blog for more information about native RTL support.

https://android-developers.googleblog.com/2013/03/native-rtl-support-in-android-42.html

Capitalizing on Technology in Charity

01

Charity has always been one of the fundamental themes in the lives of Egyptians. With the continuous declination of the standard of living for both the lower-middle and lower classes in the society, NGOs and people working in the charity and CSR fields are facing a huge challenge to provide an adequate support to those social classes that the country’s government is failing to provide.

Charity and community service in Egypt comes in many forms such as NGOs, CSR departments in corporates, clubs in universities, small groups of friends or even individuals. Activities in all these entities are typically more centralized around some seasons that are mostly religion-related. However, to give you a hint of how huge this theme is in Egypt, during Ramadan only in 2015 approximately EGP 30 Billion donations were collected according to the official numbers. (For more details about the economics of donations in Ramadan, we recommend this article by Omar El Shenety.)

In spite of this huge amount of spending and donations, the relationship between charity and technology in Egypt remains very shallow. From my personal experience in this field and what we have reached in robusta throughout the different engagements with NGOs and CSR departments, I believe that technology isn’t being fully utilized or even slightly utilized at a minimum level to help in the charity work here in Egypt.

During our previous engagements in robusta with lots of NGOs, we noticed that most of them are only willing to make use of technology superficially by building simple websites to use them only as an online informative tool. While on the other side there are several serious problems that are present in the current charity/CSR model that technology would really help in resolving but utilizing technology isn’t on their roadmap.

Below are some examples of the current problems and how technology can help resolve that.

Accessibility of Donating

It is such a pity that people are creating WhatsApp groups to collect money for certain cases. Meanwhile a simple web/mobile application listing the cases by their different types and with detailed information can be very handy especially when it is integrated with an online payment gateway provided by bank or independent platforms like Payfort.

Cases Reach

Lots of people sometimes want to donate money/furniture/…etc and actually don’t know where or how to donate despite the huge number of NGOs. The idea is that you want a simple way to do so which is quite feasible by a location based mobile app that detects users’ locations and can show the different cases around them with their needs. Location based apps can be used in an opposite way by NGOs to see the donors around them and get in contact with them.

Reaching out to more people around the globe

A lot of Egyptians all over the globe would mostly prefer to give their money donations or Zakah to the poor in Egypt or to help the people here to establish microprojects via microloans or similar models yet unfortunately there are no easy to use, credible and transparent platforms where they can do that. Then what about a mobile application that aggregates the cases from the different NGOs with their statuses and integrates with a payment gateway allowing people from other countries to donate their money online to specific cases.

Transparency

Any donor usually needs answers to some questions, where am I putting my donations exactly? which case am I supporting? and the more the donor pays, the more details and follow up they would expect to be provided with. This type of transparency is typically very difficult when you donate, for instance, via SMS or when you donate to an NGO via bank transfer but you aren’t sure where this amount of money was placed. The issue of transparency normally hinders some people from donating to NGOs. Again, this can be achieved by personalization of the donation experience when the user can have a dashboard listing the cases they are donating to and follow up on their progress with whatever amounts of money paid and with some history and statistics about the previous donations and cases.

Recurring Reminders and Notifications

We all usually get consumed in our daily work so we continuously need those reminders from NGOs or our friends if we pay a recurring donation to help some cases and technology definitely can help automating all of that with a combination of simple cron jobs on the server side and push notifications via an almost free service like Amazon SNS.

Follow up and Reconnecting

Technology in general will easily help the NGOs and the donors in several other aspects. One of those is following up on some cases that they donated for via SMSs or Push notifications which will definitely increase the credibility of the NGO.

Another one is reconnecting with the donors in case they are interested in helping specific types of cases when those cases appear or even sending and receiving feedback between Donors and NGOs.

Some Inspiring Examples

There are several inspiring examples in the charity world. I will just demonstrate the idea of three of them and there are others of course all over the globe.

Kiva is an amazing platform that provides microloans to different people all over the world to use them in unique and useful projects that would fit in their environment. The donations are mainly crowd-sourced and you can actually even choose to lend some people to help them do their project and then return your money back after they pay  and if you’re worried about being getting your money back, the loan repayment rate is 97% which indicates how successful they are.

Watsi is another adorable non-profit platform that focuses on crowd-sourcing donations to patients all over the world who are facing difficulties in paying for their treatments. They have an extensive database about the patients with their detailed cases, their stories and so on.

Farmraiser is a web and mobile platform that was built by robusta. It is a very good example for a community-service-like profitable platform. It is built to help organizations like schools, clubs,…etc raise funds for their campaigns by making students sell healthy food and these profits go to funding campaigns so there are four parties that are benefiting and profiting here, vendors who sell their products, campaign organizers who receive  funds for their campaigns, customers who buy healthy products and are encouraged to lead a healthy lifestyle and finally students who participate in the whole community service experience and learn to give back to their community.

There are definitely tons of other platforms with various ideas out there yet those three examples are just simple examples on the different types of platforms we are talking about and hope they would be utilized, implemented and followed instead of going for an informative website for an NGO.
To sum up, it is crucial for all NGOs and people working in the CSR field to pay attention to capitalizing on the available technologies and think creatively about new ideas that would make the lives of everyone easier and gets the most benefit out of the available tools that are already utilized by many and are becoming part of the people’s daily lives and culture.

On Finding The Perfect “Add to Cart” Button

0

Recently I participated in a code camp at Al-Makinah where we introduce participants to the fundamentals of the front-end component of the web. I was asked to review the model answer to one of the exercises given to the students. It was simple; they take a web page written in HTML, CSS and JavaScript and improve it in a way that shows what they’ve learnt that reflects what they were taught. The exercise addressed several aspects like user experience improvement, semantics, validation of the markup … etc. It was a simple shopping cart with several products cards laid out in a grid.

I spend a lot of time writing HTML. It’s been a part of what I am doing every day for more than a decade. For me, HTML is more than just a few elements that you throw here and there; I invest a lot in picking the elements that I use. While I was reviewing the exercise, I stopped in front of the “Add to Cart” button. It was an <a> tag with a link. I started questioning myself; part of me hates the fact that this is a link not a button inside a form. It makes perfect sense to be a button. Of course it can be made anything. Simply attaching a listener that fires an ajax request updating the cart will work. But it doesn’t feel right. This isn’t semantically correct. Before I decide what the “Add to Cart” element should be, I decided I should write down the criteria addressing how this element should behave given all the possible circumstances.

Criteria:

  1. It must have the same behavior in presence or absence of JavaScript.
  2. If there are other fields like “amount,” pressing enter (submitting the form) should behave like clicking the button.

At this point I was convinced that this should be a submit button not a link. I quickly realized that this will require each product card to have a form tag with more elements like hidden input with product id for example. In big shops, the home page sometimes hosts a lot of product cards. It even uses sliders to save the space for “Newly arrived,” “Hot offers,” “Hot in category X” and the list can go on. A single page can contain more than a hundred of product cards. All this increase the amount of the HTML tags we serve to the user and increase the page size (comparing to serving a single <a> tag per card).

There is also another problem the submit button doesn’t address and it is very common. It’s the products that need you to select attributes before adding it to your cart (like shirt size or color). It’s common that these product cards redirect the user to the full details page of the product asking him to pick the required attributes in order to add the proper item to the cart. Now I changed my mind; I don’t think it’s a problem using a link for this functionality. I decided to change the first rule I mentioned earlier; it shouldn’t have the same behavior. It just should work in a way.

Before discussing the possible scenarios, I want to clarify something before getting into the argument of whether we should support users with no JavaScript or not. I believe both sides of the argument have valid points; however, there are reasons that you don’t want to lose even the smallest fraction of the users without JavaScript. We’re talking about e-commerce where conversion is translated directly into money. The solution is also pretty simple whether you decided to go with progressive enhancement or graceful degradation as you will see later on.

The available scenarios

Using button

If the product can be added directly to the cart, use button inside a form tag. It can use ajax when JavaScript is available or submit to the server directly when it isn’t (embracing progressive enhancement).

Pros:

  • Semantically, it is more accurate.
  • The behavior is similar in presence or absence of JavaScript.

Cons:

 

  • Require more code for form tag and other elements that identify the product.

 

If the product cannot be added without selecting attributes, use an anchor tag linking to the full product details page.

Using link

Use links in all cases. When JavaScript is available, hijack the click event and add the product to the cart using ajax (embracing graceful degradation). If it isn’t, direct the user to the full details page.

Pros:

 

  • Requires less HTML, just a link with data attribute for product id.

 

Cons:

 

  • The experience is different based on the presence or absence of JavaScript.
  • In absence of JavaScript, the link that says “Add to Cart” will do something completely different. It should then say “Show product details.” This might cause confusion for people using assistive technologies like screen readers.

 

How other e-commerce platforms address this issue?

I decided to review how the other popular e-commerce platforms address this issue. At robusta, we have success stories building successful big e-commerce platforms in Egypt using popular platforms like WooCommerce and Magento Enterprise Edition. I picked the popular open source e-commerce platforms available which provided a demo and a default theme. Now, bear in mind that the result of this analysis is highly based on the used theme. If you are using a different theme it is very likely that your theme uses a different markup than what I am about to show you. The default theme is important because developers use it as a boilerplate for their themes. Some platforms like Magento allow defining a parent theme and extend it to override some of its parts instead of writing everything from scratch.

Magento 2

Magento comes with a theme called Luma. It uses a button tag without a form. The button itself has some additional data attributes related to the product. As you might guess, this implementation doesn’t work except when JavaScript is available. It’s worth mentioning that Magento 2 utilizes RequireJS to split JavaScript into modules. Luma theme by default loads 119 JavaScript file in the homepage alone. With Magento, JavaScript bundler merely seems to function properly; there is a big chance for failure at any point (by network timeout, server failure, slow internet connection,…etc.). It’s disappointing to see the e-commerce giant uses an inaccessible solution that only works with JavaScript.

WooCommerce

The number 1 WordPress plugin for e-commerce really shines with its implementation. It uses a link that directs to the current page with the query string “?add-to-cart=id”. When JavaScript is available, the product is added to the cart using ajax. When it’s absent, WooCommerce handles it in a way different than the scenarios I mentioned before. The product is added to the cart and the user is redirected to the same page again with a success message on top. WooCommerce says “Add to cart” and it delivers what it says exactly with no confusion. When the product requires picking attributes, it redirects the user to the product details page.

OpenCart

OpenCart uses a button without a form that has an onclick attribute. It requires JavaScript to work. When JavaScript is available the product is added to the cart. If the product requires selection of attribute the same button redirects the user to the full details page.

VirtueMart

Perhaps this is one of the least known e-commerce platforms but it is well known across Joomla community. VirtueMart uses a classic form with a button. If JavaScript is available, the experience is enhanced with ajax. If not, the form is submitted and the user is redirected to the cart page. If the product requires selection of additional attributes the button is disabled and the options are displayed to pick from inside the cart. VirtueMart embraces progressive enhancement and provides a solution that works smoothly.

osCommerce

This is an obligatory mention to the e-commerce dinosaur. From the minute you check the demo you get the feeling that you stepped back in time into PhpNuke. osCommerce doesn’t include an add to cart button in the listing. Adding the product to the cart is only available inside the full product details.

Conclusion

There are several methods to mark down the “Add to Cart” button. We should always embrace a method that guarantees the button will work then improve the experience using JavaScript.

Action Cable: Rails 5 Most Anticipated Features

CDMbA57p

Being a tech agency, we at robusta deal with a lot of apps with different kinds of business logic. From simple e-commerce apps to complex full-featured social networks. So being able to communicate with users is a vital feature that we have to incorporate in almost every project. We were looking for a simple solution to create chat modules in Rails apps. That was when we decided to give Action Cable a shot in one of our projects.

Action Cable

Action Cable is a simple framework that introduces WebSocket support to Rails apps. It provides a server-side as well as a client-side integration with WebSocket. DHH made a quick tutorial and a preview of Action Cable on his YouTube Channel.

WebSocket

WebSocket is a two-way TCP-based protocol. It works by opening a persistent connection between the server and the client. Both sides can use the connection for data exchange.

Drawbacks

When we decided to try ActionCable and WebSocket, we have looked for the
points where WebSocket falls behind. The main concern (still a small concern though) is that WebSocket is a relatively new protocol. Thus, older browsers lack WebSocket support. Thus, not all web browsers support WebSockets.

WebSocket Vs. Other Solutions

In our research, we had to find out the differences between WebSokcet and other solutions. Here’s a quick comparison between WebSocket and other well-known solutions.

AJAX

WebSocket protocol differs from HTTP known methods (Ajax or Polling) where the client (the browser) does not need to make a request for the data it needs to fetch.
In AJAX, the client sends a request to the server and gets an instant response from the server then the connection is closed as most HTTP requests.

Polling

Server polling resembles AJAX except that the connection is kept alive for some time until it times out and gets closed. The client requests for a new connection with the server again after a defined time.

WebRTC

WebRTC is different from the previous methods in the way the data is transmitted. In WebRTC, the data is exchanged between clients (no servers involved). On the other hand, WebSocket data exchange happens between a client and a server.

A Use Case

Here we will build a simple app to demonstrate the abilities of Action Cable. The app is somewhat similar to a Twitter replica. The app will have three main features: tweeting, messaging, and showing the online presence of registered users.

Setting up the app

We start by installing the latest version of Rails. As of this time, the latest version of Rails is 5.0.0.rc2. An important note before trying to install the latest version of Rails is that it requires Ruby 2.2.2+ to run. $ gem install rails -v 5.0.0.rc2. We then create a new app without a test framework using $ rails new TwitterCable -T --database=mysql. Now we need to create the database $ bundle exec rake db:create. Next step is writing code for our app.

Authenticating users

We setup devise for user authentication. We do that by adding gem 'devise' to the Gemfile and calling $ bundle install. Then we use Devise’s generator to install it. $ rails generate devise:install and $ rails generate devise User to create our user model. Last step is to migrate the database $ bundle exec rake db:migrate

The tweeting module

To keep our app as simple as possible, we’ll add only two attributes to our Tweet model $ rails g model Tweet content:string user_id:integer. Now we open Tweet model and add the association with User model.

  # app/models/tweet.rb
  class Tweet < ApplicationRecord
    belongs_to :user
  end

Now we need to setup the controller and the views:

  # app/controllers/tweets_controller.rb
  def index
    @tweets = Tweet.all.order("created_at DESC")
  end

  def create
    @tweet = current_user.tweets.create! tweet_params

    redirect_to tweets_path
  end

  private

  def tweet_params
    params.require(:tweet).permit(:content)
  end
  # config/routes.rb
  resources :tweets, only: [:index, :create]
  <!-- app/views/index.html.erb -->
  <div class="text-center">
    <h3>Recent Tweets</h3>
  </div>
  <br>
  <% if current_user %>
    <%= form_for Tweet.new do |f|%>
      <%= f.text_area :content, placeholder: 'New Tweet' %>
      <div class="right">
        <%= f.submit 'Add Tweet', class: 'button' %>
      </div>
    <% end %>
  <% end %>
  <br>
  <div class="text-center">
    <div id="tweets">
      <%= render @tweets %>
    </div>
  </div>
  <!--app/views/tweets/_tweet.html.erb -->
  <% cache tweet do %>
    <div class="tweet">
      <div class="callout">
        <h5><%= tweet.user.email %></h5>
        <p>
          <%= tweet.content %>
        </p>
      </div>
    </div>
  <% end %>

It’s time to try the app. In your browser, open localhost:3000/tweets. This is where we can create new tweets and each time we we will get redirected to the tweets index page.

Up until now, everything is normal as we would’ve seen in any CRUD application but things will change a bit when we start using Action Cable to handle rendering new tweets.

We can use Rails generator to create a new channel for our tweets $ rails g channel Tweet. This creates two new files app/channels/tweet_channel.rb and app/assets/javascripts/channels/tweet.js. The first file handles the connection on the server side while the other handles the client-side connections.

We have to mount Action Cable server in our routes file so that Action Cable can listen to WebSocket requests:

# config/routes.rb
mount ActionCable.server => '/cable'

# app/channels/tweet_channel.rb
...
def subscribed
  stream_from "tweet_channel"
end
...

We will use Coffeescript for its Ruby-like syntax and our convenience. Rename app/assets/javascripts/channels/tweet.js to tweet.coffee and add the following code to the file.

# app/assets/javascripts/channels/tweet.coffee
App.twitter = App.cable.subscriptions.create "TweetChannel",
  received: (data) ->
    $('#tweets').prepend data['tweet']
    $('[data-behavior~=tweet_field]').val('')
  # Called when there's incoming data on the websocket for this channel

We then modify the form by adding remote: true to prevent Rails from redirecting after submission.

<!-- app/views/index.html.erb -->
...
  <%= form_for Tweet.new, remote: true do |f|%>
  <% end %>
...

And we inform the controller to broadcast the new tweet html to the TweetChannel in the create action.

# app/controllers/tweets_controller.rb
...
def create
  @tweet = current_user.tweets.create! tweet_params
  ActionCable.server.broadcast "twitter_channel", tweet: render_tweet(@tweet)
  head :ok
end

private
...
def render_tweet tweet
  render(partial: 'tweets/tweet', locals: { tweet: tweet })
end

Now we try again to create a new tweet; the tweet will be immediately appended to the DOM of the tweets index page.

The messaging module

We start now by adding our models and filling them with methods and scopes that we will need in the next steps.

$ rails g model Conversation sender_id:integer:index recipient_id:integer:index
$ rails g model Message body:text conversation_id:integer:index user_id:integer:index

Check the
conversation model and the
message model on Github.

Next we add
conversations controller
and messages controller and we set up our
routes.

We also need to add our view templates and partials for conversations and messages controllers.
Check conversation views
and message views on Github.

The trick in the messages module is that we want to stream and subscribe to message channel based on the conversation id (a conversation is between two users).

We use Rails generator to create a new channel for our messages $ rails g channel Message. This creates two new files app/channels/message_channel.rb and app/assets/javascripts/channels/message.js. The first file handles the connection on the server-side while the other handles the client-side connections.

On the server side, we subscribe to message_channel_#{conversation_id}, so that each connection between any two users will be unique.

# app/channels/message_channel.rb
...
def subscribed
  stream_from "message_channel_#{params[:conversation_id]}"
end
...

On the client side, we will use Coffeescript for its Ruby-like syntax and our convenience. Rename app/assets/javascripts/channels/message.js to message.coffee and add the following code:

# app/assets/javascripts/channels/message.coffee
$ ->
  window.conversation_id = $('#conversation_id').attr('value')

    App.message = App.cable.subscriptions.create { channel: "MessageChannel", conversation_id: conversation_id },

      received: (data) ->
        $('#messages_' + conversation_id).append data['message']
        $('[data-behavior~=new_message_field]').val('')
      # Called when there's incoming data on the websocket for this channel

Here we set a global variable conversation_id whose value is obtained from the
DOM and passed in the params object to the MessageChannel on the server-side.
The received function is called when there is data sent from the server to
the client side. This is where we append the new message to messages_conversation_id
element in the conversations show template.

Here, we find the messages_conversation_id element which we append new messages to.

<!-- app/views/conversations/show.html.erb -->
...
<%= content_tag :div, id: "messages_#{@conversation.id}"  do %>
  <%= render @conversation.messages, conversation: @conversation %>
<% end %>
...

Inside the form, we add a hidden field that holds the current conversation_id
so that the client side of the message channel can send it to the
server-side channel.
Note that we add remote: true to prevent Rails from redirecting after the form submission.

  <!-- app/views/conversations/show.html.erb -->
  ...
  <%= form_for [@conversation, Message.new], remote: true do |f|%>
    <%= f.text_area :body, placeholder: 'New Nessage', 'data-behavior' => 'new_message_field' %>
    <%= f.hidden_field :conversation_id, value: params[:id], id: 'conversation_id' %>
    <%= f.submit 'Send', class: 'button' %>
  <% end %>

The difference in messages controller is that we broadcast our newly created
message to Action Cable server using the conversation_id of that message.

# app/controllers/messages_controller.rb
...
def create
  @message = @conversation.messages.create message_params
  ActionCable.server.broadcast "message_channel_#{@conversation.id}", message: render_message(@message)
end

private

def render_message(message)
  render(partial: 'messages/message', locals: { message: message })
end
...

The online presence module

In this part, we will show the currently logged-in users inside the conversations index page so when we click on any user, we could chat with them directly.
The different part here is that we need Redis to store our logged-in users because, in Action Cable, each page refresh is counted as a new subscription. Thus, each time a user refreshes the web page, a duplicate entry will be created for that user in the online users list.

We will setup Redis by uncommenting redis gem in the Gemfile. And then we will add an initializer file for Redis so we can use it in any part of our application.

# Gemfile
gem 'redis', '~> 3.0'

# config/initializers/redis.rb
$redis = Redis.new(:host => '0.0.0.0', :port => 6379)

We will use Redis sets to store the id of each subscribed user and to remove the ids of unsubscribed users. Then we will rerender the partial responsible for listing the logged-in users.

We start by generating a new channel $ rails g channel OnlineUsers and adding the code responsible for storing or removing user ids from Redis set and rendering the online_users partial.

# app/channels/online_users_channel.rb
class OnlineUsersChannel > ApplicationCable::Channel
  def subscribed
    stream_from "online_users_channel"
    $redis.sadd 'online', current_user.id
    ActionCable.server.broadcast "online_users_channel", users_html: render_online_users
  end

  def unsubscribed
    $redis.srem 'online', current_user.id
    ActionCable.server.broadcast "online_users_channel", users_html: render_online_users
  end

  private

  def render_online_users
    ApplicationController.renderer.render(partial: 'users/online_users')
  end
end

On the client-side part, we use jQuery to set the html() attribute of #onlineUsers element to the html received from the server-side channel that contains the newly rendered online_users partial.

# app/assets/channels/online_users.cofee
App.online_users = App.cable.subscriptions.create "OnlineUsersChannel",
  received: (data) ->
    $('#onlineUsers').html(data['users_html'])

We add _online_users partial under users views. Inside the partial, we loop thought our Redis set online and fetch each user.

Online Users

In conversations index page, we render the partial inside the #onlineUsers element.

  <!-- app/views/conversations/index.html.erb -->
  ...
  <div id="onlineUsers">
    <%= render partial: 'users/online_users'%>
  </div>
  ...

You can check the full source code on Robusta’s Github account.

Conlusion

Action Cable is an easy and simple solution to use. It introduces a fully integrated suite that works well with Ruby on Rails on both client and server sides. To use WebSockets or not is dependent on the use case.

Resources

Real-Time Rails: Implementing WebSockets in Rails 5 with Action Cable
WebSockets, caution required!
http://stackoverflow.com/questions/10028770/in-what-situations-would-ajax-long-short-polling-be-preferred-over-html5-websock

Magento 2 vs Magento 1: A Comparison and Review (Part 2)

magento_logo

In part 1, we started a comparison between Magento 2 and Magento 1 in order to list what’s new in Magento 2, while comparing it to Magento 1 to put things into perspective.

We compared themes and extensions development, frontend development, and admin dashboard.In this sequel, we will explore more into the features, performance, stability, and deployment process.

Features

Magento 2 has all the features included in Magento 1, yet adds upon it many new features like:

  • CSS Preprocessing
  • Better Security
  • PayPal integration enhancements
  • More payment methods based on BrainTree
  • Full-Page Cache (FPC), now available for Community edition as well.
  • Performance, or lackthereof as we will discuss later.

Magento 2 is not an upgrade from Magento 1; it is more of a re-write so while it introduces some new features, more effort is put into Magento’s Core as we inspected earlier, so the lack of impressive new features is justified as long as no features were removed and hopefully with time new features will be added after stabilizing the product.

Performance

Releasing a re-write version of a software without adding new features is justifiable and actually expected for the first couple of releases until bugs are squashed and everything is stabilized.

However, releasing a new version of a software like Magento 2 with clear performance issues, where performance has been/is a crucial cornerstone of the software, is never acceptable and is a clear sign that the maturity of the software is badly affected.

Although the different articles list performance enhancements as a feature of Magento 2, we do realize from the experience of working with both Magento products that this is not true and, most probably, this is all just theoretical speculations.

It takes only seconds after installing Magento 2 to realize the following:

  • Magento 2 is more CPU hungry than Magento 1.
  • Magento 2 requires more housekeeping than Magento 1
  • Running Magento 2 in “developer” mode, which is essential during development phase, means you have to wait minutes between page loads, and you won’t even be able to spend that time doing something else as Magento will make sure to leave no resources whatsoever for your computer to be able to perform other actions in parallel.
  • Magento 2 is slow, like really slow, unbearably slow, not even comparable to Magento 1; we expected Magento 2 to be at least on par with Magento 1; however, this is not true, performance is much worse and pages load much slower and use much more resources.
  • Even in “developer” mode, which should mean that all caching is turned off, Magento 2 still utilizes some caching mechanisms to be able to perform in an acceptable manner. You have to run `setup:static-content:deploy` to deploy static content like assets, and Magento automatically caches “Dependency Injection” in var/di directory, which causes frustrations and slows down development.

These disappointments were confirmed by the various benchmarks published by other developers, as well as comments by the developers on the different forums.

Almost all benchmarks indicated that while Magento 2 uses more CPU resources than Magento 1, it is also twice as slow as Magento 1, meaning that it can serve only half the number of requests that Magento 1 can serve in the same time, all while using more CPU resources.

These benchmarks were confirmed even with caching turned on, so while Magento 2 offers Full-Page Cache (FPC) for both enterprise and community editions (Magento 1 offered FPC only for enterprise edition), and also offers integration with Varnish out-of-the-box, it is still slower even when utilizing the different caching techniques.

A detailed benchmark can be found at https://www.magecore.com/blog/news/magento-ce-1-9-vs-magento-ce-2-0-performance-comparison “Magento CE 1.9 vs Magento CE 2.0 Performance Comparison”, written by “Dima Soroka” who is the former lead Architect of the Magento project and wrote on the official blog for “MageCore” who are certified Magento Partners.

While Magento 2 supports PHP7 which normally reduces processing time by almost 50%, Magento 2 is still slower than Magento 1; however, utilizing PHP7 makes Magento 2 a bit faster and decreases the gap between Magento 2 and Magento 1.

Here is a detailed benchmark by Dima Soroka as well, https://www.magecore.com/blog/news/php-7-affects-performance-magento-1-9-ce-vs-magento-2-0-ce “How Does PHP 7 Affects Performance of Magento 1.9 CE vs. Magento 2.0 CE”

Magento 2 tries to offer better performance by offering the following tools, which while helping a lot it also adds a lot to the complexity:

  • Compiling of PHP files.
  • Merging of global assets
  • Indexing
  • Full-Page Cache
  • Caching of “Dependency Injection”
  • Caching various other items like configurations and layout

We hope that Magento team will focus on optimizing performance so that Magento 2 at least matches the performance of Magento 1 in the near future.

Stability

It is expected that a major software like Magento doesn’t go live unless bugs are squashed and proper testing is conducted; unfortunately, this was not the case in our experience.

A quick visit to Magento 2 code repository on GitHub at https://github.com/magento/magento2 reveals the amount of issues opened. We have also faced many issues ourselves although we have always used the latest stable release of Magento 2.

Some issues were critical, like the issues affecting the cache and the translations, others we have attempted to make temporary fixes for ourselves, but all in all, our developers have always been surprised by the bad quality of the code in areas with bugs.

Have a look at the release notes for the latest version of Magento 2.1 at http://devdocs.magento.com/guides/v2.1/release-notes/ReleaseNotes2.1.0EE.html. Notice the amount of issues fixed and the known issues not fixed yet. This is obviously not an enterprise-edition software.

It is worth-mentioning that upgrading from Magento to version 2.1 was a complete failure for us; we even had to roll back to a backup of version 2.0.7 after 48 hours of downtime and different trials to fix Magento issues ourselves.

One issue was with the default Magento theme, which we built upon a customized theme. Here is an answer from Stack OverFlow pointing out the bug in the theme “Luma”, along with comments by developers who suffer from Magento 2 instability.

image04

Deployment Process

In today’s software development world, deployment should be fully automated; it is no longer accepted to have a person dedicated to deployments, or even downtime caused by deploying a newer version of a software.

Continuous Integration (CI) and Continuous Deployment (CD) aim at decreasing the effort and time required to push new features, enhancements, and fixes by the developers to production servers by automating the process.

Different softwares and frameworks are built with CI and CD in mind; tools and scripts are developed to make sure deployments are safe, automated, and fast.

We have easily established an automated deployment process for Magento 1 on production servers; the process simplified is the following:

  1. Push release to code repository.
  2. Automatically trigger a script on production servers.
  3. Pull the updated files.
  4. Run modman to make sure new files are correctly linked.
  5. Clear the cache.

What’s beautiful about this process is, beside the simplicity, it takes couple of minutes and doesn’t cause downtimes, unless the code itself caused issues which should be detected by CI when running the automated tests.

We tried to devise a similar process for Magento 2, after many iterations we figured out a long process that looks something along the lines of:

  1. Push release to code repository.
  2. Automatically trigger a script on production servers.
  3. Run `composer update` to update the different packages and since we built our extensions as composer packages which will be updated as well and this usually takes a couple of minutes.
  4. Run `setup:upgrade`; this upgrades the extensions and run any install/upgrade scripts that alter the database and/or install new extensions; this usually takes a minute.
  5. Delete some directories from the directory “var”
  6. Run `setup:di:compile`, this generates DI configuration files, which usually takes 5 minutes and can fail and cause a lot of trouble.
  7. Clear everything inside the directory pub/static.
  8. Run `setup:static-content:deploy`, which creates and deploys static content and assets for all themes, and for all locales, usually takes a whopping 20~30 minutes, shouldn’t fail but actually failed miserably when upgrading Magento to version 2.1.
  9. Re-Indexing.
  10. Flushing the cache.

The process is complicated, long and prone to failure. It causes downtime and takes on average 45 minutes.

This is definitely an unacceptable downtime; the process is overly complicated due to different caching and caching-like mechanisms like DI configuration and static-content deployment.

Conclusion

Magento 2 is definitely a great effort towards matching modern PHP frameworks, which we touched upon in different aspects and have always praised during day-to-day development.

However, Magento 2 team has a lot of challenges to tackle if they aim at staying the number 1 e-commerce solution, using and applying modern standards and technologies is an advantage; however, stability and performance are killers if not given proper focus.

At the end, we hope to see practical improvements during the coming months so as to restore our confidence in Magento being our go-to solution for e-commerce platforms which require scaling, performance, and integrations with the different systems.

Magento 2 vs Magento 1: A Comparison and Review (Part 1)

magento_logo

Magento is an open-source e-commerce platform written in PHP. The software was originally developed by Varien Inc., but after witnessing huge successes eBay started investing in Magento by buying shares and eventually acquired Varien.

In late 2015, Magento 2.0 was released, almost completely rewritten using modern programming concepts and technologies, we will be discussing the changes in Magento 2.0 and the new features through comparing it to Magento 1.

Extension & Theme Development

Magento 2 uses modern approaches in how it is built and how developers can build extensions and themes for it.

In Magento 1, themes and extensions’ files were distributed in many locations, we had to use a Module Manager “modman” which allows developers to place the files in 1 folder and then let modman create symlinks “shortcuts” to where Magento expects the files to be placed; this allows for better and easier development and also allows for using Code Version Control systems like “git”.

Magento 2 on the other hand uses modern approach; everything is a Composer package, which allows for better organization, updating, and code maintenance, along with automating some of the scripts and commands that need to be run after any updates.

In our current project with B.TECH, we made use of that fact and based all our work (both extensions and theme) on Composer packages, linked to our code repository to allow for instant code deployment (Continuous Deployment) for both staging and production servers.

This is definitely a step forward towards modern development cycle, and one that puts Magento 2 inline with modern PHP frameworks while opening new opportunities by enabling direct use of any of the thousands of packages available using Composer Packagist.

Frontend Development

Magento 1 uses Prototype JavaScript framework because -believe it or not- jQuery was not production-ready when Magento was in vitro, and it kept depending mainly on Prototype and the framework’s add-ons like Scriptaculous.

This made frontend development for Magento 1 a bit hard, although you can easily inject jQuery, sometimes you just need to stick with Prototype and work with it, which is not a pleasant experience usually.

Magento 2, on the other hand, uses modern approaches; it uses jQuery and Knockout, but more importantly, it uses RequireJS, which makes a webpage load only the required libraries instead of loading everything in all pages.

Magento 1 -and 2- has options for merging JS files, which, while reducing the number of HTTP requests, makes loading a huge JS file required with every page load, This was a valid recommendation in the early days;however, things have changed with HTTP 2.

HTTP 1.1 used to open a new connection for every HTTP request, so merging assets was a must; however, this has changed with HTTP 2 which allows for parallel requests on the same connection. This allows faster assets download and invalidates the recommendation for having less requests per page.

RequireJS is a good candidate for making better use of HTTP 2, as it makes use of HTTP 2 parallel requests per connection, while loading only required libraries per page, a win-win situation.

Our Senior Frontend Developer, Ahmed Alfy, wrote a nice introduction to RequireJS; make sure to check it out here.

Admin Dashboard

Magento 1 had a very clear dashboard; you can easily navigate and access everything; it loads fast and extensions can easily add functionalities to it.

Magento 2 revamped the dashboard completely. It is based on AngularJS, along with RequireJS for loading the assets, which, while sounds like a step towards utilizing modern technologies, raises many flags.

Magento 2’s dashboard is criticized due to the following.

  • It can easily fail to load if any of the assets didn’t load for any reason.
  • It is also much slower, due to having to wait for all the assets to load.
  • While using AngularJS sound promising, it is actually a disadvantage as it makes loading a large number of products or orders -or any relatively long list- very slow, and very CPU demanding, which can even cause the whole browser or computer to freeze for seconds or indefinitely sometimes.
  • It is built on AngularJS version 1, although version 2 is now out of beta.
  • While the overall look of the dashboard is modern and the use of icons and large menus should make it more usable and friendly, this is actually not the case as it is harder to navigate through all the menus and the different menu options and submenus.
  • While it is easy for extensions to add menu items, installing many extensions -which is normal- can easily make the dashboard’s menu much harder to use or not really usable at all.

Here is a quick example showing the steps required to reach the “Cache Management” page, which is a frequently visited page.

Magento 1

image02

 

  1. Hover over the “System” link in the horizontal menu.
  2. Click on “Cache Management” in the vertical submenu.

Magento 2

image03

image00

image01

  1. Look for the “System” menu item in the vertical (sidebar menu).FYI you won’t be able to see it as extensions add menu items that push Magento’s menu items downwards.
  2. Scroll down till the icon for “System” menu item is visible.
  3. Click on it.
  4. Inspect the submenu that slides, you won’t find the “Cache Management” link.
  5. Scroll up till you see the link for “Cache Management”.
  6. Click on it.

This is just an example of how the navigation, while might look seemingly better, is actually confusing and hard.

We have touched upon important aspects of the comparison and saw the advancements in Magento 2 in many areas. While it looks like Magento 2 is a real improvement upon Magento 1, in the second part of this blog post we will see comparison of performance and performance-related changes in Magento 2, we will also discuss the stability of Magento 2, so here is a sneak peak.

image04