1. Главная
  2. Docs
  3. Документация по инструментам и технологиям
  4. Cursor
  5. Рефакторинг и оптимизация кода в Cursor | Глава 8

Рефакторинг и оптимизация кода в Cursor | Глава 8

18 октября 2025
62

Глава 8. Рефакторинг и оптимизация кода в Cursor

8.1. Умный рефакторинг кода

Рефакторинг с AI выходит за рамки простого переименования переменных — это интеллектуальное улучшение структуры кода.

Автоматический рефакторинг

Extract Function

Выделите блок кода → Right click → Refactor → Extract Function

Или используйте AI в Chat:


You: [Выделите повторяющийся код]
Извлеки это в отдельную функцию

AI: [Создаёт функцию с подходящим именем и параметрами]

Пример:


// До

function processOrder(order) {
if (!order.customerId) throw new Error('Missing customer');
if (!order.items || order.items.length === 0) {
throw new Error('Order must have items');
}
if (order.total <= 0) throw new Error('Invalid total');

// ... обработка заказа
}

function processRefund(refund) {
if (!refund.customerId) throw new Error('Missing customer');
if (!refund.items || refund.items.length === 0) {
throw new Error('Refund must have items');
}
if (refund.amount <= 0) throw new Error('Invalid amount');

// ... обработка возврата
}

После рефакторинга с AI:


function validateCustomerTransaction(transaction, type = 'order') {

if (!transaction.customerId) {
throw new Error('Missing customer');
}
if (!transaction.items?.length) {
throw new Error(`${type} must have items`);
}
const amountField = type === 'order' ? 'total' : 'amount';
if (transaction[amountField] <= 0) {
throw new Error(`Invalid ${amountField}`);
}
}

function processOrder(order) {
validateCustomerTransaction(order, 'order');
// ... обработка заказа
}

function processRefund(refund) {
validateCustomerTransaction(refund, 'refund');
// ... обработка возврата
}

Extract Component (React)


// До - монолитный компонент

function UserDashboard({ user }) {
return (
<div>
<div className="header">
<img src={user.avatar} />
<h1>{user.name}</h1>
<p>{user.email}</p>
</div>

<div className="stats">
<div>Posts: {user.postCount}</div>
<div>Followers: {user.followers}</div>
<div>Following: {user.following}</div>
</div>

<div className="recent-activity">
{user.activities.map(activity => (
<div key={activity.id}>
<span>{activity.type}</span>
<span>{activity.timestamp}</span>
</div>
))}
</div>
</div>
);
}

Попросите AI:


Разбей этот компонент на подкомпоненты

После рефакторинга:


// UserHeader.jsx

function UserHeader({ user }) {
return (
<div className="header">
<img src={user.avatar} alt={user.name} />
<h1>{user.name}</h1>
<p>{user.email}</p>
</div>
);
}

// UserStats.jsx
function UserStats({ stats }) {
return (
<div className="stats">
<StatItem label="Posts" value={stats.postCount} />
<StatItem label="Followers" value={stats.followers} />
<StatItem label="Following" value={stats.following} />
</div>
);
}

// RecentActivity.jsx
function RecentActivity({ activities }) {
return (
<div className="recent-activity">
{activities.map(activity => (
<ActivityItem key={activity.id} activity={activity} />
))}
</div>
);
}

// UserDashboard.jsx
function UserDashboard({ user }) {
return (
<div>
<UserHeader user={user} />
<UserStats stats={user} />
<RecentActivity activities={user.activities} />
</div>
);
}

Применение Design Patterns


You: Рефактори @api/products.js используя Repository pattern

AI преобразует прямые database вызовы в repository структуру:


// До

async function getProducts() {
return await db.query('SELECT * FROM products');
}

// После
class ProductRepository {
async findAll(filters = {}) {
let query = 'SELECT * FROM products WHERE 1=1';
const params = [];

if (filters.category) {
query += ' AND category = ?';
params.push(filters.category);
}

return await db.query(query, params);
}

async findById(id) {
return await db.queryOne('SELECT * FROM products WHERE id = ?', [id]);
}

async create(data) {
return await db.insert('products', data);
}

async update(id, data) {
return await db.update('products', data, { id });
}

async delete(id) {
return await db.delete('products', { id });
}
}

export const productRepository = new ProductRepository();

8.2. Улучшение читаемости

AI помогает сделать код более понятным и поддерживаемым.

Улучшение именования


// До - плохие имена

function proc(d) {
const r = d.map(x => x.v * 1.2);
return r.reduce((a, b) => a + b, 0);
}

Попросите:


Улучши имена переменных и функций для читаемости

Результат:


function calculateTotalWithTax(items) {

const itemsWithTax = items.map(item => item.value * 1.2);
return itemsWithTax.reduce((total, current) => total + current, 0);
}

Добавление комментариев и документации


You: Добавь JSDoc комментарии к этой функции


/**

* Calculates the total value of items including 20% tax
* @param {Array<{value: number}>} items - Array of items with value property
* @returns {number} Total value including tax
* @example
* const items = [{ value: 100 }, { value: 200 }];
* const total = calculateTotalWithTax(items); // returns 360
*/
function calculateTotalWithTax(items) {
const itemsWithTax = items.map(item => item.value * 1.2);
return itemsWithTax.reduce((total, current) => total + current, 0);
}

Упрощение сложной логики


// До - сложная вложенная логика

function getUserDiscount(user) {
if (user) {
if (user.isPremium) {
if (user.ordersCount > 10) {
return 0.3;
} else {
return 0.2;
}
} else {
if (user.ordersCount > 5) {
return 0.1;
} else {
return 0.05;
}
}
} else {
return 0;
}
}

После AI рефакторинга:


function getUserDiscount(user) {

if (!user) return 0;

if (user.isPremium) {
return user.ordersCount > 10 ? 0.3 : 0.2;
}

return user.ordersCount > 5 ? 0.1 : 0.05;
}

// Или еще лучше - табличный подход
const DISCOUNT_RATES = {
premium: { high: 0.3, low: 0.2 },
regular: { high: 0.1, low: 0.05 }
};

function getUserDiscount(user) {
if (!user) return 0;

const tier = user.isPremium ? 'premium' : 'regular';
const level = user.ordersCount > (user.isPremium ? 10 : 5) ? 'high' : 'low';

return DISCOUNT_RATES[tier][level];
}

8.3. Оптимизация производительности

AI может выявить и исправить проблемы производительности.

Оптимизация алгоритмов


// О(n²) - неэффективно

function findDuplicates(arr) {
const duplicates = [];
for (let i = 0; i < arr.length; i++) {
for (let j = i + 1; j < arr.length; j++) {
if (arr[i] === arr[j] && !duplicates.includes(arr[i])) {
duplicates.push(arr[i]);
}
}
}
return duplicates;
}

Попросите:


Оптимизируй эту функцию для лучшей производительности

AI предложит О(n) решение:


function findDuplicates(arr) {

const seen = new Set();
const duplicates = new Set();

for (const item of arr) {
if (seen.has(item)) {
duplicates.add(item);
} else {
seen.add(item);
}
}

return Array.from(duplicates);
}

React Performance


// Проблема: ререндер при каждом изменении parent

function ProductList({ products, onSelect }) {
return (
<div>
{products.map(product => (
<ProductCard
key={product.id}
product={product}
onClick={() => onSelect(product.id)}
/>
))}
</div>
);
}

AI предложит оптимизацию:


// Мемоизированный компонент

const ProductCard = React.memo(({ product, onClick }) => {
return (
<div onClick={onClick}>
{product.name} - ${product.price}
</div>
);
});

function ProductList({ products, onSelect }) {
// Мемоизируем callbacks
const handlers = useMemo(() => {
return products.reduce((acc, product) => {
acc[product.id] = () => onSelect(product.id);
return acc;
}, {});
}, [products, onSelect]);

return (
<div>
{products.map(product => (
<ProductCard
key={product.id}
product={product}
onClick={handlers[product.id]}
/>
))}
</div>
);
}

Database Query Optimization


// N+1 проблема

async function getUsersWithPosts() {
const users = await db.query('SELECT * FROM users');

for (const user of users) {
user.posts = await db.query(
'SELECT * FROM posts WHERE user_id = ?',
[user.id]
);
}

return users;
}

AI предложит:


async function getUsersWithPosts() {

const users = await db.query('SELECT * FROM users');
const userIds = users.map(u => u.id);

// Один запрос вместо N
const posts = await db.query(
'SELECT * FROM posts WHERE user_id IN (?)',
[userIds]
);

// Группируем посты по пользователям
const postsByUser = posts.reduce((acc, post) => {
if (!acc[post.user_id]) acc[post.user_id] = [];
acc[post.user_id].push(post);
return acc;
}, {});

// Присваиваем посты пользователям
return users.map(user => ({
...user,
posts: postsByUser[user.id] || []
}));
}

8.4. Modernization устаревшего кода

AI отлично справляется с обновлением старого кода до современных стандартов.

ES5 → ES6+


// Старый ES5 код

var UserService = function() {
this.users = [];
};

UserService.prototype.addUser = function(user) {
this.users.push(user);
};

UserService.prototype.findUser = function(id) {
for (var i = 0; i < this.users.length; i++) {
if (this.users[i].id === id) {
return this.users[i];
}
}
return null;
};

Попросите:


Обнови этот код до ES6+ синтаксиса

Результат:


class UserService {

constructor() {
this.users = [];
}

addUser(user) {
this.users.push(user);
}

findUser(id) {
return this.users.find(user => user.id === id) ?? null;
}
}

Callbacks → Promises → Async/Await


// Callback hell

function getUser Data(userId, callback) {
db.getUser(userId, function(err, user) {
if (err) return callback(err);

db.getPosts(user.id, function(err, posts) {
if (err) return callback(err);

db.getComments(posts[0].id, function(err, comments) {
if (err) return callback(err);
callback(null, { user, posts, comments });
});
});
});
}

AI переделает в async/await:


async function getUserData(userId) {

try {
const user = await db.getUser(userId);
const posts = await db.getPosts(user.id);
const comments = await db.getComments(posts[0].id);

return { user, posts, comments };
} catch (error) {
console.error('Error fetching user data:', error);
throw error;
}
}

jQuery → Vanilla JS


// jQuery код

$(document).ready(function() {
$('#submitBtn').click(function() {
var name = $('#nameInput').val();
$.ajax({
url: '/api/users',
method: 'POST',
data: { name: name },
success: function(response) {
$('#result').html('Success: ' + response.message);
},
error: function(xhr) {
$('#result').html('Error: ' + xhr.responseText);
}
});
});
});

Современный вариант:


document.addEventListener('DOMContentLoaded', () => {

const submitBtn = document.getElementById('submitBtn');
const nameInput = document.getElementById('nameInput');
const result = document.getElementById('result');

submitBtn.addEventListener('click', async () => {
try {
const response = await fetch('/api/users', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: nameInput.value })
});

const data = await response.json();
result.textContent = `Success: ${data.message}`;
} catch (error) {
result.textContent = `Error: ${error.message}`;
}
});
});

8.5. Работа с техническим долгом

AI помогает систематически устранять технический долг.

Аудит технического долга


You: Проанализируй @src/ и найди основные проблемы
технического долга

AI: Обнаружено несколько проблем:

1. Дублирование кода (15 экземпляров):
   - Валидация email повторяется в 5 файлах
   - API обработка ошибок дублирована
   
2. Устаревшие паттерны (23 файла):
   - Class components вместо hooks
   - var вместо const/let
   - Callbacks вместо async/await

3. Отсутствие тестов:
   - 0% coverage для utils/
   - Критические функции не покрыты

4. Performance проблемы:
   - N+1 queries в UserService
   - Отсутствие мемоизации в Dashboard
   
5. Security:
   - SQL injection риск в 3 файлах
   - Незащищенные endpoints

Рекомендации по приоритизации:
1. Security (критично)
2. Performance (высокий приоритет)
3. Дублирование (средний)
4. Modernization (низкий)

Постепенное улучшение

Вместо большого переписывания, AI может помочь с инкрементальным улучшением:


You: Создай план рефакторинга @components/ на 4 недели

AI: План постепенного рефакторинга:

Неделя 1: Подготовка
- Добавить тесты к критическим компонентам
- Настроить TypeScript
- Создать style guide

Неделя 2: Базовые улучшения
- Конвертировать 10 самых используемых компонентов в hooks
- Стандартизировать prop types
- Добавить PropTypes/TypeScript types

Неделя 3: Структурные изменения
- Разбить монолитные компоненты
- Вынести общую логику в hooks
- Оптимизировать ререндеры

Неделя 4: Финализация
- Code review всех изменений
- Performance тестирование
- Документация обновлений