laboratorio
Este procedimiento es parte de un laboratorio que le enseña cómo solucionar problemas de su aplicación web con New Relic Browser.
Cada procedimiento en el laboratorio se basa en el anterior, así que asegúrese de haber completado el último procedimiento, instrumentado su aplicación con nuestro agente del navegador, antes de comenzar este.
Hasta ahora, su aplicación ha funcionado bien. El usuario pudo realizar sus pedidos y quedó satisfecho con su servicio. Pero ahora que tiene información valiosa en su aplicación, observa que muestra algunos errores de JavaScript.
En este procedimiento, utiliza New Relic Browser para descubrir qué está causando estos errores y depurar su aplicación oportunamente.
Importante
Para ver sus datos en New Relic, debe habilitar para este procedimiento.
Si aún no lo has hecho, instrumenta tu aplicación con nuestro agente del navegador.
Depurar errores de interfaz
La mala noticia es que ha confirmado que hay algunos errores en su aplicación. ¡La buena noticia es que recientemente instrumentaste tu aplicación con nuestro agente del navegador! Vaya a New Relic e inicie sesión en su cuenta, si aún no lo ha hecho.
Sugerencia
¿No ves tus datos? Asegúrese de haber habilitado el monitoreo del navegador y de que su generador de carga esté ejecutándose.
Al observar los detalles del error anteriores, ahora conoce el error particular que afecta sus servicios. Sin embargo, el rastreo del stack que se muestra aquí está minimizado y es difícil entender qué está causando este error. Para entender esto, debemos cargar el mapa fuente para eliminar el error.
Cargue el mapa fuente para eliminar el error de JS
JavaScript minimizado genera principalmente un rastreo del stack inútil y difícil de entender en la página de errores del browser. La carga de mapas de origen convierte estos errores en un rastreo del stack comprensible. También proporciona una referencia útil a las líneas de código y facilita la depuración. Puede cargar su mapa de origen en New Relic a través de UI, la API o el módulo npm.
Aquí, utilizamos UI de New Relic para cargar el mapa fuente y eliminar el error de JS.
Haga clic en find file.
Esto abre una ventana del explorador de archivos para que pueda cargar el mapa fuente desde su almacenamiento local. Busque y cargue su mapa fuente desde el directorio build/static/js de su proyecto.
Sugerencia
Los archivos de mapas de origen tienen una extensión de archivo de .js.map
. Relicstaurants está configurado para generar mapas fuente y lo encontrará en el directorio build/static/js . Si tiene problemas para generar mapas fuente para su proyecto, siga nuestra documentación para aprender cómo generar uno.
Una vez que su mapa de origen se haya cargado correctamente, verá el error sin minimizar.
Aquí verá el archivo en particular y la línea de código que genera este error. Observe que en la línea 119, el Cart cannot be empty! está asociado con el evento onClick en el archivo components/layouts/app/app-container/header/app-container-header.js y también activa una alerta para el usuario. ¡Echemos un vistazo más de cerca a este archivo!
Abra la aplicación en el IDE de su elección y navegue hasta el archivo src/components/layouts/app/app-container/header/app-container-header.js . Eche un vistazo más de cerca al código mostrado.
import { Button, Drawer, Table } from 'antd';import Text from 'antd/lib/typography/Text';import { orderList } from 'atoms/order-list.atom';import { useState } from 'react';import { Link } from 'react-router-dom';import { useRecoilState } from 'recoil';import { Logo, StyledHeader } from './app-header-styled';import Navi from './navi-items';import { useNavigate } from 'react-router';
const Header = () => { const [isSidebarVisible, setIsSidebarVisible] = useState(false); const [orderListState, setOrderList] = useRecoilState(orderList); const navigate = useNavigate();
const onClose = () => { setIsSidebarVisible(false); }; const handleSidebarOpen = () => { setIsSidebarVisible(true); };
const itemQuantity = (list) => { let totalItemQuantity = 0; list.forEach((item) => (totalItemQuantity += item.count));
return totalItemQuantity; };
const handleDeleteItem = (clickedRow) => { const reducedData = orderListState.filter((item) => item.name === clickedRow.name ? false : true ); setOrderList(reducedData); };
const columns = [ { title: 'Name', dataIndex: 'name', key: 'name', }, { title: 'Count', dataIndex: 'count', key: 'count', }, { title: 'Price', dataIndex: 'price', key: 'price', }, { title: 'Delete', render: (clickedRow) => ( <Button onClick={() => handleDeleteItem(clickedRow)}>-</Button> ), }, ];
return ( <StyledHeader> <Link to="/"> <Logo> <div>Relicstaurants</div> <p>by New Relic</p> </Logo> </Link> <Navi sidebarVisible={handleSidebarOpen} orderListLength={itemQuantity(orderListState)} /> <Drawer size="large" title="Cart" placement="right" onClose={onClose} visible={isSidebarVisible} > <Table dataSource={orderListState} columns={columns} pagination={false} summary={(pageData) => { let totalPrice = 0;
pageData.forEach( ({ price, count }) => (totalPrice += price * count) );
return ( <> <Table.Summary.Row> <Table.Summary.Cell colSpan={2}>Total</Table.Summary.Cell> <Table.Summary.Cell> <Text type="danger">{totalPrice.toFixed(2)}</Text> </Table.Summary.Cell> </Table.Summary.Row> <Table.Summary.Row> <Table.Summary.Cell colSpan={3}> <Button disabled={totalPrice > 0 ? false : true} primary onClick={() => { setOrderList([]); setIsSidebarVisible(false); }} > Clear Cart </Button> </Table.Summary.Cell> <Table.Summary.Cell> <Button id="pay" primary onClick={() => { if (!(totalPrice > 0)) { var err = new Error('Cart cannot be empty!'); newrelic.noticeError(err); alert(err) navigate('/') setIsSidebarVisible(false); } else { navigate(`/payment`, { state: totalPrice }); setIsSidebarVisible(false); } }} > PAY </Button> </Table.Summary.Cell> </Table.Summary.Row> </> ); }} /> </Drawer> </StyledHeader> );};
export default Header;
Aquí, observe que el error Cart cannot be empty! solo ocurre cuando el usuario intenta accidentalmente realizar el pago con un carrito vacío. La función está codificada para alertar al usuario final de que no puede realizar el pago con un carrito vacío. Ahora sabes que este error no afectará tus servicios. Sin embargo, existen mejores formas de manejar este caso límite y evitar el error.
Presione Ctrl+C
en la terminal que ejecuta su aplicación para dejar de servirla. Actualice src/components/layouts/app/app-container/header/app-container-header.js de la siguiente manera.
import { Button, Drawer, Table } from 'antd';import Text from 'antd/lib/typography/Text';import { orderList } from 'atoms/order-list.atom';import { Message } from 'components/common';import { useState } from 'react';import { Link } from 'react-router-dom';import { useRecoilState } from 'recoil';import { Logo, StyledHeader } from './app-header-styled';import Navi from './navi-items';import { useNavigate } from 'react-router';
const Header = () => { const [isSidebarVisible, setIsSidebarVisible] = useState(false); const [orderListState, setOrderList] = useRecoilState(orderList); const navigate = useNavigate();
const onClose = () => { setIsSidebarVisible(false); }; const handleSidebarOpen = () => { setIsSidebarVisible(true); };
const itemQuantity = (list) => { let totalItemQuantity = 0; list.forEach((item) => (totalItemQuantity += item.count));
return totalItemQuantity; };
const handleDeleteItem = (clickedRow) => { const reducedData = orderListState.filter((item) => item.name === clickedRow.name ? false : true ); setOrderList(reducedData); };
const columns = [ { title: 'Name', dataIndex: 'name', key: 'name', }, { title: 'Count', dataIndex: 'count', key: 'count', }, { title: 'Price', dataIndex: 'price', key: 'price', }, { title: 'Delete', render: (clickedRow) => ( <Button onClick={() => handleDeleteItem(clickedRow)}>-</Button> ), }, ];
return ( <StyledHeader> <Link to="/"> <Logo> <div>Relicstaurants</div> <p>by New Relic</p> </Logo> </Link> <Navi sidebarVisible={handleSidebarOpen} orderListLength={itemQuantity(orderListState)} /> <Drawer size="large" title="Cart" placement="right" onClose={onClose} visible={isSidebarVisible} > {orderListState.length > 0 ? ( <Table dataSource={orderListState} columns={columns} pagination={false} summary={(pageData) => { let totalPrice = 0;
pageData.forEach( ({ price, count }) => (totalPrice += price * count) );
return ( <> <Table.Summary.Row> <Table.Summary.Cell colSpan={2}>Total</Table.Summary.Cell> <Table.Summary.Cell> <Text type="danger">{totalPrice.toFixed(2)}</Text> </Table.Summary.Cell> </Table.Summary.Row> <Table.Summary.Row> <Table.Summary.Cell colSpan={3}> <Button disabled={totalPrice > 0 ? false : true} primary onClick={() => { setOrderList([]); setIsSidebarVisible(false); }} > Clear Cart </Button> </Table.Summary.Cell> <Table.Summary.Cell> <Button id="pay" disabled={totalPrice > 0 ? false : true} primary onClick={() => { navigate(`/payment`, { state: totalPrice }); setIsSidebarVisible(false); }} > PAY </Button> </Table.Summary.Cell> </Table.Summary.Row> </> ); }} /> ) : ( <Message>Nothing in cart</Message> )} </Drawer> </StyledHeader> );};
export default Header;
Aquí, modificó el archivo y muestra un mensaje Nothing in cart en lugar de un error cuando el carrito está vacío. El botón PAY permanece deshabilitado hasta que el usuario final tenga artículos en su carrito.
Reinicia tu aplicación
Ahora que ha arreglado su aplicación, es hora de reiniciar su servidor local.
$npm run build$npm run newstart
Reinicie también su generador de carga.
$python3 simulator.py
Importante
Asegúrese de ejecutar estos comandos en las ventanas de terminal correctas. Si ya no tienes esas ventanas, sigue los pasos del procedimiento de configuración.
Una vez que el generador de carga comienza a enviar datos a New Relic, observe que la aplicación ya no informa errores de JavaScript.
Resumen
En resumen, observó un error en su aplicación y utilizó New Relic Browser para:
- Revisar el porcentaje de error
- Analiza los errores JS en tu aplicación
- Comprender la instancia de error
- Depure el error de JS cargando el mapa fuente
laboratorio
Este procedimiento es parte de un laboratorio que le enseña cómo solucionar problemas de su aplicación web con New Relic Browser. A continuación, intente depurar la lentitud del frontend en su aplicación.