Showing posts with label HTML. Show all posts
Showing posts with label HTML. Show all posts

Monday, September 30, 2024

Discover the Top 10 Advantages of Progressive Web Apps for Your Next Project

 

Discover the Top 10 Advantages of Progressive Web Apps for Your Next Project
https://www.nilebits.com/blog/2024/09/progressive-web-apps/

Progressive online Apps, or PWAs, are quickly changing the online development landscape. PWAs are becoming the ideal way to connect mobile applications and traditional websites as companies look for ways to increase efficiency, save expenses, and provide consistent user experiences across all platforms. In-depth code examples are provided to illustrate the characteristics and advantages of Progressive Web Apps, which are explored in this article along with the top 10 reasons to use them for your next project.

1. Cross-Platform Compatibility

Progressive Web Apps' cross-platform interoperability is one of the strongest arguments in favor of using them. Desktop, smartphone, or tablet computers that have an up-to-date web browser can all use PWAs. Without the need for different codebases for the desktop, iOS, and Android environments, this flexibility guarantees that your product reaches a wider audience.

With PWAs, you write the app once using standard web technologies such as HTML, CSS, and JavaScript, and it works seamlessly across devices.

Example: Basic PWA Setup

Here’s how you can create a basic Progressive Web App structure using HTML, JavaScript, and a service worker:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="theme-color" content="#2F3BA2"/>
    <link rel="manifest" href="/manifest.json">
    <title>My First PWA</title>
</head>
<body>
    <h1>Hello, PWA World!</h1>
    <script>
        if ('serviceWorker' in navigator) {
            navigator.serviceWorker.register('/service-worker.js')
                .then(registration => {
                    console.log('Service Worker registered with scope:', registration.scope);
                })
                .catch(error => {
                    console.error('Service Worker registration failed:', error);
                });
        }
    </script>
</body>
</html>

This simple PWA can run across all platforms, leveraging the web’s ubiquity.

2. Improved Performance

Performance is a critical factor for any web-based application. Progressive Web Apps improve load times by caching assets and content using service workers, allowing users to quickly access previously visited pages, even with poor internet connections.

Example: Service Worker for Caching

A service worker is a script that the browser runs in the background, enabling features like caching, push notifications, and background sync. Here’s an example of a service worker that caches static assets:

const CACHE_NAME = 'v1_cache';
const urlsToCache = [
    '/',
    '/styles.css',
    '/script.js',
    '/offline.html'
];

// Install the service worker
self.addEventListener('install', event => {
    event.waitUntil(
        caches.open(CACHE_NAME)
            .then(cache => {
                return cache.addAll(urlsToCache);
            })
    );
});

// Fetch and serve cached assets
self.addEventListener('fetch', event => {
    event.respondWith(
        caches.match(event.request)
            .then(response => {
                return response || fetch(event.request);
            })
            .catch(() => caches.match('/offline.html'))
    );
});

With this setup, the PWA will load instantly for returning users and display a custom offline page when there is no internet connectivity.

3. Offline Functionality

PWAs offer offline functionality, ensuring users can continue interacting with the app when they have no internet access. By caching essential resources using service workers, the app can serve previously loaded content and even queue actions for later synchronization.

Example: Offline Handling with Service Worker

Let’s extend our service worker to handle offline scenarios effectively:

self.addEventListener('fetch', event => {
    event.respondWith(
        fetch(event.request)
            .catch(() => {
                return caches.match(event.request).then(response => {
                    return response || caches.match('/offline.html');
                });
            })
    );
});

This code ensures that if a user loses connectivity, they can still access the cached version of the app or an offline page.

4. Better User Engagement with Push Notifications

PWAs allow developers to engage users through push notifications, even when the app is not actively running in the foreground. Push notifications help keep users informed about updates, reminders, and other interactions that can boost engagement.

Example: Push Notifications

First, we need to ask for permission from the user to send notifications:

Notification.requestPermission().then(permission => {
    if (permission === 'granted') {
        navigator.serviceWorker.getRegistration().then(registration => {
            registration.showNotification('Hello, PWA User!', {
                body: 'Thanks for using our Progressive Web App.',
                icon: '/images/icon.png'
            });
        });
    }
});

This code will display a notification to the user if they grant permission. Push notifications make your PWA more engaging by reminding users to revisit the app.

5. Reduced Development Costs

Developing separate native apps for iOS, Android, and web platforms is expensive. PWAs solve this by using a single codebase across all platforms. By building one Progressive Web App, you can drastically reduce the development time and costs associated with maintaining multiple apps.

Example: Unified Codebase

// This single piece of code works on both mobile and desktop environments
function detectDevice() {
    if (window.innerWidth < 768) {
        return 'Mobile';
    } else {
        return 'Desktop';
    }
}

console.log(`You are using a ${detectDevice()} device`);

With such cross-platform compatibility, businesses can save on development and maintenance costs while ensuring a consistent user experience.

6. Increased Security

Since PWAs are served via HTTPS, they inherently ensure that all communications between the user and the server are encrypted, preventing man-in-the-middle attacks. Additionally, the use of service workers ensures that only the content that is cached is displayed to users, preventing malicious injections.

Example: Enforcing HTTPS

Make sure your web server enforces HTTPS:

# Redirect all HTTP traffic to HTTPS
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

This simple configuration makes sure that any non-secure HTTP requests are redirected to HTTPS, increasing security for your Progressive Web App.

7. Discoverability Through Search Engines

Unlike native apps, which are primarily distributed through app stores, PWAs are discoverable through search engines like regular websites. This makes them easily accessible to users and allows businesses to take advantage of SEO techniques to increase visibility.

Example: SEO Optimization in PWA

Use meta tags and structured data to optimize your PWA for search engines:

<meta name="description" content="Learn why Progressive Web Apps are the future of web development.">
<link rel="canonical" href="https://www.yourdomain.com/progressive-web-apps">
<meta name="robots" content="index, follow">

By optimizing your PWA for SEO, you improve its chances of being found by users searching for relevant topics.

8. Native App-Like Experience

PWAs provide a native app-like experience by offering features such as offline access, home screen installation, push notifications, and a responsive design. This provides users with the benefits of a native app without requiring a download from an app store.

Example: Adding PWA to Home Screen

Here’s how you can allow users to add your PWA to their home screen on mobile devices:

let deferredPrompt;
window.addEventListener('beforeinstallprompt', event => {
    // Prevent the mini-infobar from appearing on mobile
    event.preventDefault();
    deferredPrompt = event;
    // Display your custom install button
    document.getElementById('install-button').style.display = 'block';

    document.getElementById('install-button').addEventListener('click', () => {
        deferredPrompt.prompt();
        deferredPrompt.userChoice.then(choiceResult => {
            if (choiceResult.outcome === 'accepted') {
                console.log('User accepted the PWA installation');
            } else {
                console.log('User dismissed the PWA installation');
            }
            deferredPrompt = null;
        });
    });
});

With this code, users can add the app to their home screen, giving it the appearance and feel of a native app.

9. Automatic Updates

Progressive Web Apps update automatically in the background, ensuring that users always have the latest version. There’s no need for users to manually download updates, as PWAs automatically fetch the latest files when they become available.

Example: Force Update in PWA

You can force an update for users when a new version of your service worker is available:

self.addEventListener('install', event => {
    event.waitUntil(
        caches.open(CACHE_NAME).then(cache => {
            return cache.addAll(urlsToCache);
        }).then(() => {
            self.skipWaiting();
        })
    );
});

self.addEventListener('activate', event => {
    event.waitUntil(
        caches.keys().then(cacheNames => {
            return Promise.all(
                cacheNames.map(cache => {
                    if (cache !== CACHE_NAME) {
                        return caches.delete(cache);
                    }
                })
            );
        })
    );
});

This ensures that users get the latest version of your PWA without needing to take any manual action.

10. Reduced Data Consumption

Compared to traditional websites or native apps, PWAs consume far less data, which is especially important for users in areas with limited or expensive data plans. By caching content locally, PWAs minimize data usage and reduce the load on servers.

Example: Minimal Data Consumption

with Lazy Loading

Implementing lazy loading allows your PWA to load images and content only when they are needed, reducing data usage:

<img src="placeholder.jpg" data-src="actual-image.jpg" class="lazy">
document.addEventListener('DOMContentLoaded', function() {
    let lazyImages = [].slice.call(document.querySelectorAll('img.lazy'));

    if ('IntersectionObserver' in window) {
        let lazyImageObserver = new IntersectionObserver(function(entries, observer) {
            entries.forEach(function(entry) {
                if (entry.isIntersecting) {
                    let lazyImage = entry.target;
                    lazyImage.src = lazyImage.dataset.src;
                    lazyImage.classList.remove('lazy');
                    lazyImageObserver.unobserve(lazyImage);
                }
            });
        });

        lazyImages.forEach(function(lazyImage) {
            lazyImageObserver.observe(lazyImage);
        });
    }
});

This reduces bandwidth by loading content only when it is needed, improving both performance and user experience.

Conclusion

Progressive Web Apps (PWAs) are the future of web development, offering cross-platform compatibility, offline functionality, enhanced performance, and better user engagement. Whether you’re looking to reduce development costs, improve security, or offer users a native app-like experience, PWAs are an excellent choice for your next project.

With features like automatic updates, push notifications, and offline capabilities, PWAs provide a seamless and efficient user experience across all devices. As businesses continue to explore ways to improve their digital presence, the adoption of Progressive Web Apps is bound to rise.

References:

  1. Google Developers - Introduction to Progressive Web Apps
  2. Mozilla Developer Network - Service Workers
  3. W3C - Web App Manifest

https://www.nilebits.com/blog/2024/09/progressive-web-apps/

Sunday, September 22, 2024

Deploying Your First React App to Production

 

Deploying Your First React App to Production

https://www.nilebits.com/blog/2024/09/deploying-react-app-to-production/

Putting your first React application live might be intimidating, particularly if you've never done it before. That being said, any developer creating contemporary web apps has to have this ability. With thorough instructions and a ton of code samples, we'll go over everything you should know in this tutorial to launch a React project. Additionally, we'll guide you through several deployment techniques utilizing platforms like Vercel, Netlify, GitHub Pages, and more.

What Is React?

Before moving on to deployment, let's talk a little bit about React. A well-liked JavaScript package called React is used to create user interfaces, especially for single-page applications (SPAs). Facebook developed it, allowing programmers to create expansive apps where data is updated without requiring a page reload. The component-based approach, which is the main focus of React, enables you to construct reusable user interface components that independently maintain state.

Preparing Your React App for Production

1. Setting Up Your React Project

If you haven't created a React project yet, you can use the create-react-app command to get started quickly. Here’s how you can set up a new React project:

npx create-react-app my-react-app
cd my-react-app
npm start

Once you run npm start, your application will be running in development mode. Before deploying to production, you'll want to ensure that your app is production-ready.

2. Optimizing Your React App for Production

By default, React provides several optimizations when building for production. These include minification of JavaScript, optimized asset loading, and improved performance. You can build your app for production by running:

npm run build

This command creates an optimized build in the build/ folder. It includes:

  • HTML, CSS, and JavaScript files optimized for performance.
  • Static assets like images and fonts.
  • Minified code to reduce the size of the application.
  • Source maps to help debug issues in production.

Deploying React App on GitHub Pages

GitHub Pages is an easy and free option to host static websites. Since React apps are typically SPAs, you can deploy them on GitHub Pages. Here’s how to deploy a React app on GitHub Pages:

1. Install the gh-pages Package

First, install the gh-pages package as a development dependency:

npm install gh-pages --save-dev

2. Update package.json

In your package.json, add the following configurations:

{
  "homepage": "https://<your-username>.github.io/<your-repo-name>",
  "scripts": {
    "predeploy": "npm run build",
    "deploy": "gh-pages -d build"
  }
}

Replace <your-username> and <your-repo-name> with your GitHub username and repository name.

3. Deploy the App

Push your code to the repository, and then run the following command to deploy your app:

npm run deploy

GitHub Pages will now host your React app at https://<your-username>.github.io/<your-repo-name>.

Deploying React App on Netlify

Netlify is another popular platform for deploying React applications. It simplifies the deployment process and offers features like automatic build, continuous deployment, and custom domain support. Here’s how to deploy a React app on Netlify:

1. Build Your React App

Run the following command to build the app for production:

npm run build

2. Deploy the App via Netlify Dashboard

  1. Go to Netlify and sign up for an account.
  2. Click New Site from Git and choose your repository.
  3. Configure the build settings. For React apps, use the following build command and publish directory:
  • Build command: npm run build
  • Publish directory: build/
  1. Click Deploy and let Netlify do the work.

3. Continuous Deployment

Netlify automatically redeploys your app whenever you push changes to your GitHub repository. This makes it easy to keep your production app up to date.

Deploying React App on Vercel

Vercel is another great platform for deploying React apps. It’s optimized for performance and offers a seamless integration with GitHub.

1. Build Your React App

Like other platforms, you need to build the app first:

npm run build

2. Deploying with Vercel CLI

You can use the Vercel CLI for quick deployments. First, install the Vercel CLI globally:

npm install -g vercel

Next, run the following command to deploy your app:

vercel

Vercel will prompt you to configure your deployment, after which it will deploy your app to a custom URL.

Deploying React App on Heroku

Heroku is a cloud platform that supports server-side applications. If you need to deploy a full-stack React app with a backend, Heroku is a great option.

1. Install the Heroku CLI

First, install the Heroku CLI:

curl https://cli-assets.heroku.com/install.sh | sh

2. Create a Heroku App

Log in to Heroku and create a new app:

heroku login
heroku create

3. Deploy Your React App

Initialize a Git repository if you haven't done so:

git init

Then, commit your code:

git add .
git commit -m "First commit"

Deploy your app to Heroku:

git push heroku master

Your React app is now live on Heroku.

Handling Routing in React for Production

When deploying React apps with client-side routing (e.g., using react-router), you might encounter issues where refreshing a page gives a 404 error. This happens because static hosts like GitHub Pages, Netlify, and Vercel don't handle routing on the client side.

To fix this issue, you can add a redirect rule:

For Netlify

Create a _redirects file in your public/ folder with the following content:

/*    /index.html   200

This tells Netlify to redirect all traffic to index.html, allowing react-router to handle routing.

For Vercel

Vercel automatically handles client-side routing, so no extra configuration is required.

Optimizing React App Performance for Production

Once your app is deployed, you’ll want to ensure it performs optimally. Here are some best practices to follow:

1. Code Splitting

Code splitting allows you to break your code into smaller bundles that can be loaded on demand. This reduces the initial load time. React makes it easy to implement code splitting using React.lazy() and Suspense:

const MyComponent = React.lazy(() => import('./MyComponent'));

function App() {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <MyComponent />
    </Suspense>
  );
}

2. Lazy Loading Images

You can lazy load images to improve performance by using the loading attribute:

<img src="image.jpg" loading="lazy" alt="Lazy loaded image" />

3. Minify CSS and JavaScript

React’s build process automatically minifies your CSS and JavaScript. However, you can further optimize your stylesheets and scripts using tools like cssnano and terser.

4. Use a CDN

Deploy your static assets (e.g., images, fonts) to a content delivery network (CDN) to reduce latency and improve load times.

Common Deployment Pitfalls and How to Avoid Them

1. Forgetting to Build for Production

Always run npm run build before deploying your React app. The build process optimizes your app for production and ensures better performance.

2. Issues with Environment Variables

When deploying, make sure your environment variables are correctly set. You can define environment variables in a .env file in the root of your project:

REACT_APP_API_URL=https://api.example.com

3. Routing Issues

If you’re using react-router, make sure your host supports client-side routing or implement redirect rules as mentioned earlier.

Conclusion

Congratulations! You’ve now learned how to deploy your first React app to production using various platforms, including GitHub Pages, Netlify, Vercel, and Heroku. By following the steps outlined in this guide, you can confidently deploy your React applications to production environments and ensure they perform optimally.

References

Deploying a React app might seem challenging at first, but with practice, it becomes straightforward. Follow best practices, avoid common pitfalls, and leverage the right tools to make your deployment process smoother.

https://www.nilebits.com/blog/2024/09/deploying-react-app-to-production/

Monday, September 16, 2024

Top 10 Advanced JavaScript Performance Optimization Techniques and Patterns

 

Top 10 Advanced JavaScript Performance Optimization Techniques and Patterns

https://www.nilebits.com/blog/2024/09/10-javascript-performance-techniques/

In the world of web development today, user experience is mostly determined by performance. A sluggish website or application may cause bounce rates to rise, user annoyance, and harm to search engine results. Adopting sophisticated optimization strategies and patterns is necessary to ensure optimal performance for applications relying on JavaScript. Ten sophisticated JavaScript speed optimization strategies and patterns that might aid developers in writing quicker and more effective code are covered in this article. Examples are provided for each strategy to show how successful it is in actual situations.

Introduction

The foundation of contemporary online apps is JavaScript. JavaScript is a strong script, but when used carelessly, its versatility may lead to inefficiencies. JavaScript optimization becomes crucial for keeping responsive and quick applications as online programs get more complicated. This post goes over advanced methods that can boost your JavaScript efficiency and allow you to decrease runtime, utilize less memory, and provide consumers a smoother experience.


1. Minimize DOM Access and Manipulation

Accessing and manipulating the DOM is one of the most expensive operations in JavaScript. Every time you interact with the DOM, the browser must recalculate layouts, repaint the page, and potentially re-render elements. To improve performance, it’s essential to minimize the number of DOM access operations and batch them whenever possible.

Why DOM Access Is Expensive

  • Layout Thrashing: When you repeatedly access the DOM and modify it in rapid succession, you trigger layout recalculations that can significantly slow down your application.
  • Reflows and Repaints: DOM manipulations cause the browser to reflow (calculate the layout again) and repaint (render the UI elements), which takes time and resources.

Optimization Techniques

  • Batch DOM Updates: Instead of updating the DOM element-by-element, batch multiple changes at once using techniques such as document fragments.
  • Virtual DOM: Frameworks like React introduce the concept of the virtual DOM to minimize direct DOM manipulation by keeping an in-memory representation.

Code Example:

// Inefficient DOM manipulation
for (let i = 0; i < items.length; i++) {
  const element = document.createElement('div');
  element.innerText = items[i];
  document.body.appendChild(element);
}

// Efficient DOM manipulation (using DocumentFragment)
const fragment = document.createDocumentFragment();
items.forEach(item => {
  const element = document.createElement('div');
  element.innerText = item;
  fragment.appendChild(element);
});
document.body.appendChild(fragment);

By using document fragments or tools like the virtual DOM, you can minimize the number of times the browser needs to reflow and repaint, improving overall performance.

Reference:


2. Use Efficient Loops and Iterators

Loops are fundamental to JavaScript, but not all loops are created equal. Choosing the right loop structure can have a significant impact on performance, especially when dealing with large data sets.

Best Practices for Loops

  • Use Modern Iterators: Instead of using traditional for or while loops, prefer modern methods like forEach(), map(), filter(), and reduce(). These methods are optimized internally and lead to cleaner code.
  • Avoid Unnecessary Looping: If you find yourself looping over data multiple times, consider refactoring to reduce the number of passes over the data.

Code Example:

// Traditional for loop
let sum = 0;
for (let i = 0; i < numbers.length; i++) {
  sum += numbers[i];
}

// Optimized reduce method
const sum = numbers.reduce((acc, num) => acc + num, 0);

In the example above, the reduce method not only simplifies the code but also performs better in many scenarios by reducing the number of iterations.


3. Debounce and Throttle Expensive Operations

Event listeners (like resize, scroll, or keyup) can fire events rapidly, leading to performance bottlenecks if you perform expensive computations or DOM manipulations in response to every event. Debouncing and throttling are two common strategies to limit the number of times a function is called within a specific time frame.

Debouncing

Debouncing ensures that the function is called after a certain delay following the last event trigger.

Code Example:

function debounce(func, delay) {
  let debounceTimer;
  return function(...args) {
    clearTimeout(debounceTimer);
    debounceTimer = setTimeout(() => func.apply(this, args), delay);
  };
}

window.addEventListener('resize', debounce(() => {
  console.log('Resized');
}, 300));

Throttling

Throttling ensures that the function is called at most once within a specified time frame.


4. Avoid Memory Leaks and Optimize Garbage Collection

Memory leaks in JavaScript occur when objects are no longer needed but continue to be retained in memory. This not only increases memory usage but also slows down garbage collection, causing performance degradation over time. Proper memory management is key to keeping JavaScript performant.

Common Sources of Memory Leaks:

  • Uncleared event listeners: Event listeners attached to elements that are later removed.
  • Closures: When a function holds references to variables long after the outer function has returned.
  • Circular references: Objects referencing each other in a way that prevents garbage collection.

Code Example (Memory Leak):

// Example of memory leak with closures
function createClosure() {
  const largeArray = new Array(1000000); // Takes up a lot of memory
  return function() {
    console.log(largeArray.length); // Still holds onto largeArray
  };
}

const leak = createClosure();

To avoid memory leaks, clear event listeners when no longer needed, avoid holding onto references unnecessarily, and be mindful of how closures are used.


5. Lazy Loading JavaScript and Assets

Lazy loading defers the loading of non-critical resources until they are needed, improving initial load time and overall performance. This is especially useful for large JavaScript bundles, images, and other assets.

Techniques for Lazy Loading:

  • Dynamic Imports: Use dynamic imports to load JavaScript code only when it's needed. This reduces the initial bundle size and speeds up the loading process.
  • Code Splitting: Tools like Webpack support code splitting, which allows you to break up your JavaScript code into smaller chunks.

Code Example (Dynamic Import):

// Lazy load a module only when needed
import('./module').then(module => {
  module.default();
});

6. Use Web Workers for Heavy Computation

JavaScript is single-threaded by default, meaning that long-running tasks can block the main thread and cause the UI to become unresponsive. Web Workers allow you to offload heavy computation to a separate thread, improving performance and keeping the UI responsive.

Code Example:

// Main thread
const worker = new Worker('worker.js');
worker.postMessage('Start computation');

// Worker thread (worker.js)
self.onmessage = function() {
  // Perform heavy computation here
  let result = computeIntensiveTask();
  self.postMessage(result);
};

By offloading intensive tasks to a Web Worker, you can keep the main thread free for handling user interactions, leading to a smoother user experience.

Reference:


7. Optimize and Cache API Requests

Frequent or unnecessary API calls can slow down your application and increase load times. Caching API responses and avoiding redundant network requests can help optimize performance, especially in Single Page Applications (SPAs).

Code Example:

const cache = new Map();

async function fetchData(url) {
  if (cache.has(url)) {
    return cache.get(url);
  }

  const response = await fetch(url);
  const data = await response.json();
  cache.set(url, data);
  return data;
}

In this example, we use a simple caching mechanism to store API responses and reuse them when the same request is made again.


8. Efficient Use of Closures

Closures are powerful in JavaScript but can easily lead to performance issues if misused. Closures retain references to their outer scope, which can create memory overhead when not managed carefully.

Code Example:

// Potential memory overhead with closures
function outer() {
  const largeArray = new Array(1000000);
  return function inner() {
    return largeArray.length;
  };
}

While closures are useful for encapsulation and scoping, it’s important to be cautious of retaining unnecessary references that could lead to memory bloat.


9. Optimize Rendering with RequestAnimationFrame

When building animations or handling frequent UI updates, requestAnimationFrame is a more efficient alternative to setTimeout or setInterval. It helps ensure that updates are synchronized with the browser's refresh rate, leading to smoother animations and better performance.

Code Example:

let lastKnownScrollPosition = 0;
let ticking = false;

function doSomething(scrollPos) {
  console.log(scrollPos);
}

window.addEventListener('scroll', function() {
  lastKnownScrollPosition = window.scrollY;

  if (!ticking) {
    window.requestAnimationFrame(function() {
      doSomething(lastKnownScrollPosition);
      ticking = false;
    });

    ticking = true;
  }
});

Using requestAnimationFrame ensures that the browser handles updates at the optimal time, improving performance for tasks like scrolling and animations.


10. Use Immutable Data Structures

Immutable data structures ensure that data is not mutated directly but instead returns a new object whenever a change is made. This can lead to performance benefits by avoiding unexpected side effects and allowing for more efficient change detection in libraries like React.

Code Example:

// Mutating object
const obj = { name: 'John', age: 30 };
obj.age = 31; // Mutates the original object

// Using an immutable pattern
const newObj = { ...obj, age: 31 }; // Creates a new object instead of mutating

Immutable patterns allow for more predictable and efficient state management, which can help in applications with complex data flows.


Conclusion

JavaScript performance optimization is an ongoing process that requires careful consideration of how code is structured and executed. By following these 10 advanced techniques and patterns, you can ensure that your JavaScript applications are as efficient and responsive as possible. From minimizing DOM manipulations to leveraging Web Workers, each technique plays a crucial role in improving performance and delivering a smooth user experience.


This article provides an extensive guide to advanced JavaScript performance techniques, including real-world examples that developers can adopt for optimizing their applications. Let me know if you'd like any further modifications!

https://www.nilebits.com/blog/2024/09/10-javascript-performance-techniques/

Thursday, August 8, 2024

Boosting Your Next.js App with SEO: Implementing Static & Dynamic Metadata

 

Boosting Your Next.js App with SEO: Implementing Static & Dynamic Metadata

https://www.nilebits.com/blog/2024/08/boosting-your-nextjs-app-with-seo/

It is imperative that your Next.js application is search engine optimized in the cutthroat online environment of today. Though Next.js provides powerful server-side rendering and static site creation tools, the real strength is in how you use and maintain both static and dynamic information to improve your app's search engine ranking. With the help of this thorough tutorial, you will be able to optimize your Next.js application and increase its search engine ranking and reach by using both static and dynamic information.

Understanding Metadata in Next.js

Understanding what metadata is and why it's important for SEO is necessary before delving into the code. Search engines index and rank your web pages based on metadata, which includes things like the title, description, and keywords. The visibility of your website can be considerably increased with well-managed metadata.

Setting Up a Next.js Project

Let's start by creating a new Next.js project. If you haven't already set up Next.js, follow these steps to get started:

npx create-next-app my-seo-app
cd my-seo-app
npm run dev

This will create a basic Next.js application that we will use to implement SEO best practices.

Implementing Static Metadata

Static metadata is content that doesn't change and is set at the build time. In Next.js , static metadata can be implemented using the <Head> component. Here's an example of how to add static metadata to a page:

import Head from 'next/head';

export default function Home() {
  return (
    <>
      <Head>
        <title>My SEO-Optimized Next.js App</title>
        <meta name="description" content="This is a sample application optimized for SEO using Next.js." />
        <meta name="keywords" content="Next.js, SEO, Static Metadata" />
        <meta name="robots" content="index, follow" />
      </Head>
      <h1>Welcome to My SEO-Optimized Next.js App</h1>
      <p>This is the homepage of your SEO-friendly Next.js application.</p>
    </>
  );
}

Implementing Dynamic Metadata

Dynamic metadata, on the other hand, changes based on the content or user interaction. This is particularly useful for pages like blogs or product listings, where each page might have different metadata. Next.js makes it easy to generate dynamic metadata by fetching data during the server-side rendering process.

Here’s how you can implement dynamic metadata in a Next.js app:

import Head from 'next/head';

export async function getServerSideProps(context) {
  const { slug } = context.params;
  const res = await fetch(`https://api.example.com/posts/${slug}`);
  const post = await res.json();

  return {
    props: {
      post,
    },
  };
}

export default function BlogPost({ post }) {
  return (
    <>
      <Head>
        <title>{post.title} - My Blog</title>
        <meta name="description" content={post.excerpt} />
        <meta name="keywords" content={post.keywords.join(', ')} />
        <meta name="robots" content="index, follow" />
      </Head>
      <h1>{post.title}</h1>
      <p>{post.content}</p>
    </>
  );
}

Combining Static and Dynamic Metadata

In many cases, you might want to combine both static and dynamic metadata. For instance, you could have a static base title for your site but dynamically generate other metadata based on the content. Here's an example:

import Head from 'next/head';

export async function getStaticProps() {
  const res = await fetch('https://api.example.com/homepage');
  const data = await res.json();

  return {
    props: {
      data,
    },
  };
}

export default function Home({ data }) {
  return (
    <>
      <Head>
        <title>{data.title} - My SEO-Optimized Next.js App</title>
        <meta name="description" content={data.description} />
        <meta name="keywords" content={data.keywords.join(', ')} />
      </Head>
      <h1>{data.title}</h1>
      <p>{data.content}</p>
    </>
  );
}

Advanced SEO Techniques with Next.js

Beyond basic metadata management, Next.js offers advanced features to enhance your SEO strategy. Here are a few techniques:

  1. Canonical Tags: Prevent duplicate content issues by specifying canonical URLs for your pages.
<Head>
  <link rel="canonical" href="https://example.com/your-page" />
</Head>
  1. Open Graph and Twitter Cards: Improve social media sharing by adding Open Graph and Twitter Card metadata.
<Head>
  <meta property="og:title" content="My SEO-Optimized Next.js App" />
  <meta property="og:description" content="This is a sample application optimized for SEO using Next.js." />
  <meta property="og:image" content="https://example.com/og-image.jpg" />
  <meta property="og:url" content="https://example.com" />
  <meta name="twitter:card" content="summary_large_image" />
</Head>
  1. Structured Data: Implement JSON-LD structured data to help search engines better understand your content.
<Head>
  <script type="application/ld+json">
    {`
      {
        "@context": "https://schema.org",
        "@type": "WebSite",
        "url": "https://example.com",
        "name": "My SEO-Optimized Next.js App",
        "potentialAction": {
          "@type": "SearchAction",
          "target": "https://example.com/search?q={search_term_string}",
          "query-input": "required name=search_term_string"
        }
      }
    `}
  </script>
</Head>

Optimizing Performance for SEO

Performance is a critical factor in SEO. Search engines like Google prioritize fast-loading websites, and Next.js provides several features to enhance performance:

  • Image Optimization: Use the next/image component for optimized image loading.
  • Code Splitting: Next.js automatically splits your code, loading only what’s necessary.
  • Static Site Generation (SSG): Where possible, use SSG to serve pre-rendered pages for faster load times.
import Image from 'next/image';

export default function Home() {
  return (
    <>
      <Head>
        <title>Optimized Images in Next.js</title>
      </Head>
      <h1>Optimized Images</h1>
      <Image
        src="/images/sample.jpg"
        alt="Sample Image"
        width={500}
        height={500}
      />
    </>
  );
}

Conclusion

Implementing SEO in your Next.js app is not just about adding meta tags. It involves a holistic approach, combining static and dynamic metadata, optimizing performance, and leveraging advanced features like structured data and Open Graph. By following this guide, you’ll be well on your way to ensuring your Next.js application is not only fast and functional but also ranks well on search engines.

References:



https://www.nilebits.com/blog/2024/08/boosting-your-nextjs-app-with-seo/

Wednesday, August 7, 2024

Robots and CAPTCHA: Why AI Can’t Click ‘I’m Not a Robot’ on Websites

 

Robots and CAPTCHA: Why AI Can’t Click ‘I’m Not a Robot’ on Websites

https://www.nilebits.com/blog/2024/08/robots-and-captcha-why-ai-can-not-click-i-am-not-a-robot-on-websites/

The proliferation of automated systems and bots across the internet has necessitated the development of robust mechanisms to distinguish between human users and non-human agents. CAPTCHA (Completely Automated Public Turing test to tell Computers and Humans Apart) stands as one of the most effective tools in this regard. This blog post delves into the intricacies of CAPTCHA, exploring why robots can't click the 'I’m Not a Robot' box on websites, with a focus on the underlying technologies, their evolution, and the challenges they pose for AI and automation.

Understanding CAPTCHA: The Basics

The early 2000s saw the introduction of CAPTCHA, which has since undergone substantial change. Tests that are simple for people to pass but difficult for automated systems to do so is its main objective. Sorting through distorted text or recognizing items in pictures were common tasks for traditional CAPTCHAs. The 'I'm Not a Robot' checkbox and other more complex alternatives were developed as a result of these techniques losing their effectiveness as AI technology developed.

The 'I’m Not a Robot' CAPTCHA

The 'I’m Not a Robot' CAPTCHA, also known as reCAPTCHA, introduced by Google, relies on advanced risk analysis engines and machine learning to distinguish between human and automated interactions. This method goes beyond simple visual challenges by analyzing user behavior, such as mouse movements, clicks, and keystrokes, to determine if the user is human.

Why AI Struggles with 'I’m Not a Robot' CAPTCHA

  1. Behavioral Analysis: The 'I’m Not a Robot' CAPTCHA evaluates the user's behavior, including mouse movements, the time taken to complete actions, and the overall interaction pattern with the page. AI bots, despite their sophistication, often lack the nuanced and random behavior exhibited by humans, making them easier to detect.
  2. Machine Learning Algorithms: Google's reCAPTCHA uses machine learning algorithms trained on vast datasets of human interactions. These algorithms are adept at identifying subtle differences between human and bot behavior, which can be challenging for AI to mimic accurately.
  3. Constant Evolution: CAPTCHA technologies are continuously updated to counteract advancements in AI and automation. This dynamic nature means that even as bots become more sophisticated, CAPTCHAs are regularly enhanced to stay one step ahead.

Exploring CAPTCHA Implementations

Let’s dive into some code examples to understand how CAPTCHA is implemented and why it poses challenges for bots.

Example 1: Integrating reCAPTCHA with a Web Form

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>reCAPTCHA Example</title>
    <script src="https://www.google.com/recaptcha/api.js" async defer></script>
</head>
<body>
    <form action="submit_form.php" method="POST">
        <div class="g-recaptcha" data-sitekey="your_site_key"></div>
        <input type="submit" value="Submit">
    </form>
</body>
</html>

In this example, the g-recaptcha div embeds the reCAPTCHA widget into the form. The data-sitekey attribute contains the public site key provided by Google, which is necessary for the widget to function.

Example 2: Server-Side Verification

Once the user submits the form, the server needs to verify the CAPTCHA response. Here’s an example in PHP:

<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $recaptchaSecret = 'your_secret_key';
    $recaptchaResponse = $_POST['g-recaptcha-response'];

    $response = file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=$recaptchaSecret&response=$recaptchaResponse");
    $responseKeys = json_decode($response, true);

    if (intval($responseKeys["success"]) !== 1) {
        echo 'Please complete the CAPTCHA';
    } else {
        echo 'CAPTCHA verification successful';
        // Process the form submission
    }
}
?>

In this script, the server sends the CAPTCHA response to Google’s reCAPTCHA API for verification. The API returns a JSON object indicating whether the CAPTCHA validation was successful.

Advanced CAPTCHA Mechanisms

While reCAPTCHA is widely used, other CAPTCHA mechanisms also play a significant role in preventing bot activity.

NoCAPTCHA reCAPTCHA

Google’s NoCAPTCHA reCAPTCHA is an evolution that further simplifies the process for users while maintaining security. Users often only need to click a checkbox, with additional challenges presented only if the system detects suspicious behavior.

Invisible reCAPTCHA

Invisible reCAPTCHA operates without user interaction unless deemed necessary. It runs in the background and leverages advanced risk analysis to validate users, presenting challenges only when suspicious activity is detected.

Challenges and Limitations of CAPTCHA

Despite its effectiveness, CAPTCHA is not without limitations. Users often find CAPTCHA tests annoying or difficult, leading to potential user experience issues. Additionally, as AI continues to advance, there is an ongoing arms race between CAPTCHA developers and bot creators.

The Role of AI in Solving CAPTCHAs

AI-based solutions have made great progress in resolving classic CAPTCHA problems, especially in the areas of machine learning and computer vision. AI may be trained, for example, to accurately identify objects in photos or detect distorted language. Modern CAPTCHAs' behavioral analysis feature is still a strong protection, though.

Future of CAPTCHA

The future of CAPTCHA will likely see further integration of behavioral analysis and biometric data, making it even harder for bots to mimic human behavior. Additionally, advancements in AI and machine learning will continue to shape the evolution of CAPTCHA technologies.

Conclusion

CAPTCHA remains a critical tool in the fight against automated bots and malicious activities online. While AI has made significant progress in bypassing traditional CAPTCHA challenges, modern CAPTCHA systems like reCAPTCHA leverage advanced behavioral analysis and machine learning to stay ahead. As the digital landscape continues to evolve, CAPTCHA technologies will adapt to ensure the security and integrity of online interactions.

For more information on CAPTCHA and its implementations, you can refer to the following resources:

By understanding the complexities of CAPTCHA and the reasons behind its effectiveness, developers can better implement these systems to protect their websites from malicious activities while ensuring a seamless user experience for legitimate users.


https://www.nilebits.com/blog/2024/08/robots-and-captcha-why-ai-can-not-click-i-am-not-a-robot-on-websites/

Tuesday, August 6, 2024

10 Amazing Things You Can Do With Simple JavaScript

 

10 Amazing Things You Can Do With Simple JavaScript

https://www.nilebits.com/blog/2024/08/10-things-you-can-do-with-javascript/

JavaScript is a fairly flexible language that can be used to create everything from straightforward server-side systems to intricate online apps. Both inexperienced and seasoned developers love it for its versatility and simplicity of usage. This post will go over 10 incredible things you can do with basic JavaScript, along with code snippets and resources to help you learn more.

1. Create Interactive Web Pages

JavaScript is essential for adding interactivity to web pages. You can create dynamic content, handle user events, and update the DOM without reloading the page.

Example: Toggle Dark Mode

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Dark Mode Toggle</title>
    <style>
        body {
            transition: background-color 0.3s, color 0.3s;
        }
        .dark-mode {
            background-color: #121212;
            color: #ffffff;
        }
    </style>
</head>
<body>
    <h1>Welcome to My Website</h1>
    <button id="toggle-dark-mode">Toggle Dark Mode</button>
    <script>
        const button = document.getElementById('toggle-dark-mode');
        button.addEventListener('click', () => {
            document.body.classList.toggle('dark-mode');
        });
    </script>
</body>
</html>

References:

2. Build Simple Games

JavaScript can be used to create engaging games directly in the browser. With the HTML5 canvas element, you can draw graphics and animate objects.

Example: Basic Snake Game

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Snake Game</title>
    <style>
        canvas {
            display: block;
            margin: auto;
            background-color: #f0f0f0;
        }
    </style>
</head>
<body>
    <canvas id="gameCanvas" width="400" height="400"></canvas>
    <script>
        const canvas = document.getElementById('gameCanvas');
        const ctx = canvas.getContext('2d');
        const grid = 20;
        let snake = [{ x: 160, y: 160 }];
        let direction = 'right';
        let food = { x: 200, y: 200 };

        function update() {
            const head = { ...snake[0] };
            switch (direction) {
                case 'up': head.y -= grid; break;
                case 'down': head.y += grid; break;
                case 'left': head.x -= grid; break;
                case 'right': head.x += grid; break;
            }
            snake.unshift(head);
            if (head.x === food.x && head.y === food.y) {
                food.x = Math.floor(Math.random() * canvas.width / grid) * grid;
                food.y = Math.floor(Math.random() * canvas.height / grid) * grid;
            } else {
                snake.pop();
            }
        }

        function draw() {
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            ctx.fillStyle = 'green';
            snake.forEach(segment => ctx.fillRect(segment.x, segment.y, grid, grid));
            ctx.fillStyle = 'red';
            ctx.fillRect(food.x, food.y, grid, grid);
        }

        function loop() {
            update();
            draw();
            setTimeout(loop, 100);
        }

        document.addEventListener('keydown', (e) => {
            switch (e.key) {
                case 'ArrowUp': direction = 'up'; break;
                case 'ArrowDown': direction = 'down'; break;
                case 'ArrowLeft': direction = 'left'; break;
                case 'ArrowRight': direction = 'right'; break;
            }
        });

        loop();
    </script>
</body>
</html>

References:

3. Fetch and Display Data from APIs

JavaScript makes it easy to fetch data from APIs and display it dynamically on your web pages. This is especially useful for creating interactive dashboards and real-time applications.

Example: Display Weather Data

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Weather App</title>
</head>
<body>
    <h1>Weather App</h1>
    <input type="text" id="city" placeholder="Enter city">
    <button id="getWeather">Get Weather</button>
    <div id="weather"></div>
    <script>
        document.getElementById('getWeather').addEventListener('click', () => {
            const city = document.getElementById('city').value;
            fetch(`https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=YOUR_API_KEY`)
                .then(response => response.json())
                .then(data => {
                    const weatherDiv = document.getElementById('weather');
                    weatherDiv.innerHTML = `
                        <h2>${data.name}</h2>
                        <p>${data.weather[0].description}</p>
                        <p>Temperature: ${(data.main.temp - 273.15).toFixed(2)} °C</p>
                    `;
                })
                .catch(error => console.error('Error fetching data:', error));
        });
    </script>
</body>
</html>

References:

4. Form Validation

Client-side form validation can be easily handled with JavaScript, providing immediate feedback to users and reducing the need for server-side validation.

Example: Simple Form Validation

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Form Validation</title>
</head>
<body>
    <form id="myForm">
        <label for="username">Username:</label>
        <input type="text" id="username" required>
        <span id="usernameError" style="color: red;"></span>
        <br>
        <label for="email">Email:</label>
        <input type="email" id="email" required>
        <span id="emailError" style="color: red;"></span>
        <br>
        <button type="submit">Submit</button>
    </form>
    <script>
        document.getElementById('myForm').addEventListener('submit', function (e) {
            e.preventDefault();
            let valid = true;
            const username = document.getElementById('username').value;
            const email = document.getElementById('email').value;

            if (username.length < 5) {
                valid = false;
                document.getElementById('usernameError').textContent = 'Username must be at least 5 characters';
            } else {
                document.getElementById('usernameError').textContent = '';
            }

            const emailPattern = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$/;
            if (!emailPattern.test(email)) {
                valid = false;
                document.getElementById('emailError').textContent = 'Invalid email address';
            } else {
                document.getElementById('emailError').textContent = '';
            }

            if (valid) {
                alert('Form submitted successfully!');
            }
        });
    </script>
</body>
</html>

References:

5. Create Animations

JavaScript, along with CSS, allows you to create smooth animations on your web pages. This can be used to enhance user experience and make your site more engaging.

Example: Fade In Effect

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Fade In Effect</title>
    <style>
        #fadeInElement {
            opacity: 0;
            transition: opacity 2s;
        }
        .visible {
            opacity: 1;
        }
    </style>
</head>
<body>
    <h1>Fade In Effect</h1>
    <div id="fadeInElement">Hello, World!</div>
    <button id="fadeInButton">Fade In</button>
    <script>
        document.getElementById('fadeInButton').addEventListener('

click', () => {
            document.getElementById('fadeInElement').classList.add('visible');
        });
    </script>
</body>
</html>

References:

6. Build Single Page Applications (SPAs)

JavaScript frameworks like React, Angular, and Vue allow you to build single-page applications that provide a seamless user experience.

Example: Simple SPA with Vanilla JavaScript

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Simple SPA</title>
    <style>
        .hidden {
            display: none;
        }
    </style>
</head>
<body>
    <nav>
        <a href="#home">Home</a>
        <a href="#about">About</a>
        <a href="#contact">Contact</a>
    </nav>
    <div id="content"></div>
    <script>
        const routes = {
            home: '<h1>Home Page</h1><p>Welcome to the home page.</p>',
            about: '<h1>About Page</h1><p>This is the about page.</p>',
            contact: '<h1>Contact Page</h1><p>Get in touch through the contact page.</p>'
        };

        function navigate() {
            const hash = window.location.hash.substring(1);
            document.getElementById('content').innerHTML = routes[hash] || routes.home;
        }

        window.addEventListener('hashchange', navigate);
        navigate();
    </script>
</body>
</html>

References:

7. Enhance Accessibility

JavaScript can be used to improve the accessibility of your web applications, ensuring they are usable by everyone, including people with disabilities.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Skip to Content</title>
    <style>
        #mainContent {
            margin-top: 100px;
        }
    </style>
</head>
<body>
    <a href="#mainContent" id="skipToContent">Skip to Content</a>
    <nav>
        <ul>
            <li><a href="#">Home</a></li>
            <li><a href="#">About</a></li>
            <li><a href="#">Contact</a></li>
        </ul>
    </nav>
    <main id="mainContent">
        <h1>Main Content</h1>
        <p>This is the main content of the page.</p>
    </main>
    <script>
        document.getElementById('skipToContent').addEventListener('click', function (e) {
            e.preventDefault();
            document.getElementById('mainContent').focus();
        });
    </script>
</body>
</html>

References:

8. Create Browser Extensions

JavaScript can be used to develop browser extensions that enhance the functionality of your browser, automate tasks, and integrate with other services.

Example: Simple Chrome Extension

Create a manifest.json file:

{
    "manifest_version": 2,
    "name": "Hello World Extension",
    "version": "1.0",
    "description": "A simple hello world Chrome extension",
    "browser_action": {
        "default_popup": "popup.html"
    }
}

Create a popup.html file:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Hello World</title>
</head>
<body>
    <h1>Hello, World!</h1>
    <button id="clickMe">Click Me</button>
    <script>
        document.getElementById('clickMe').addEventListener('click', () => {
            alert('Hello from your Chrome Extension!');
        });
    </script>
</body>
</html>

References:

9. Automate Tasks with Node.js

JavaScript can also be used on the server-side with Node.js to automate repetitive tasks, such as file manipulation, web scraping, and data processing.

Example: Read and Write Files

Create a file named app.js:

const fs = require('fs');

const content = 'Hello, World!';
fs.writeFile('hello.txt', content, (err) => {
    if (err) throw err;
    console.log('File written successfully');

    fs.readFile('hello.txt', 'utf8', (err, data) => {
        if (err) throw err;
        console.log('File content:', data);
    });
});

Run the script with Node.js:

node app.js

References:

10. Implement Machine Learning

With libraries like TensorFlow.js, you can implement machine learning models directly in the browser using JavaScript.

Example: Simple Image Classification

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Image Classification</title>
</head>
<body>
    <h1>Image Classification</h1>
    <input type="file" id="imageUpload" accept="image/*">
    <div id="result"></div>
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs"></script>
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/mobilenet"></script>
    <script>
        const imageUpload = document.getElementById('imageUpload');
        const result = document.getElementById('result');

        imageUpload.addEventListener('change', async () => {
            const file = imageUpload.files[0];
            const img = new Image();
            img.src = URL.createObjectURL(file);

            img.onload = async () => {
                const model = await mobilenet.load();
                const predictions = await model.classify(img);
                result.innerHTML = predictions.map(p => `${p.className}: ${p.probability.toFixed(2)}`).join('<br>');
            };
        });
    </script>
</body>
</html>

References:

Conclusion

There are many uses for JavaScript, making it a versatile and potent language. The possibilities are unlimited, ranging from developing single-page applications and automating processes with Node.js to making simple games and interactive web pages. You may begin exploring these incredible things you can accomplish with basic JavaScript by using the examples and resources provided. Have fun with coding!

Additional References:


https://www.nilebits.com/blog/2024/08/10-things-you-can-do-with-javascript/